import gnome-shell-extensions-40.7-2.el9

i9c changed/i9c/gnome-shell-extensions-40.7-2.el9
MSVSphere Packaging Team 2 years ago
commit 7fbc83005d

1
.gitignore vendored

@ -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 95bf73c668eab5c222568bdb6a3030a5bed8d4d3 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 8b67435b..fd328df5 100644
--- a/meson.build
+++ b/meson.build
@@ -48,6 +48,7 @@ all_extensions += [
'auto-move-windows',
'classification-banner',
'dash-to-dock',
+ 'gesture-inhibitor',
'native-window-placement',
'panel-favorites',
'systemMonitor',
--
2.33.1
From 89daf03fcc0f7b157e90a5ef4487e94e27fe8d38 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.33.1
From 00ffe8e51dbb8609461239d753d2215e66b2b76d 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.33.1
From cd42930b27efbffdac6b259bf7417a4528f5bfdf 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.33.1
From 294fe1f115d8c23e71608c34be296dd0080f2671 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.33.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,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,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

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

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save