commit
d949c86cf9
@ -0,0 +1 @@
|
|||||||
|
SOURCES/gnome-shell-extensions-40.7.tar.xz
|
@ -0,0 +1 @@
|
|||||||
|
a905a152407590d18e8dc14bb4133fbde0e03abb SOURCES/gnome-shell-extensions-40.7.tar.xz
|
@ -0,0 +1,438 @@
|
|||||||
|
From 38c4fc02dea622f198b078eb4003c777d982119c Mon Sep 17 00:00:00 2001
|
||||||
|
From: rpm-build <rpm-build>
|
||||||
|
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 | 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 3600e824..b3812b8d 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -49,6 +49,7 @@ all_extensions += [
|
||||||
|
'classification-banner',
|
||||||
|
'custom-menu',
|
||||||
|
'dash-to-dock',
|
||||||
|
+ 'gesture-inhibitor',
|
||||||
|
'native-window-placement',
|
||||||
|
'panel-favorites',
|
||||||
|
'systemMonitor',
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
||||||
|
|
||||||
|
From aff83154aa639e33e5ba925b5ddcc824a9beaf6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Wed, 20 Oct 2021 19:48:46 +0200
|
||||||
|
Subject: [PATCH 2/5] gesture-inhibitor: Fix up indentation
|
||||||
|
|
||||||
|
---
|
||||||
|
extensions/gesture-inhibitor/extension.js | 59 +++++++++++------------
|
||||||
|
1 file changed, 29 insertions(+), 30 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
|
||||||
|
index e74ede2f..734d61cc 100644
|
||||||
|
--- a/extensions/gesture-inhibitor/extension.js
|
||||||
|
+++ b/extensions/gesture-inhibitor/extension.js
|
||||||
|
@@ -29,44 +29,43 @@ const Gio = imports.gi.Gio;
|
||||||
|
|
||||||
|
class Extension {
|
||||||
|
constructor() {
|
||||||
|
- this._settings = ExtensionUtils.getSettings();
|
||||||
|
- let actions = global.stage.get_actions();
|
||||||
|
+ 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;
|
||||||
|
- });
|
||||||
|
+ 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 }
|
||||||
|
- ];
|
||||||
|
+ 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);
|
||||||
|
- });
|
||||||
|
+ this._map.forEach(m => {
|
||||||
|
+ this._settings.bind(m.setting, m.action, 'enabled',
|
||||||
|
+ Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
+ });
|
||||||
|
}
|
||||||
|
|
||||||
|
disable() {
|
||||||
|
- this._map.forEach(m => {
|
||||||
|
- m.action.enabled = true;
|
||||||
|
- });
|
||||||
|
+ this._map.forEach(
|
||||||
|
+ m => (m.action.enabled = true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
||||||
|
|
||||||
|
From 5c8b087e99f79cc6bd83b5e7ad0775f8510e1a5d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Wed, 20 Oct 2021 19:47:05 +0200
|
||||||
|
Subject: [PATCH 3/5] gesture-inhibitor: Adjust for GNOME 40 changes
|
||||||
|
|
||||||
|
---
|
||||||
|
extensions/gesture-inhibitor/extension.js | 11 +++--------
|
||||||
|
...ome.shell.extensions.gesture-inhibitor.gschema.xml | 4 ----
|
||||||
|
2 files changed, 3 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
|
||||||
|
index 734d61cc..13586108 100644
|
||||||
|
--- a/extensions/gesture-inhibitor/extension.js
|
||||||
|
+++ b/extensions/gesture-inhibitor/extension.js
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
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 Main = imports.ui.main;
|
||||||
|
const WindowManager = imports.ui.windowManager;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
@@ -33,9 +33,7 @@ class Extension {
|
||||||
|
let actions = global.stage.get_actions();
|
||||||
|
|
||||||
|
actions.forEach(a => {
|
||||||
|
- if (a instanceof ViewSelector.ShowOverviewAction)
|
||||||
|
- this._showOverview = a;
|
||||||
|
- else if (a instanceof WindowManager.AppSwitchAction)
|
||||||
|
+ if (a instanceof WindowManager.AppSwitchAction)
|
||||||
|
this._appSwitch = a;
|
||||||
|
else if (a instanceof EdgeDragAction.EdgeDragAction &&
|
||||||
|
a._side == St.Side.BOTTOM)
|
||||||
|
@@ -43,16 +41,13 @@ class Extension {
|
||||||
|
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: 'overview', action: Main.overview._swipeTracker },
|
||||||
|
{ setting: 'app-switch', action: this._appSwitch },
|
||||||
|
{ setting: 'show-osk', action: this._showOsk },
|
||||||
|
{ setting: 'unfullscreen', action: this._unfullscreen },
|
||||||
|
- { setting: 'show-app-grid', action: this._showAppGrid }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
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..4bdf9260 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
|
||||||
|
@@ -1,9 +1,5 @@
|
||||||
|
<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>
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
||||||
|
|
||||||
|
From 7f8031a97046a18ebb39972150376b9f1cf9a70b Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Thu, 18 Nov 2021 15:54:23 +0100
|
||||||
|
Subject: [PATCH 4/5] gesture-inhibitor: Unbind setting on disable
|
||||||
|
|
||||||
|
---
|
||||||
|
extensions/gesture-inhibitor/extension.js | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
|
||||||
|
index 13586108..02b34ec4 100644
|
||||||
|
--- a/extensions/gesture-inhibitor/extension.js
|
||||||
|
+++ b/extensions/gesture-inhibitor/extension.js
|
||||||
|
@@ -59,8 +59,10 @@ class Extension {
|
||||||
|
}
|
||||||
|
|
||||||
|
disable() {
|
||||||
|
- this._map.forEach(
|
||||||
|
- m => (m.action.enabled = true));
|
||||||
|
+ this._map.forEach(m => {
|
||||||
|
+ Gio.Settings.unbind(m.action, 'enabled');
|
||||||
|
+ m.action.enabled = true;
|
||||||
|
+ });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
||||||
|
|
||||||
|
From 15b4dde292cd1dd33c881289e6182d7261bee544 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Thu, 18 Nov 2021 16:06:09 +0100
|
||||||
|
Subject: [PATCH 5/5] gesture-inhibitor: Override :enabled property
|
||||||
|
|
||||||
|
Otherwise gnome-shell can re-enable an inhibited gesture behind our
|
||||||
|
back.
|
||||||
|
---
|
||||||
|
extensions/gesture-inhibitor/extension.js | 23 ++++++++++++++++++++++-
|
||||||
|
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
|
||||||
|
index 02b34ec4..fb8a6dc0 100644
|
||||||
|
--- a/extensions/gesture-inhibitor/extension.js
|
||||||
|
+++ b/extensions/gesture-inhibitor/extension.js
|
||||||
|
@@ -49,18 +49,39 @@ class Extension {
|
||||||
|
{ setting: 'show-osk', action: this._showOsk },
|
||||||
|
{ setting: 'unfullscreen', action: this._unfullscreen },
|
||||||
|
];
|
||||||
|
+
|
||||||
|
+ 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._settings;
|
||||||
|
+
|
||||||
|
this._map.forEach(m => {
|
||||||
|
- this._settings.bind(m.setting, m.action, 'enabled',
|
||||||
|
+ settings.bind(m.setting, m.action, 'enabled',
|
||||||
|
Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
+
|
||||||
|
+ this._overrideEnabledSetter(m.action, function (value) {
|
||||||
|
+ if (settings.get_boolean(m.setting))
|
||||||
|
+ this.set_enabled(value);
|
||||||
|
+ });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
disable() {
|
||||||
|
this._map.forEach(m => {
|
||||||
|
Gio.Settings.unbind(m.action, 'enabled');
|
||||||
|
+ this._overrideEnabledSetter(m.action);
|
||||||
|
m.action.enabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 1982ab4218fa3a7ff622fff5af7c15c2e11351f7 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 afc0133..78dee5b 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -31,6 +31,7 @@ classic_extensions = [
|
||||||
|
'desktop-icons',
|
||||||
|
'places-menu',
|
||||||
|
'launch-new-instance',
|
||||||
|
+ 'top-icons',
|
||||||
|
'window-list'
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -49,7 +50,6 @@ all_extensions += [
|
||||||
|
'native-window-placement',
|
||||||
|
'panel-favorites',
|
||||||
|
'systemMonitor',
|
||||||
|
- 'top-icons',
|
||||||
|
'updates-dialog',
|
||||||
|
'user-theme'
|
||||||
|
]
|
||||||
|
--
|
||||||
|
2.32.0
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From 9ca03a744552c43251523fd23292b243130e1f89 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Mon, 24 May 2021 15:36:04 +0200
|
||||||
|
Subject: [PATCH] Update style
|
||||||
|
|
||||||
|
---
|
||||||
|
data/gnome-shell-sass | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
Submodule data/gnome-shell-sass 9d66f7d..60230f4:
|
||||||
|
diff --git a/data/gnome-shell-sass/widgets/_panel.scss b/data/gnome-shell-sass/widgets/_panel.scss
|
||||||
|
index 1f46507..ad638b2 100644
|
||||||
|
--- a/data/gnome-shell-sass/widgets/_panel.scss
|
||||||
|
+++ b/data/gnome-shell-sass/widgets/_panel.scss
|
||||||
|
@@ -67,6 +67,11 @@ $panel_transition_duration: 250ms; // same as the overview transition duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .panel-logo-icon {
|
||||||
|
+ padding-right: .4em;
|
||||||
|
+ icon-size: 1em;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// status area icons
|
||||||
|
.system-status-icon {
|
||||||
|
icon-size: $base_icon_size;
|
||||||
|
diff --git a/data/gnome-classic.css b/data/gnome-classic.css
|
||||||
|
index 52e5367..3be81e9 100644
|
||||||
|
--- a/data/gnome-classic.css
|
||||||
|
+++ b/data/gnome-classic.css
|
||||||
|
@@ -1234,6 +1234,9 @@ StScrollBar {
|
||||||
|
box-shadow: none; }
|
||||||
|
#panel .panel-button.clock-display:hover .clock, #panel .panel-button.clock-display:active .clock, #panel .panel-button.clock-display:overview .clock, #panel .panel-button.clock-display:focus .clock, #panel .panel-button.clock-display:checked .clock {
|
||||||
|
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.2); }
|
||||||
|
+ #panel .panel-button .panel-logo-icon {
|
||||||
|
+ padding-right: .4em;
|
||||||
|
+ icon-size: 1em; }
|
||||||
|
#panel .panel-button .system-status-icon {
|
||||||
|
icon-size: 1.09em;
|
||||||
|
padding: 5px;
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From fe13aa54e7c104f63689fcd15957ab16ffc0c3ef 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 | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
|
||||||
|
index 983a4e7..f8cef41 100644
|
||||||
|
--- a/extensions/apps-menu/extension.js
|
||||||
|
+++ b/extensions/apps-menu/extension.js
|
||||||
|
@@ -113,7 +113,9 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
|
||||||
|
else
|
||||||
|
name = _('Favorites');
|
||||||
|
|
||||||
|
- this.add_child(new St.Label({ text: name }));
|
||||||
|
+ const label = new St.Label({ text: name });
|
||||||
|
+ this.add_child(label);
|
||||||
|
+ this.actor.label_actor = label;
|
||||||
|
this.connect('motion-event', this._onMotionEvent.bind(this));
|
||||||
|
this.connect('notify::active', this._onActiveChanged.bind(this));
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.32.0
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
From 08e720c793baa0cb12ed99c4333c75df46e3a9ed 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 | 22 +++++++++++++++++++++-
|
||||||
|
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
|
||||||
|
index e36b0fe..983a4e7 100644
|
||||||
|
--- a/extensions/apps-menu/extension.js
|
||||||
|
+++ b/extensions/apps-menu/extension.js
|
||||||
|
@@ -364,13 +364,24 @@ class ApplicationsButton extends PanelMenu.Button {
|
||||||
|
// role ATK_ROLE_MENU like other elements of the panel.
|
||||||
|
this.accessible_role = Atk.Role.LABEL;
|
||||||
|
|
||||||
|
+ const hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
|
||||||
|
+
|
||||||
|
+ const 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,
|
||||||
|
y_align: Clutter.ActorAlign.CENTER,
|
||||||
|
});
|
||||||
|
+ hbox.add_actor(this._label);
|
||||||
|
|
||||||
|
- this.add_actor(this._label);
|
||||||
|
+ this.add_actor(hbox);
|
||||||
|
this.name = 'panelApplications';
|
||||||
|
this.label_actor = this._label;
|
||||||
|
|
||||||
|
@@ -404,6 +415,14 @@ class ApplicationsButton extends PanelMenu.Button {
|
||||||
|
this._display();
|
||||||
|
this._installedChangedId = appSys.connect('installed-changed',
|
||||||
|
this._onTreeChanged.bind(this));
|
||||||
|
+ this._sessionUpdatedId = Main.sessionMode.connect('updated',
|
||||||
|
+ this._sessionUpdated.bind(this));
|
||||||
|
+ this._sessionUpdated();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _sessionUpdated() {
|
||||||
|
+ this._icon.visible =
|
||||||
|
+ !Main.sessionMode.panel.left.includes('activities');
|
||||||
|
}
|
||||||
|
|
||||||
|
_onTreeChanged() {
|
||||||
|
@@ -429,6 +448,7 @@ class ApplicationsButton extends PanelMenu.Button {
|
||||||
|
|
||||||
|
Main.overview.disconnect(this._showingId);
|
||||||
|
Main.overview.disconnect(this._hidingId);
|
||||||
|
+ Main.sessionMode.disconnect(this._sessionUpdatedId);
|
||||||
|
appSys.disconnect(this._installedChangedId);
|
||||||
|
this._tree.disconnect(this._treeChangedId);
|
||||||
|
this._tree = null;
|
||||||
|
--
|
||||||
|
2.32.0
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
From ffba821e1142c3cb96b9ced24dd1f161f0609d2a 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 cc046e01..ea788022 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;
|
||||||
|
+
|
||||||
|
this._settings?.run_dispose();
|
||||||
|
this._settings = null;
|
||||||
|
});
|
||||||
|
@@ -94,6 +97,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',
|
||||||
|
@@ -110,6 +118,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
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From 8bea7c892c24694efda753ad1d76ab470032c6fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Thu, 15 Dec 2022 17:09:45 +0100
|
||||||
|
Subject: [PATCH] desktop-icons: Don't grab focus on click
|
||||||
|
|
||||||
|
We will move keyboard focus away immediately, either when opening
|
||||||
|
the context menu or when starting the rubberband.
|
||||||
|
|
||||||
|
In theory the grab is still useful, because it will move keyboard
|
||||||
|
focus to the grid when restoring focus after ending the rubberband
|
||||||
|
or closing the menu, however as keyboard navigation support is
|
||||||
|
lacking, all it does is preventing the focus to return to the
|
||||||
|
focus window after the operation.
|
||||||
|
---
|
||||||
|
extensions/desktop-icons/desktopGrid.js | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js
|
||||||
|
index 002803c7..9a89d5a3 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopGrid.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopGrid.js
|
||||||
|
@@ -559,8 +559,6 @@ var DesktopGrid = GObject.registerClass({
|
||||||
|
let button = event.get_button();
|
||||||
|
let [x, y] = event.get_coords();
|
||||||
|
|
||||||
|
- this._grid.grab_key_focus();
|
||||||
|
-
|
||||||
|
if (button == 1) {
|
||||||
|
let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
|
||||||
|
let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,108 @@
|
|||||||
|
From 2a1dd773a529c89b5f9577b53ae3c88aea2efc48 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 | 45 +++++++++++++++-------
|
||||||
|
1 file changed, 32 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
|
||||||
|
index 74d0e6bd..75b2a22a 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopManager.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopManager.js
|
||||||
|
@@ -54,6 +54,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: {
|
||||||
|
@@ -272,9 +287,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);
|
||||||
|
}
|
||||||
|
@@ -283,7 +296,7 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
let items = [];
|
||||||
|
for (let item of await this._enumerateDesktop())
|
||||||
|
items.push(item);
|
||||||
|
- for (let item of this._getMounts())
|
||||||
|
+ for (let item of await this._getMounts())
|
||||||
|
items.push(item);
|
||||||
|
|
||||||
|
let tmpFileItems = new Map();
|
||||||
|
@@ -328,14 +341,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);
|
||||||
|
@@ -359,19 +380,17 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
this._monitorDesktopDir.connect('changed', (obj, file, otherFile, eventType) => this._updateDesktopIfChanged(file, otherFile, eventType));
|
||||||
|
}
|
||||||
|
|
||||||
|
- _getMounts() {
|
||||||
|
+ async _getMounts() {
|
||||||
|
let files = [];
|
||||||
|
if (!Prefs.settings.get_boolean('show-mount'))
|
||||||
|
return files;
|
||||||
|
|
||||||
|
- this._mountMonitor.get_mounts().forEach( mount => {
|
||||||
|
+ this._mountMonitor.get_mounts().forEach(async mount => {
|
||||||
|
if (this._isNetworkMount(mount))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let file = mount.get_root();
|
||||||
|
- let info = file.query_info(DesktopIconsUtil.DEFAULT_ATTRIBUTES,
|
||||||
|
- Gio.FileQueryInfoFlags.NONE,
|
||||||
|
- null);
|
||||||
|
+ let info = await queryInfo(file);
|
||||||
|
files.push([file, info, Prefs.FileType.MOUNT_DISK]);
|
||||||
|
});
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,209 @@
|
|||||||
|
From 73000f25e578b3ce6654fdf0d3da2ec3d9b95dd2 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 | 109 ++++++++++++---------
|
||||||
|
extensions/desktop-icons/fileItem.js | 1 +
|
||||||
|
3 files changed, 67 insertions(+), 44 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js
|
||||||
|
index 002803c..c7846bf 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopGrid.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopGrid.js
|
||||||
|
@@ -388,6 +388,7 @@ var DesktopGrid = GObject.registerClass({
|
||||||
|
}
|
||||||
|
|
||||||
|
_openMenu(x, y) {
|
||||||
|
+ Extension.desktopManager.endRubberBand();
|
||||||
|
Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0);
|
||||||
|
this._submenu.menu.removeAll();
|
||||||
|
let templates = Extension.templateManager.getTemplates();
|
||||||
|
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
|
||||||
|
index 10e3ce0..08bc82b 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopManager.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopManager.js
|
||||||
|
@@ -81,6 +81,7 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
this._unixMode = null;
|
||||||
|
this._writableByOthers = null;
|
||||||
|
this._discreteGpuAvailable = false;
|
||||||
|
+ this._rubberBandActive = false;
|
||||||
|
|
||||||
|
this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', () => this._recreateDesktopIcons());
|
||||||
|
this._rubberBand = new St.Widget({ style_class: 'rubber-band' });
|
||||||
|
@@ -94,6 +95,20 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
this._mountRemovedId = this._mountMonitor.connect('mount-removed', (monitor, mount) => {
|
||||||
|
this._recreateDesktopIcons(); });
|
||||||
|
|
||||||
|
+ 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();
|
||||||
|
|
||||||
|
@@ -133,57 +148,67 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
this._rubberBandInitialY = y;
|
||||||
|
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);
|
||||||
|
- 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() {
|
||||||
|
+ _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);
|
||||||
|
+ 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(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._stageReleaseEventId);
|
||||||
|
- this._rubberBandId = 0;
|
||||||
|
this._stageReleaseEventId = 0;
|
||||||
|
|
||||||
|
this._selection = new Set([...this._selection, ...this._currentSelection]);
|
||||||
|
@@ -825,10 +850,6 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
global.stage.disconnect(this._stageReleaseEventId);
|
||||||
|
this._stageReleaseEventId = 0;
|
||||||
|
|
||||||
|
- if (this._rubberBandId)
|
||||||
|
- global.stage.disconnect(this._rubberBandId);
|
||||||
|
- this._rubberBandId = 0;
|
||||||
|
-
|
||||||
|
this._rubberBand.destroy();
|
||||||
|
|
||||||
|
if (this._queryFileInfoCancellable)
|
||||||
|
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
|
||||||
|
index 1e8ea89..37ee54d 100644
|
||||||
|
--- a/extensions/desktop-icons/fileItem.js
|
||||||
|
+++ b/extensions/desktop-icons/fileItem.js
|
||||||
|
@@ -747,6 +747,7 @@ var FileItem = GObject.registerClass({
|
||||||
|
}
|
||||||
|
|
||||||
|
_onPressButton(actor, event) {
|
||||||
|
+ Extension.desktopManager.endRubberBand();
|
||||||
|
this._updateClickState(event);
|
||||||
|
let button = event.get_button();
|
||||||
|
if (button == 3) {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From ba4208c00504439bad19de4680fac68210767798 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 | 6 +-----
|
||||||
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/po/ja.po b/po/ja.po
|
||||||
|
index 8eb7725..ddf1eb7 100644
|
||||||
|
--- a/po/ja.po
|
||||||
|
+++ b/po/ja.po
|
||||||
|
@@ -897,11 +897,7 @@ msgstr "押し込み量 (ピクセル)"
|
||||||
|
#: desktopGrid.js:359
|
||||||
|
#, 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.32.0
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 62289dff5cb2e615a277b72f034fa42f45aad639 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Thu, 15 Dec 2022 15:14:08 +0100
|
||||||
|
Subject: [PATCH] desktopManager: Hook into LayoutManager to create grids
|
||||||
|
|
||||||
|
Right now we track the `monitors-changed` signal to recreate the
|
||||||
|
per-monitor grids. Usually that's enough, but if something else
|
||||||
|
causes backgrounds to update, we'll end up without desktop icons
|
||||||
|
until some other change (settings, mounts, monitor/resolution
|
||||||
|
changes, ...) results in a reload of the grid.
|
||||||
|
|
||||||
|
To address this, hook into LayoutManager to always create the grid
|
||||||
|
when backgrounds are updated.
|
||||||
|
---
|
||||||
|
extensions/desktop-icons/desktopManager.js | 15 +++++++++++----
|
||||||
|
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
|
||||||
|
index 08bc82b7..74d0e6bd 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopManager.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopManager.js
|
||||||
|
@@ -83,7 +83,6 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
this._discreteGpuAvailable = false;
|
||||||
|
this._rubberBandActive = false;
|
||||||
|
|
||||||
|
- this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', () => this._recreateDesktopIcons());
|
||||||
|
this._rubberBand = new St.Widget({ style_class: 'rubber-band' });
|
||||||
|
this._rubberBand.hide();
|
||||||
|
Main.layoutManager._backgroundGroup.add_child(this._rubberBand);
|
||||||
|
@@ -109,6 +108,13 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
return origCapturedEvent.bind(this._grabHelper)(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
+ this._origUpdateBackgrounds =
|
||||||
|
+ Main.layoutManager._updateBackgrounds;
|
||||||
|
+ Main.layoutManager._updateBackgrounds = () => {
|
||||||
|
+ this._origUpdateBackgrounds.call(Main.layoutManager);
|
||||||
|
+ this._recreateDesktopIcons();
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
this._addDesktopIcons();
|
||||||
|
this._monitorDesktopFolder();
|
||||||
|
|
||||||
|
@@ -843,9 +849,10 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
GLib.source_remove(this._deleteChildrenId);
|
||||||
|
this._deleteChildrenId = 0;
|
||||||
|
|
||||||
|
- if (this._monitorsChangedId)
|
||||||
|
- Main.layoutManager.disconnect(this._monitorsChangedId);
|
||||||
|
- this._monitorsChangedId = 0;
|
||||||
|
+ if (this._origUpdateBackgrounds)
|
||||||
|
+ Main.layoutManager._updateBackgrounds = this._origUpdateBackgrounds;
|
||||||
|
+ delete this._origUpdateBackgrounds;
|
||||||
|
+
|
||||||
|
if (this._stageReleaseEventId)
|
||||||
|
global.stage.disconnect(this._stageReleaseEventId);
|
||||||
|
this._stageReleaseEventId = 0;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From c70a1fa37f68687b8c0a013d2328e6262f8419d0 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 | 1 +
|
||||||
|
.../org.gnome.shell.extensions.gesture-inhibitor.gschema.xml | 4 ++++
|
||||||
|
2 files changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js
|
||||||
|
index fb8a6dc0..d103d5b8 100644
|
||||||
|
--- a/extensions/gesture-inhibitor/extension.js
|
||||||
|
+++ b/extensions/gesture-inhibitor/extension.js
|
||||||
|
@@ -48,6 +48,7 @@ class Extension {
|
||||||
|
{ 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(
|
||||||
|
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 4bdf9260..b06d027a 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
|
||||||
|
@@ -12,6 +12,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
|
||||||
|
|
@ -0,0 +1,986 @@
|
|||||||
|
From 8beb3b27486fd50f74c15d2cf9ed8ca22fb546c2 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 | 436 ++++++++++++++++++
|
||||||
|
extensions/heads-up-display/headsUpMessage.js | 170 +++++++
|
||||||
|
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 | 194 ++++++++
|
||||||
|
extensions/heads-up-display/stylesheet.css | 32 ++
|
||||||
|
meson.build | 1 +
|
||||||
|
8 files changed, 906 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..7cebfa99
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/extensions/heads-up-display/extension.js
|
||||||
|
@@ -0,0 +1,436 @@
|
||||||
|
+/* 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 Layout = imports.ui.layout;
|
||||||
|
+const HeadsUpMessage = Me.imports.headsUpMessage;
|
||||||
|
+
|
||||||
|
+const _ = ExtensionUtils.gettext;
|
||||||
|
+
|
||||||
|
+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 Layout.MonitorConstraint {
|
||||||
|
+ _init(props) {
|
||||||
|
+ super._init(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);
|
||||||
|
+ }
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+class Extension {
|
||||||
|
+ constructor() {
|
||||||
|
+ ExtensionUtils.initTranslations();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ enable() {
|
||||||
|
+ this._settings = ExtensionUtils.getSettings('org.gnome.shell.extensions.heads-up-display');
|
||||||
|
+ 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();
|
||||||
|
+
|
||||||
|
+ this._stopWatchingForIdle();
|
||||||
|
+
|
||||||
|
+ 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._screenShieldVisibleId) {
|
||||||
|
+ Main.screenShield._dialog._clock.disconnect(this._screenShieldVisibleId);
|
||||||
|
+ this._screenShieldVisibleId = 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) {
|
||||||
|
+ 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 Meta.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() {
|
||||||
|
+ 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;
|
||||||
|
+
|
||||||
|
+ 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.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));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+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..87a8c8ba
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/extensions/heads-up-display/headsUpMessage.js
|
||||||
|
@@ -0,0 +1,170 @@
|
||||||
|
+const { Atk, Clutter, GLib, 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._widthCoverage = 0.75;
|
||||||
|
+ this._heightCoverage = 0.25;
|
||||||
|
+
|
||||||
|
+ this._workAreasChangedId = global.display.connect('workareas-changed', this._getWorkAreaAndMeasureLineHeight.bind(this));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _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(oldParent) {
|
||||||
|
+ 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];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ destroy() {
|
||||||
|
+ if (this._workAreasChangedId) {
|
||||||
|
+ global.display.disconnect(this._workAreasChangedId);
|
||||||
|
+ this._workAreasChangedId = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ super.destroy();
|
||||||
|
+ }
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+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,
|
||||||
|
+ opacity: 0,
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ 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));
|
||||||
|
+
|
||||||
|
+ const 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);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vfunc_parent_set(oldParent) {
|
||||||
|
+ this._alignWithPanel();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _alignWithPanel() {
|
||||||
|
+ if (this._afterUpdateId)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ this._afterUpdateId = 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._afterUpdateId);
|
||||||
|
+ this._afterUpdateId = 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;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ destroy() {
|
||||||
|
+ if (this._panelAllocationId) {
|
||||||
|
+ Main.layoutManager.panelBox.disconnect(this._panelAllocationId);
|
||||||
|
+ this._panelAllocationId = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (this._afterUpdateId) {
|
||||||
|
+ global.stage.disconnect(this._afterUpdateId);
|
||||||
|
+ this._afterUpdateId = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (this.bodyLabel) {
|
||||||
|
+ this.bodyLabel.destroy();
|
||||||
|
+ this.bodyLabel = null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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..a7106e07
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/extensions/heads-up-display/prefs.js
|
||||||
|
@@ -0,0 +1,194 @@
|
||||||
|
+
|
||||||
|
+/* 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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ .contents {
|
||||||
|
+ padding: 20px;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ .message-label {
|
||||||
|
+ font-weight: bold;
|
||||||
|
+ }
|
||||||
|
+`;
|
||||||
|
+
|
||||||
|
+var settings;
|
||||||
|
+
|
||||||
|
+function init() {
|
||||||
|
+ settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.heads-up-display");
|
||||||
|
+ const cssProvider = new Gtk.CssProvider();
|
||||||
|
+ cssProvider.load_from_data(cssData);
|
||||||
|
+
|
||||||
|
+ const display = Gdk.Display.get_default();
|
||||||
|
+ Gtk.StyleContext.add_provider_for_display(display, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function buildPrefsWidget() {
|
||||||
|
+ ExtensionUtils.initTranslations();
|
||||||
|
+
|
||||||
|
+ const contents = new Gtk.Box({
|
||||||
|
+ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
+ spacing: 10,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ contents.append(buildSwitch('show-when-locked', _("Show message when screen is locked")));
|
||||||
|
+ contents.append(buildSwitch('show-when-unlocking', _("Show message on unlock screen")));
|
||||||
|
+ contents.append(buildSwitch('show-when-unlocked', _("Show message when screen is unlocked")));
|
||||||
|
+ contents.append(buildSpinButton('idle-timeout', _("Seconds after user goes idle before reshowing message")));
|
||||||
|
+ contents.get_style_context().add_class("contents");
|
||||||
|
+
|
||||||
|
+ const outerMessageBox = new Gtk.Box({
|
||||||
|
+ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
+ spacing: 5,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ contents.append(outerMessageBox);
|
||||||
|
+
|
||||||
|
+ const messageLabel = new Gtk.Label({
|
||||||
|
+ label: 'Message',
|
||||||
|
+ halign: Gtk.Align.START,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ messageLabel.get_style_context().add_class("message-label");
|
||||||
|
+ outerMessageBox.append(messageLabel);
|
||||||
|
+
|
||||||
|
+ const innerMessageBox = new Gtk.Box({
|
||||||
|
+ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
+ spacing: 0,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ innerMessageBox.get_style_context().add_class("border");
|
||||||
|
+ outerMessageBox.append(innerMessageBox);
|
||||||
|
+
|
||||||
|
+ innerMessageBox.append(buildEntry('message-heading', _("Message Heading")));
|
||||||
|
+ innerMessageBox.append(buildTextView('message-body', _("Message Body")));
|
||||||
|
+ return contents;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function buildTextView(key, labelText) {
|
||||||
|
+ const textView = new Gtk.TextView({
|
||||||
|
+ accepts_tab: false,
|
||||||
|
+ visible: true,
|
||||||
|
+ wrap_mode: Gtk.WrapMode.WORD,
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ settings.bind(key, textView.get_buffer(), 'text', Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
+
|
||||||
|
+ const scrolledWindow = new Gtk.ScrolledWindow({
|
||||||
|
+ hexpand: true,
|
||||||
|
+ vexpand: true,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ const styleContext = scrolledWindow.get_style_context();
|
||||||
|
+ styleContext.add_class("margins");
|
||||||
|
+
|
||||||
|
+ scrolledWindow.set_child(textView);
|
||||||
|
+ return scrolledWindow;
|
||||||
|
+}
|
||||||
|
+function buildEntry(key, labelText) {
|
||||||
|
+ const entry = new Gtk.Entry({
|
||||||
|
+ placeholder_text: labelText,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ const 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) {
|
||||||
|
+ const hbox = new Gtk.Box({
|
||||||
|
+ orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
+ spacing: 10,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ const label = new Gtk.Label({
|
||||||
|
+ hexpand: true,
|
||||||
|
+ label: labelText,
|
||||||
|
+ visible: true,
|
||||||
|
+ xalign: 0,
|
||||||
|
+ });
|
||||||
|
+ const adjustment = new Gtk.Adjustment({
|
||||||
|
+ value: 0,
|
||||||
|
+ lower: 0,
|
||||||
|
+ upper: 2147483647,
|
||||||
|
+ step_increment: 1,
|
||||||
|
+ page_increment: 60,
|
||||||
|
+ page_size: 60,
|
||||||
|
+ });
|
||||||
|
+ const spinButton = new Gtk.SpinButton({
|
||||||
|
+ adjustment: adjustment,
|
||||||
|
+ climb_rate: 1.0,
|
||||||
|
+ digits: 0,
|
||||||
|
+ max_width_chars: 3,
|
||||||
|
+ visible: true,
|
||||||
|
+ width_chars: 3,
|
||||||
|
+ });
|
||||||
|
+ settings.bind(key, spinButton, 'value', Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
+ hbox.append(label);
|
||||||
|
+ hbox.append(spinButton);
|
||||||
|
+ return hbox;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function buildSwitch(key, labelText) {
|
||||||
|
+ const hbox = new Gtk.Box({
|
||||||
|
+ orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
+ spacing: 10,
|
||||||
|
+ visible: true,
|
||||||
|
+ });
|
||||||
|
+ const label = new Gtk.Label({
|
||||||
|
+ hexpand: true,
|
||||||
|
+ label: labelText,
|
||||||
|
+ visible: true,
|
||||||
|
+ xalign: 0,
|
||||||
|
+ });
|
||||||
|
+ const switcher = new Gtk.Switch({
|
||||||
|
+ active: settings.get_boolean(key),
|
||||||
|
+ });
|
||||||
|
+ settings.bind(key, switcher, 'active', Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
+ hbox.append(label);
|
||||||
|
+ hbox.append(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 582535c4..ecc86fc8 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -39,6 +39,7 @@ classic_extensions = [
|
||||||
|
default_extensions = classic_extensions
|
||||||
|
default_extensions += [
|
||||||
|
'drive-menu',
|
||||||
|
+ 'heads-up-display',
|
||||||
|
'screenshot-window-sizer',
|
||||||
|
'windowsNavigator',
|
||||||
|
'workspace-indicator'
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
From f0e4618bf0752aaf094d78b4c810ebda817ccaad 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 79e2f42..3dfba46 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.32.0
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From a31f4b6ca703faab25c306dc33056763642a83cb Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Fri, 30 Sep 2022 18:16:16 +0200
|
||||||
|
Subject: [PATCH] window-list: Explicitly dispose settings on destroy
|
||||||
|
|
||||||
|
This will not only disconnect the signal handler, but also remove
|
||||||
|
any bindings. This works around a crash that happens if a setting
|
||||||
|
that triggers the binding changes at the same time as a setting
|
||||||
|
that rebuilds the window list; in that case, the binding handler
|
||||||
|
runs after gjs has dropped its wrapper object, but before the
|
||||||
|
binding is removed automaticalled when the object is finalized.
|
||||||
|
|
||||||
|
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/416
|
||||||
|
|
||||||
|
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/243>
|
||||||
|
---
|
||||||
|
extensions/window-list/extension.js | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
|
||||||
|
index 89413818..91ee3e6b 100644
|
||||||
|
--- a/extensions/window-list/extension.js
|
||||||
|
+++ b/extensions/window-list/extension.js
|
||||||
|
@@ -842,8 +842,8 @@ class WindowList extends St.Widget {
|
||||||
|
this._dndWindow = null;
|
||||||
|
|
||||||
|
this._settings = ExtensionUtils.getSettings();
|
||||||
|
- this._groupingModeChangedId = this._settings.connect(
|
||||||
|
- 'changed::grouping-mode', this._groupingModeChanged.bind(this));
|
||||||
|
+ this._settings.connect('changed::grouping-mode',
|
||||||
|
+ () => this._groupingModeChanged());
|
||||||
|
this._grouped = undefined;
|
||||||
|
this._groupingModeChanged();
|
||||||
|
}
|
||||||
|
@@ -1112,7 +1112,7 @@ class WindowList extends St.Widget {
|
||||||
|
Main.xdndHandler.disconnect(this._dragBeginId);
|
||||||
|
Main.xdndHandler.disconnect(this._dragEndId);
|
||||||
|
|
||||||
|
- this._settings.disconnect(this._groupingModeChangedId);
|
||||||
|
+ this._settings.run_dispose();
|
||||||
|
|
||||||
|
let windows = global.get_window_actors();
|
||||||
|
for (let i = 0; i < windows.length; i++)
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,231 @@
|
|||||||
|
From afa394114c57197e96f18e7942729634ece5d3c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Wed, 19 May 2021 16:46:59 +0200
|
||||||
|
Subject: [PATCH 1/2] desktop-icons: Revert "Use GTK-Theme CSS for selected
|
||||||
|
file-item and rubberband"
|
||||||
|
|
||||||
|
GtkStyleContext requires a (X11) display connection, which may not
|
||||||
|
be available with xwayland-on-demand. Better use some hardcoded
|
||||||
|
colors than crashing the session.
|
||||||
|
|
||||||
|
This reverts commit 8dc524aa4efd6a3fbad67480bd6c904b0c0c99d6.
|
||||||
|
---
|
||||||
|
extensions/desktop-icons/desktopIconsUtil.js | 11 ----------
|
||||||
|
extensions/desktop-icons/desktopManager.js | 12 -----------
|
||||||
|
extensions/desktop-icons/fileItem.js | 22 ++++----------------
|
||||||
|
extensions/desktop-icons/stylesheet.css | 9 ++++++++
|
||||||
|
4 files changed, 13 insertions(+), 41 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/desktop-icons/desktopIconsUtil.js b/extensions/desktop-icons/desktopIconsUtil.js
|
||||||
|
index 696c945..57bedc1 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopIconsUtil.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopIconsUtil.js
|
||||||
|
@@ -16,7 +16,6 @@
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-const Gtk = imports.gi.Gtk;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
|
@@ -114,16 +113,6 @@ function getFileExtensionOffset(filename, isDirectory) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
-function getGtkClassBackgroundColor(classname, state) {
|
||||||
|
- let widget = new Gtk.WidgetPath();
|
||||||
|
- widget.append_type(Gtk.Widget);
|
||||||
|
-
|
||||||
|
- let context = new Gtk.StyleContext();
|
||||||
|
- context.set_path(widget);
|
||||||
|
- context.add_class(classname);
|
||||||
|
- return context.get_background_color(state);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
// Reference the extension org.gnome.shell.extensions.drive-menu
|
||||||
|
function eject(mount) {
|
||||||
|
let unmountArgs = [
|
||||||
|
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
|
||||||
|
index 1aad8c6..10e3ce0 100644
|
||||||
|
--- a/extensions/desktop-icons/desktopManager.js
|
||||||
|
+++ b/extensions/desktop-icons/desktopManager.js
|
||||||
|
@@ -16,7 +16,6 @@
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-const Gtk = imports.gi.Gtk;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GObject = imports.gi.GObject;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
@@ -132,7 +131,6 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
startRubberBand(x, y) {
|
||||||
|
this._rubberBandInitialX = x;
|
||||||
|
this._rubberBandInitialY = y;
|
||||||
|
- this._initRubberBandColor();
|
||||||
|
this._updateRubberBand(x, y);
|
||||||
|
this._rubberBand.show();
|
||||||
|
this._grabHelper.grab({ actor: global.stage });
|
||||||
|
@@ -235,16 +233,6 @@ var DesktopManager = GObject.registerClass({
|
||||||
|
this._desktopGrids = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
- /**
|
||||||
|
- * Initialize rubberband color from the GTK rubberband class
|
||||||
|
- * */
|
||||||
|
- _initRubberBandColor() {
|
||||||
|
- let rgba = DesktopIconsUtil.getGtkClassBackgroundColor('rubberband', Gtk.StateFlags.NORMAL);
|
||||||
|
- let background_color =
|
||||||
|
- 'rgba(' + rgba.red * 255 + ', ' + rgba.green * 255 + ', ' + rgba.blue * 255 + ', 0.4)';
|
||||||
|
- this._rubberBand.set_style('background-color: ' + background_color);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
async _scanFiles() {
|
||||||
|
for (let [fileItem, fileItemHandler] of this._fileItemHandlers)
|
||||||
|
Object.values(fileItemHandler).forEach(id => fileItem.disconnect(id));
|
||||||
|
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
|
||||||
|
index 9987e7f..1e8ea89 100644
|
||||||
|
--- a/extensions/desktop-icons/fileItem.js
|
||||||
|
+++ b/extensions/desktop-icons/fileItem.js
|
||||||
|
@@ -16,7 +16,6 @@
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-const Gtk = imports.gi.Gtk;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
@@ -649,17 +648,6 @@ var FileItem = GObject.registerClass({
|
||||||
|
DBusUtils.openFileWithOtherApplication(this.file.get_path());
|
||||||
|
}
|
||||||
|
|
||||||
|
- _getSelectionStyle() {
|
||||||
|
- let rgba = DesktopIconsUtil.getGtkClassBackgroundColor('view', Gtk.StateFlags.SELECTED);
|
||||||
|
- let background_color =
|
||||||
|
- 'rgba(' + rgba.red * 255 + ', ' + rgba.green * 255 + ', ' + rgba.blue * 255 + ', 0.6)';
|
||||||
|
- let border_color =
|
||||||
|
- 'rgba(' + rgba.red * 255 + ', ' + rgba.green * 255 + ', ' + rgba.blue * 255 + ', 0.8)';
|
||||||
|
-
|
||||||
|
- return 'background-color: ' + background_color + ';' +
|
||||||
|
- 'border-color: ' + border_color + ';';
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
get menu() {
|
||||||
|
return this._menu;
|
||||||
|
}
|
||||||
|
@@ -901,12 +889,10 @@ var FileItem = GObject.registerClass({
|
||||||
|
if (isSelected == this._isSelected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- if (isSelected) {
|
||||||
|
- this._container.set_style(this._getSelectionStyle());
|
||||||
|
- } else {
|
||||||
|
- this._container.set_style('background-color: transparent');
|
||||||
|
- this._container.set_style('border-color: transparent');
|
||||||
|
- }
|
||||||
|
+ if (isSelected)
|
||||||
|
+ this._container.add_style_pseudo_class('selected');
|
||||||
|
+ else
|
||||||
|
+ this._container.remove_style_pseudo_class('selected');
|
||||||
|
|
||||||
|
this._isSelected = isSelected;
|
||||||
|
}
|
||||||
|
diff --git a/extensions/desktop-icons/stylesheet.css b/extensions/desktop-icons/stylesheet.css
|
||||||
|
index 61b4ce8..4fd31c3 100644
|
||||||
|
--- a/extensions/desktop-icons/stylesheet.css
|
||||||
|
+++ b/extensions/desktop-icons/stylesheet.css
|
||||||
|
@@ -8,6 +8,15 @@
|
||||||
|
background-color: rgba(238, 238, 238, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
+.file-item:selected {
|
||||||
|
+ background-color: rgba(74, 144, 217, 0.6);
|
||||||
|
+ border-color: rgba(74, 144, 217, 0.8);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+.rubber-band {
|
||||||
|
+ background-color: rgba(74, 144, 238, 0.4);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
.name-label {
|
||||||
|
text-shadow: 1px 1px black;
|
||||||
|
color: white;
|
||||||
|
--
|
||||||
|
2.32.0
|
||||||
|
|
||||||
|
|
||||||
|
From ca050d098240b3e757f172d2012f7d1b91db3ff6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
Date: Fri, 21 May 2021 00:50:52 +0200
|
||||||
|
Subject: [PATCH 2/2] desktop-icons: Port prefs to GTK4
|
||||||
|
|
||||||
|
... for compatibility with GNOME 40.
|
||||||
|
---
|
||||||
|
extensions/desktop-icons/prefs.js | 32 ++++++++++++++++++-------------
|
||||||
|
1 file changed, 19 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/extensions/desktop-icons/prefs.js b/extensions/desktop-icons/prefs.js
|
||||||
|
index 890bcdb..c390aa8 100644
|
||||||
|
--- a/extensions/desktop-icons/prefs.js
|
||||||
|
+++ b/extensions/desktop-icons/prefs.js
|
||||||
|
@@ -98,23 +98,29 @@ function get_schema(schema) {
|
||||||
|
|
||||||
|
function buildPrefsWidget() {
|
||||||
|
initTranslations();
|
||||||
|
- let frame = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, border_width: 10, spacing: 10 });
|
||||||
|
-
|
||||||
|
- frame.add(buildSelector('icon-size', _("Size for the desktop icons"), { 'small': _("Small"), 'standard': _("Standard"), 'large': _("Large") }));
|
||||||
|
- frame.add(buildSwitcher('show-home', _("Show the personal folder in the desktop")));
|
||||||
|
- frame.add(buildSwitcher('show-trash', _("Show the trash icon in the desktop")));
|
||||||
|
- frame.add(buildSwitcher('show-mount', _("Show mounted drives in the desktop")));
|
||||||
|
- frame.show_all();
|
||||||
|
+ let frame = new Gtk.Box({
|
||||||
|
+ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
+ margin_top: 10,
|
||||||
|
+ margin_bottom: 10,
|
||||||
|
+ margin_start: 10,
|
||||||
|
+ margin_end: 10,
|
||||||
|
+ spacing: 10,
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ frame.append(buildSelector('icon-size', _("Size for the desktop icons"), { 'small': _("Small"), 'standard': _("Standard"), 'large': _("Large") }));
|
||||||
|
+ frame.append(buildSwitcher('show-home', _("Show the personal folder in the desktop")));
|
||||||
|
+ frame.append(buildSwitcher('show-trash', _("Show the trash icon in the desktop")));
|
||||||
|
+ frame.append(buildSwitcher('show-mount', _("Show mounted drives in the desktop")));
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildSwitcher(key, labelText) {
|
||||||
|
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 10 });
|
||||||
|
- let label = new Gtk.Label({ label: labelText, xalign: 0 });
|
||||||
|
+ let label = new Gtk.Label({ label: labelText, xalign: 0, hexpand: true });
|
||||||
|
let switcher = new Gtk.Switch({ active: settings.get_boolean(key) });
|
||||||
|
settings.bind(key, switcher, 'active', 3);
|
||||||
|
- hbox.pack_start(label, true, true, 0);
|
||||||
|
- hbox.add(switcher);
|
||||||
|
+ hbox.append(label);
|
||||||
|
+ hbox.append(switcher);
|
||||||
|
return hbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -131,15 +137,15 @@ function buildSelector(key, labelText, elements) {
|
||||||
|
listStore.set (iter, [0, 1], [visibleText, val]);
|
||||||
|
}
|
||||||
|
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 10 });
|
||||||
|
- let label = new Gtk.Label({ label: labelText, xalign: 0 });
|
||||||
|
+ let label = new Gtk.Label({ label: labelText, xalign: 0, hexpand: true });
|
||||||
|
let combo = new Gtk.ComboBox({model: listStore});
|
||||||
|
let rendererText = new Gtk.CellRendererText();
|
||||||
|
combo.pack_start (rendererText, false);
|
||||||
|
combo.add_attribute (rendererText, 'text', 0);
|
||||||
|
combo.set_id_column(1);
|
||||||
|
settings.bind(key, combo, 'active-id', 3);
|
||||||
|
- hbox.pack_start(label, true, true, 0);
|
||||||
|
- hbox.add(combo);
|
||||||
|
+ hbox.append(label);
|
||||||
|
+ hbox.append(combo);
|
||||||
|
return hbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.32.0
|
||||||
|
|
@ -0,0 +1,158 @@
|
|||||||
|
From 1692d4a91d95fecd5642b0c92bc2c5b0dbcb4184 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Neal Gompa <ngompa@fedoraproject.org>
|
||||||
|
Date: Fri, 29 Oct 2021 09:37:33 -0400
|
||||||
|
Subject: [PATCH] classic: Install the session for Wayland and ship override
|
||||||
|
sessions
|
||||||
|
|
||||||
|
The regular GNOME session ships with three options:
|
||||||
|
|
||||||
|
* GNOME
|
||||||
|
* GNOME on Wayland (available when GDM starts in X11)
|
||||||
|
* GNOME on Xorg (available when GDM starts in Wayland)
|
||||||
|
|
||||||
|
The main GNOME session is set up so it works to match how GDM starts,
|
||||||
|
so GNOME is on Wayland if GDM is (or GNOME is on X11 if GDM is).
|
||||||
|
|
||||||
|
For GNOME Classic, we are missing this setup, so port this behavior
|
||||||
|
over from the GNOME session setup.
|
||||||
|
|
||||||
|
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/195>
|
||||||
|
---
|
||||||
|
data/gnome-classic-wayland.desktop.in | 8 ++++++
|
||||||
|
data/gnome-classic-xorg.desktop.in | 8 ++++++
|
||||||
|
data/meson.build | 40 +++++++++++++++++++++------
|
||||||
|
meson.build | 5 ++++
|
||||||
|
meson/session-post-install.py | 20 ++++++++++++++
|
||||||
|
5 files changed, 72 insertions(+), 9 deletions(-)
|
||||||
|
create mode 100644 data/gnome-classic-wayland.desktop.in
|
||||||
|
create mode 100644 data/gnome-classic-xorg.desktop.in
|
||||||
|
create mode 100755 meson/session-post-install.py
|
||||||
|
|
||||||
|
diff --git a/data/gnome-classic-wayland.desktop.in b/data/gnome-classic-wayland.desktop.in
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..7287c689
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/data/gnome-classic-wayland.desktop.in
|
||||||
|
@@ -0,0 +1,8 @@
|
||||||
|
+[Desktop Entry]
|
||||||
|
+Name=GNOME Classic on Wayland
|
||||||
|
+Comment=This session logs you into GNOME Classic
|
||||||
|
+Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session
|
||||||
|
+TryExec=gnome-session
|
||||||
|
+Type=Application
|
||||||
|
+DesktopNames=GNOME-Classic;GNOME;
|
||||||
|
+X-GDM-SessionRegisters=true
|
||||||
|
diff --git a/data/gnome-classic-xorg.desktop.in b/data/gnome-classic-xorg.desktop.in
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..5fb338a1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/data/gnome-classic-xorg.desktop.in
|
||||||
|
@@ -0,0 +1,8 @@
|
||||||
|
+[Desktop Entry]
|
||||||
|
+Name=GNOME Classic on Xorg
|
||||||
|
+Comment=This session logs you into GNOME Classic
|
||||||
|
+Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session
|
||||||
|
+TryExec=gnome-session
|
||||||
|
+Type=Application
|
||||||
|
+DesktopNames=GNOME-Classic;GNOME;
|
||||||
|
+X-GDM-SessionRegisters=true
|
||||||
|
diff --git a/data/meson.build b/data/meson.build
|
||||||
|
index 27f42872..47fe798e 100644
|
||||||
|
--- a/data/meson.build
|
||||||
|
+++ b/data/meson.build
|
||||||
|
@@ -1,12 +1,34 @@
|
||||||
|
-session_desktop = 'gnome-classic.desktop'
|
||||||
|
-i18n.merge_file('',
|
||||||
|
- input: session_desktop + '.in',
|
||||||
|
- output: session_desktop,
|
||||||
|
- po_dir: '../po',
|
||||||
|
- install: true,
|
||||||
|
- install_dir: xsessiondir,
|
||||||
|
- type: 'desktop'
|
||||||
|
-)
|
||||||
|
+session_desktop_base = 'gnome-classic'
|
||||||
|
+
|
||||||
|
+session_desktops = [
|
||||||
|
+ session_desktop_base,
|
||||||
|
+ session_desktop_base + '-xorg',
|
||||||
|
+ session_desktop_base + '-wayland',
|
||||||
|
+]
|
||||||
|
+
|
||||||
|
+foreach name: session_desktops
|
||||||
|
+ session_desktop = name + '.desktop'
|
||||||
|
+ if name.endswith('-xorg')
|
||||||
|
+ session_instdir = xsessiondir
|
||||||
|
+ elif name.endswith('-wayland')
|
||||||
|
+ session_instdir = wlsessiondir
|
||||||
|
+ else
|
||||||
|
+ # FIXME: The same target can not be copied into two directories.
|
||||||
|
+ # There is a workaround in meson/session-post-install.py until proper
|
||||||
|
+ # solution arises:
|
||||||
|
+ # https://github.com/mesonbuild/meson/issues/2416
|
||||||
|
+ session_instdir = xsessiondir
|
||||||
|
+ #session_instdir = [ xesssiondir, wlsessiondir ]
|
||||||
|
+ endif
|
||||||
|
+ i18n.merge_file('',
|
||||||
|
+ input: session_desktop + '.in',
|
||||||
|
+ output: session_desktop,
|
||||||
|
+ po_dir: '../po',
|
||||||
|
+ install: true,
|
||||||
|
+ install_dir: session_instdir,
|
||||||
|
+ type: 'desktop'
|
||||||
|
+ )
|
||||||
|
+endforeach
|
||||||
|
|
||||||
|
classic_uuids = []
|
||||||
|
foreach e : classic_extensions
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index dda3ddac..ea8a859d 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -20,6 +20,7 @@ themedir = join_paths(shelldir, 'theme')
|
||||||
|
schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
|
||||||
|
sessiondir = join_paths(datadir, 'gnome-session', 'sessions')
|
||||||
|
xsessiondir = join_paths(datadir, 'xsessions')
|
||||||
|
+wlsessiondir = join_paths(datadir, 'wayland-sessions')
|
||||||
|
|
||||||
|
ver_arr = meson.project_version().split('.')
|
||||||
|
shell_version = ver_arr[0]
|
||||||
|
@@ -90,6 +91,10 @@ endforeach
|
||||||
|
|
||||||
|
if classic_mode_enabled
|
||||||
|
subdir('data')
|
||||||
|
+ meson.add_install_script(
|
||||||
|
+ 'meson/session-post-install.py',
|
||||||
|
+ join_paths(get_option('prefix'), datadir)
|
||||||
|
+ )
|
||||||
|
endif
|
||||||
|
|
||||||
|
subdir('extensions')
|
||||||
|
diff --git a/meson/session-post-install.py b/meson/session-post-install.py
|
||||||
|
new file mode 100755
|
||||||
|
index 00000000..36abe5e4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/meson/session-post-install.py
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+#!/usr/bin/env python3
|
||||||
|
+
|
||||||
|
+import os
|
||||||
|
+import shutil
|
||||||
|
+import sys
|
||||||
|
+
|
||||||
|
+if os.environ.get('DESTDIR'):
|
||||||
|
+ install_root = os.environ.get('DESTDIR') + os.path.abspath(sys.argv[1])
|
||||||
|
+else:
|
||||||
|
+ install_root = sys.argv[1]
|
||||||
|
+
|
||||||
|
+# FIXME: Meson is unable to copy a generated target file:
|
||||||
|
+# https://groups.google.com/forum/#!topic/mesonbuild/3iIoYPrN4P0
|
||||||
|
+dst_dir = os.path.join(install_root, 'wayland-sessions')
|
||||||
|
+if not os.path.exists(dst_dir):
|
||||||
|
+ os.makedirs(dst_dir)
|
||||||
|
+
|
||||||
|
+src = os.path.join(install_root, 'xsessions', 'gnome-classic.desktop')
|
||||||
|
+dst = os.path.join(dst_dir, 'gnome-classic.desktop')
|
||||||
|
+shutil.copyfile(src, dst)
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,116 @@
|
|||||||
|
From 0d9210e9c19c1bd9535ffb75b4834c2ccd8db6c2 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 e122cf5f..43885378 100644
|
||||||
|
--- a/extensions/window-list/extension.js
|
||||||
|
+++ b/extensions/window-list/extension.js
|
||||||
|
@@ -381,7 +381,7 @@ class WindowButton extends BaseButton {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (button === 1)
|
||||||
|
+ if (!button || button === 1)
|
||||||
|
_minimizeOrActivateWindow(this.metaWindow);
|
||||||
|
else
|
||||||
|
_openMenu(this._contextMenu);
|
||||||
|
@@ -623,7 +623,7 @@ class AppButton extends BaseButton {
|
||||||
|
if (contextMenuWasOpen)
|
||||||
|
this._contextMenu.close();
|
||||||
|
|
||||||
|
- if (button === 1) {
|
||||||
|
+ if (!button || button === 1) {
|
||||||
|
if (menuWasOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.36.1
|
||||||
|
|
||||||
|
|
||||||
|
From b080bb7ee88d0e5b35dc4a967d2e44eab7921b6f 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 | 42 +++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 42 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
|
||||||
|
index 43885378..3d1cd053 100644
|
||||||
|
--- a/extensions/window-list/extension.js
|
||||||
|
+++ b/extensions/window-list/extension.js
|
||||||
|
@@ -266,6 +266,48 @@ const BaseButton = GObject.registerClass({
|
||||||
|
this._updateVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ _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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vfunc_button_press_event(buttonEvent) {
|
||||||
|
+ if (buttonEvent.button === 1)
|
||||||
|
+ this._setLongPressTimeout();
|
||||||
|
+ return super.vfunc_button_press_event(buttonEvent);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vfunc_button_release_event(buttonEvent) {
|
||||||
|
+ this._removeLongPressTimeout();
|
||||||
|
+
|
||||||
|
+ return super.vfunc_button_release_event(buttonEvent);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vfunc_touch_event(touchEvent) {
|
||||||
|
+ if (touchEvent.type === Clutter.EventType.TOUCH_BEGIN)
|
||||||
|
+ this._setLongPressTimeout();
|
||||||
|
+ else if (touchEvent.type === Clutter.EventType.TOUCH_END)
|
||||||
|
+ this._removeLongPressTimeout();
|
||||||
|
+ return super.vfunc_touch_event(touchEvent);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
activate() {
|
||||||
|
if (this.active)
|
||||||
|
return;
|
||||||
|
--
|
||||||
|
2.36.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue