Auto sync2gitlab import of gnome-shell-extensions-3.32.1-27.el8.src.rpm

This commit is contained in:
James Antill 2022-05-26 07:49:12 -04:00
parent 5662517195
commit 8e1429a488
29 changed files with 79732 additions and 1 deletions

1
.gitignore vendored Normal file
View File

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

View File

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

View File

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

View File

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

98
0001-Update-style.patch Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1
EMPTY
View File

@ -1 +0,0 @@

71431
add-extra-extensions.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
From 1f9f4af38f991b462ee5f872a697d88a9e115499 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 20 Jan 2021 20:18:39 +0100
Subject: [PATCH 1/2] workspace-indicator: Add tooltips to workspace thumbnails
When showing previews instead of the menu, the workspace names from
our preferences don't appear anywhere. Some users care strongly about
those, so expose them as tooltip on hover.
---
extensions/workspace-indicator/extension.js | 40 +++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js
index 69eef88c..b10e37ff 100644
--- a/extensions/workspace-indicator/extension.js
+++ b/extensions/workspace-indicator/extension.js
@@ -8,6 +8,7 @@ const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
+const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
@@ -15,6 +16,9 @@ const _ = Gettext.gettext;
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
const WORKSPACE_KEY = 'workspace-names';
+const TOOLTIP_OFFSET = 6;
+const TOOLTIP_ANIMATION_TIME = 150;
+
let WindowPreview = GObject.registerClass({
GTypeName: 'WorkspaceIndicatorWindowPreview'
}, class WindowPreview extends St.Button {
@@ -117,7 +121,14 @@ let WorkspaceThumbnail = GObject.registerClass({
y_fill: true
});
+ this._tooltip = new St.Label({
+ style_class: 'dash-label',
+ visible: false,
+ });
+ Main.uiGroup.add_child(this._tooltip);
+
this.connect('destroy', this._onDestroy.bind(this));
+ this.connect('notify::hover', this._syncTooltip.bind(this));
this._index = index;
this._delegate = this; // needed for DND
@@ -204,7 +215,36 @@ let WorkspaceThumbnail = GObject.registerClass({
ws.activate(global.get_current_time());
}
+ _syncTooltip() {
+ if (this.hover) {
+ this._tooltip.text = Meta.prefs_get_workspace_name(this._index);
+ this._tooltip.opacity = 0;
+ this._tooltip.show();
+
+ const [stageX, stageY] = this.get_transformed_position();
+ const thumbWidth = this.allocation.get_width();
+ const thumbHeight = this.allocation.get_height();
+ const tipWidth = this._tooltip.width;
+ const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
+ const monitor = Main.layoutManager.findMonitorForActor(this);
+ const x = Math.min(
+ Math.max(stageX + xOffset, monitor.x),
+ monitor.x + monitor.width - tipWidth);
+ const y = stageY + thumbHeight + TOOLTIP_OFFSET;
+ this._tooltip.set_position(x, y);
+ }
+
+ Tweener.addTween(this._tooltip, {
+ opacity: this.hover ? 255 : 0,
+ time: TOOLTIP_ANIMATION_TIME * 1000,
+ transition: 'easeOutQuad',
+ onComplete: () => (this._tooltip.visible = this.hover),
+ });
+ }
+
_onDestroy() {
+ this._tooltip.destroy();
+
this._workspace.disconnect(this._windowAddedId);
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
--
2.31.1
From 19e19e11214b6b9deae110cd6a4c9232d77c18cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 20 Jan 2021 20:29:01 +0100
Subject: [PATCH 2/2] window-list: Add tooltips to workspace thumbnails
When showing previews instead of the menu, the workspace names
don't appear anywhere. Some users care strongly about those, so
expose them as tooltip on hover.
---
extensions/window-list/workspaceIndicator.js | 40 ++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js
index ca476111..33ec9b0e 100644
--- a/extensions/window-list/workspaceIndicator.js
+++ b/extensions/window-list/workspaceIndicator.js
@@ -5,10 +5,14 @@ const DND = imports.ui.dnd;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
+const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
+const TOOLTIP_OFFSET = 6;
+const TOOLTIP_ANIMATION_TIME = 150;
+
let WindowPreview = GObject.registerClass({
GTypeName: 'WindowListWindowPreview'
}, class WindowPreview extends St.Button {
@@ -111,7 +115,14 @@ let WorkspaceThumbnail = GObject.registerClass({
y_fill: true
});
+ this._tooltip = new St.Label({
+ style_class: 'dash-label',
+ visible: false,
+ });
+ Main.uiGroup.add_child(this._tooltip);
+
this.connect('destroy', this._onDestroy.bind(this));
+ this.connect('notify::hover', this._syncTooltip.bind(this));
this._index = index;
this._delegate = this; // needed for DND
@@ -198,7 +209,36 @@ let WorkspaceThumbnail = GObject.registerClass({
ws.activate(global.get_current_time());
}
+ _syncTooltip() {
+ if (this.hover) {
+ this._tooltip.text = Meta.prefs_get_workspace_name(this._index);
+ this._tooltip.opacity = 0;
+ this._tooltip.show();
+
+ const [stageX, stageY] = this.get_transformed_position();
+ const thumbWidth = this.allocation.get_width();
+ const tipWidth = this._tooltip.width;
+ const tipHeight = this._tooltip.height;
+ const xOffset = Math.floor((thumbWidth - tipWidth) / 2);
+ const monitor = Main.layoutManager.findMonitorForActor(this);
+ const x = Math.min(
+ Math.max(stageX + xOffset, monitor.x),
+ monitor.x + monitor.width - tipWidth);
+ const y = stageY - tipHeight - TOOLTIP_OFFSET;
+ this._tooltip.set_position(x, y);
+ }
+
+ Tweener.addTween(this._tooltip, {
+ opacity: this.hover ? 255 : 0,
+ time: TOOLTIP_ANIMATION_TIME * 1000,
+ transition: 'easeOutQuad',
+ onComplete: () => (this._tooltip.visible = this.hover),
+ });
+ }
+
_onDestroy() {
+ this._tooltip.destroy();
+
this._workspace.disconnect(this._windowAddedId);
this._workspace.disconnect(this._windowRemovedId);
global.display.disconnect(this._restackedId);
--
2.31.1

View File

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

View File

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

27
gnome-classic.desktop Normal file
View File

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

1159
gnome-shell-extensions.spec Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (gnome-shell-extensions-3.32.1.tar.xz) = e587a17eace87e05211bd4a0b8101a731054c99ba708051f6549c5e19974ccfeff75b0802d190d327f5ee8b4595c20e747d492f82c86aa76e0fc1cf3d20f0e4e