Compare commits

...

No commits in common. "c8" and "c9-beta" have entirely different histories.
c8 ... c9-beta

54 changed files with 72062 additions and 25428 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/gnome-shell-extensions-3.32.1.tar.xz
SOURCES/gnome-shell-extensions-40.7.tar.xz

View File

@ -1 +1 @@
51c1c16bcd0dc9125834b32d7c539c38fa9c4f52 SOURCES/gnome-shell-extensions-3.32.1.tar.xz
a905a152407590d18e8dc14bb4133fbde0e03abb SOURCES/gnome-shell-extensions-40.7.tar.xz

View File

@ -1,7 +1,7 @@
From 2a498fef3ec02d834346b545aeacba0a6224494e Mon Sep 17 00:00:00 2001
From cca3ca69a5b5a5551a9130ab4b9ea6909666108a 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
Subject: [PATCH 1/5] Add gesture-inhibitor extension
This extension may disable default GNOME Shell gestures.
---
@ -170,17 +170,269 @@ index 00000000..37b93f21
@@ -0,0 +1 @@
+/* Add your custom extension styling here */
diff --git a/meson.build b/meson.build
index e163b84d..ba84f8f3 100644
index ec600041..615dc5b0 100644
--- a/meson.build
+++ b/meson.build
@@ -55,6 +55,7 @@ all_extensions += [
@@ -50,6 +50,7 @@ all_extensions += [
'custom-menu',
'dash-to-dock',
'dash-to-panel',
'disable-screenshield',
+ 'gesture-inhibitor',
'native-window-placement',
'no-hot-corner',
'panel-favorites',
'systemMonitor',
--
2.32.0
2.41.0
From 45e88e7b5bb9537c44384a23af7d00f023d55793 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.41.0
From fe0dd05f0c8c5cfeb5edbc6b9bb73417d42f6ee8 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.41.0
From 952fa19311faecf50b02ab0f8807c2bc890848be 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.41.0
From ef7a6cb1eac7b3d6d4d047174502d88f4e78959e 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.41.0

View File

@ -0,0 +1,231 @@
From 50c6c0c2137fded5f89be5bbee2292071e464cd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 21 May 2024 19:01:30 +0200
Subject: [PATCH] Add move-notifications extension
---
extensions/move-notifications/extension.js | 49 +++++++++++
extensions/move-notifications/meson.build | 8 ++
.../move-notifications/metadata.json.in | 10 +++
....extensions.move-notifications.gschema.xml | 14 +++
extensions/move-notifications/prefs.js | 86 +++++++++++++++++++
meson.build | 1 +
6 files changed, 168 insertions(+)
create mode 100644 extensions/move-notifications/extension.js
create mode 100644 extensions/move-notifications/meson.build
create mode 100644 extensions/move-notifications/metadata.json.in
create mode 100644 extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml
create mode 100644 extensions/move-notifications/prefs.js
diff --git a/extensions/move-notifications/extension.js b/extensions/move-notifications/extension.js
new file mode 100644
index 00000000..0211696d
--- /dev/null
+++ b/extensions/move-notifications/extension.js
@@ -0,0 +1,49 @@
+/* exported init */
+const Clutter = imports.gi.Clutter;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Main = imports.ui.main;
+
+class MoveNotificationsExtension {
+ enable() {
+ const updatePanel = Main.panel._updatePanel;
+ this._updatePanelOrig = updatePanel;
+
+ Main.panel._updatePanel = () => {
+ updatePanel.call(Main.panel);
+
+ Main.messageTray.bannerAlignment = this._getAlignment();
+ };
+
+ this._settings = ExtensionUtils.getSettings();
+ this._changedId = this._settings.connect('changed::position',
+ () => Main.panel._updatePanel());
+ Main.panel._updatePanel();
+ }
+
+ disable() {
+ this._settings.disconnect(this._changedId);
+ this._settings = null;
+
+ Main.panel._updatePanel = this._updatePanelOrig;
+ delete this._updatePanelOrig;
+
+ Main.panel._updatePanel();
+ }
+
+ _getAlignment() {
+ switch (this._settings.get_string('position')) {
+ case 'top-left':
+ return Clutter.ActorAlign.START;
+ case 'top-right':
+ return Clutter.ActorAlign.END;
+ case 'top-center':
+ default:
+ return Clutter.ActorAlign.CENTER;
+ }
+ }
+}
+
+function init() {
+ return new MoveNotificationsExtension();
+}
diff --git a/extensions/move-notifications/meson.build b/extensions/move-notifications/meson.build
new file mode 100644
index 00000000..c55a7830
--- /dev/null
+++ b/extensions/move-notifications/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/move-notifications/metadata.json.in b/extensions/move-notifications/metadata.json.in
new file mode 100644
index 00000000..cae9352c
--- /dev/null
+++ b/extensions/move-notifications/metadata.json.in
@@ -0,0 +1,10 @@
+{
+ "uuid": "@uuid@",
+ "extension-id": "@extension_id@",
+ "settings-schema": "@gschemaname@",
+ "gettext-domain": "@gettext_domain@",
+ "name": "Move notifications",
+ "description": "Move notification banners",
+ "shell-version": [ "@shell_current@" ],
+ "url": "@url@"
+}
diff --git a/extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml b/extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml
new file mode 100644
index 00000000..a78d72bb
--- /dev/null
+++ b/extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml
@@ -0,0 +1,14 @@
+<schemalist gettext-domain="gnome-shell-extensions">
+ <enum id="org.gnome.shell.extensions.move-notifications.position">
+ <value nick="top-center" value="0"/>
+ <value nick="top-right" value="1"/>
+ <value nick="top-left" value="2"/>
+ </enum>
+
+ <schema id="org.gnome.shell.extensions.move-notifications" path="/org/gnome/shell/extensions/move-notifications/">
+ <key name="position" enum="org.gnome.shell.extensions.move-notifications.position">
+ <default>"top-right"</default>
+ <summary>Notification position</summary>
+ </key>
+ </schema>
+</schemalist>
diff --git a/extensions/move-notifications/prefs.js b/extensions/move-notifications/prefs.js
new file mode 100644
index 00000000..a3ecdacf
--- /dev/null
+++ b/extensions/move-notifications/prefs.js
@@ -0,0 +1,86 @@
+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
+/* exported init buildPrefsWidget */
+
+const { Gio, GLib, GObject, Gtk } = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = ExtensionUtils.getCurrentExtension();
+
+const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
+const _ = Gettext.gettext;
+
+/** */
+function init() {
+ ExtensionUtils.initTranslations();
+}
+
+const MoveNotificationsPrefsWidget = GObject.registerClass(
+class MoveNotificationsPrefsWidget extends Gtk.Box {
+ _init() {
+ super._init({
+ orientation: Gtk.Orientation.VERTICAL,
+ spacing: 6,
+ margin_top: 36,
+ margin_bottom: 36,
+ margin_start: 36,
+ margin_end: 36,
+ halign: Gtk.Align.CENTER,
+ });
+
+ this._actionGroup = new Gio.SimpleActionGroup();
+ this.insert_action_group('move-notifications', this._actionGroup);
+
+ this._settings = ExtensionUtils.getSettings();
+ this._actionGroup.add_action(
+ this._settings.create_action('position'));
+
+ const title = new Gtk.Label({
+ label: _('Notification Position'),
+ halign: Gtk.Align.START,
+ });
+ title.add_css_class('heading');
+ this.append(title);
+
+ const box = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ spacing: 12,
+ margin_bottom: 12,
+ });
+ this.append(box);
+
+ const context = box.get_style_context();
+ const cssProvider = new Gtk.CssProvider();
+ cssProvider.load_from_data(
+ 'box { padding: 12px; }', -1);
+
+ context.add_provider(cssProvider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+ context.add_class('boxed-list');
+ context.add_class('view');
+
+ const positions = [
+ { pos: 'top-right', label: _('TopRight') },
+ { pos: 'top-center', label: _('TopCenter') },
+ { pos: 'top-left', label: _('TopLeft') },
+ ];
+ let group = null;
+ for (const { pos, label } of positions) {
+ const check = new Gtk.CheckButton({
+ action_name: 'move-notifications.position',
+ action_target: new GLib.Variant('s', pos),
+ label,
+ group,
+ margin_end: 12,
+ });
+ group = check;
+ box.append(check);
+ }
+ }
+});
+
+/**
+ * @returns {Gtk.Widget} - the prefs widget
+ */
+function buildPrefsWidget() {
+ return new MoveNotificationsPrefsWidget();
+}
diff --git a/meson.build b/meson.build
index 7e6ed3e8..0a31d2f6 100644
--- a/meson.build
+++ b/meson.build
@@ -53,6 +53,7 @@ all_extensions += [
'dash-to-dock',
'dash-to-panel',
'gesture-inhibitor',
+ 'move-notifications',
'native-window-placement',
'panel-favorites',
'systemMonitor',
--
2.46.0

View File

@ -1,4 +1,4 @@
From a3db60786407481efbfc4875f887d03b58f0a7b7 Mon Sep 17 00:00:00 2001
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
@ -8,10 +8,10 @@ Subject: [PATCH] Include top-icons in classic session
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index 6764f9a..32743ed 100644
index afc0133..78dee5b 100644
--- a/meson.build
+++ b/meson.build
@@ -36,6 +36,7 @@ classic_extensions = [
@@ -31,6 +31,7 @@ classic_extensions = [
'desktop-icons',
'places-menu',
'launch-new-instance',
@ -19,14 +19,14 @@ index 6764f9a..32743ed 100644
'window-list'
]
@@ -56,7 +57,6 @@ all_extensions += [
'no-hot-corner',
@@ -49,7 +50,6 @@ all_extensions += [
'native-window-placement',
'panel-favorites',
'systemMonitor',
- 'top-icons',
'updates-dialog',
'user-theme',
'window-grouper'
'user-theme'
]
--
2.21.0
2.32.0

View File

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

View File

@ -1,48 +1,19 @@
From e768ad73e2d68b3f1567051675ba0539a75e3105 Mon Sep 17 00:00:00 2001
From 9ca03a744552c43251523fd23292b243130e1f89 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
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 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%);
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 {
@ -50,49 +21,23 @@ index a6357ba..62d9c82 100644
+ 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 {
// 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.21.0
2.28.0

View File

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

View File

@ -1,4 +1,4 @@
From 52ee25effa3debb21307e33ac223cf48ac7bc57a Mon Sep 17 00:00:00 2001
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
@ -6,35 +6,24 @@ 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(-)
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 d62e3d7..cc399c6 100644
index 983a4e7..f8cef41 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 {
@@ -113,7 +113,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.add_child(new St.Label({ text: name }));
+ const label = new St.Label({ text: name });
+ this.add_child(label);
+ this.actor.label_actor = label;
this.actor.connect('motion-event', this._onMotionEvent.bind(this));
this.connect('motion-event', this._onMotionEvent.bind(this));
this.connect('notify::active', this._onActiveChanged.bind(this));
}
--
2.21.0
2.32.0

View File

@ -1,32 +1,66 @@
From 3e3634b59455da0cbae1de4af0ce5cf97be8b80d Mon Sep 17 00:00:00 2001
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 | 8 ++++++++
1 file changed, 8 insertions(+)
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 d7ba570..d62e3d7 100644
index e36b0fe..983a4e7 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -390,6 +390,14 @@ class ApplicationsButton extends PanelMenu.Button {
@@ -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;
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
+ let iconFile = Gio.File.new_for_path(
+ 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'
+ 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.21.0
2.32.0

View File

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

View File

@ -1,4 +1,4 @@
From 3d32ab1848011a3a7af97255307b3541a7553b09 Mon Sep 17 00:00:00 2001
From ffba821e1142c3cb96b9ced24dd1f161f0609d2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 14 Dec 2022 16:55:51 +0100
Subject: [PATCH] classification-banner: Handle fullscreen monitors
@ -11,7 +11,7 @@ screen.
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/extensions/classification-banner/extension.js b/extensions/classification-banner/extension.js
index 6c2fe007..1cf03b3f 100644
index cc046e01..ea788022 100644
--- a/extensions/classification-banner/extension.js
+++ b/extensions/classification-banner/extension.js
@@ -27,16 +27,19 @@ const Main = imports.ui.main;
@ -35,10 +35,10 @@ index 6c2fe007..1cf03b3f 100644
+ global.display.disconnect(this._fullscreenChangedId);
+ delete this._fullscreenChangedId;
+
if (this._settings)
this._settings.run_dispose();
this._settings?.run_dispose();
this._settings = null;
@@ -95,6 +98,11 @@ class ClassificationBanner extends Clutter.Actor {
});
@@ -94,6 +97,11 @@ class ClassificationBanner extends Clutter.Actor {
userLabel, 'visible',
Gio.SettingsBindFlags.GET);
@ -50,7 +50,7 @@ index 6c2fe007..1cf03b3f 100644
this._settings.connect('changed::color',
() => this._updateStyles());
this._settings.connect('changed::background-color',
@@ -111,6 +119,12 @@ class ClassificationBanner extends Clutter.Actor {
@@ -110,6 +118,12 @@ class ClassificationBanner extends Clutter.Actor {
return `${key}: rgba(${red},${green},${blue},${alpha / 255});`;
}

View File

@ -0,0 +1,48 @@
From 7ed5e50cc978b7fda34aaaf56e8bf4d499f4676d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 2 Dec 2024 17:34:58 +0100
Subject: [PATCH] dash-to-panel: Remove faulty version check
In a string comparison, '40.10' is *smaller* than '40.3', so the
overview ends up being monkey-patched for an older version.
Unbreak the app grid by removing the check altogether, as we don't
have to care about older versions.
---
extensions/dash-to-panel/overview.js | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/extensions/dash-to-panel/overview.js b/extensions/dash-to-panel/overview.js
index 57600a5c..38f04c75 100644
--- a/extensions/dash-to-panel/overview.js
+++ b/extensions/dash-to-panel/overview.js
@@ -581,18 +581,14 @@ var dtpOverview = Utils.defineClass({
const workspaceAppGridBox =
this._cachedWorkspaceBoxes.get(OverviewControls.ControlsState.APP_GRID);
- if (Config.PACKAGE_VERSION > '40.3') {
- const monitor = Main.layoutManager.findMonitorForActor(this._container);
- const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
- const workAreaBox = new Clutter.ActorBox();
-
- workAreaBox.set_origin(startX, startY);
- workAreaBox.set_size(workArea.width, workArea.height);
-
- params = [workAreaBox, searchHeight, dashHeight, workspaceAppGridBox]
- } else {
- params = [box, startX, searchHeight, dashHeight, workspaceAppGridBox];
- }
+ const monitor = Main.layoutManager.findMonitorForActor(this._container);
+ const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
+ const workAreaBox = new Clutter.ActorBox();
+
+ workAreaBox.set_origin(startX, startY);
+ workAreaBox.set_size(workArea.width, workArea.height);
+
+ params = [workAreaBox, searchHeight, dashHeight, workspaceAppGridBox]
let appDisplayBox;
if (!transitionParams.transitioning) {
--
2.47.1

View File

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

View File

@ -0,0 +1,33 @@
From 8bea7c892c24694efda753ad1d76ab470032c6fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 15 Dec 2022 17:09:45 +0100
Subject: [PATCH] desktop-icons: Don't grab focus on click
We will move keyboard focus away immediately, either when opening
the context menu or when starting the rubberband.
In theory the grab is still useful, because it will move keyboard
focus to the grid when restoring focus after ending the rubberband
or closing the menu, however as keyboard navigation support is
lacking, all it does is preventing the focus to return to the
focus window after the operation.
---
extensions/desktop-icons/desktopGrid.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js
index 002803c7..9a89d5a3 100644
--- a/extensions/desktop-icons/desktopGrid.js
+++ b/extensions/desktop-icons/desktopGrid.js
@@ -559,8 +559,6 @@ var DesktopGrid = GObject.registerClass({
let button = event.get_button();
let [x, y] = event.get_coords();
- this._grid.grab_key_focus();
-
if (button == 1) {
let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
--
2.38.1

View File

@ -1,4 +1,4 @@
From 0f13a5e00d9115b4d1518c91aa45c88f3e7e7c27 Mon Sep 17 00:00:00 2001
From b48dae39341a3ba24eb3d142f99eb37d6b14ab41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 2 Nov 2023 20:51:45 +0100
Subject: [PATCH] desktop-icons: Don't try spawn with non-existent workdir
@ -15,10 +15,10 @@ to work.
1 file changed, 3 insertions(+)
diff --git a/extensions/desktop-icons/desktopIconsUtil.js b/extensions/desktop-icons/desktopIconsUtil.js
index 0aea6542..c1a0dda3 100644
index 57bedc13..c3fe5977 100644
--- a/extensions/desktop-icons/desktopIconsUtil.js
+++ b/extensions/desktop-icons/desktopIconsUtil.js
@@ -49,6 +49,9 @@ function launchTerminal(workdir) {
@@ -50,6 +50,9 @@ function launchTerminal(workdir) {
* https://gitlab.gnome.org/GNOME/gnome-shell/blob/gnome-3-30/js/misc/util.js
*/

View File

@ -1,17 +1,17 @@
From 93e3e938b322433aff862bbc46f80c60ab7dc2ab Mon Sep 17 00:00:00 2001
From 2a1dd773a529c89b5f9577b53ae3c88aea2efc48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 17 Jan 2023 20:31:21 +0100
Subject: [PATCH] desktop-icons: Don't use blocking IO
---
extensions/desktop-icons/desktopManager.js | 35 +++++++++++++++++-----
1 file changed, 28 insertions(+), 7 deletions(-)
extensions/desktop-icons/desktopManager.js | 45 +++++++++++++++-------
1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index 399aee03..2ce6eefb 100644
index 74d0e6bd..75b2a22a 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -53,6 +53,21 @@ function findMonitorIndexForPos(x, y) {
@@ -54,6 +54,21 @@ function findMonitorIndexForPos(x, y) {
return getDpy().get_monitor_index_for_rect(new Meta.Rectangle({x, y}));
}
@ -33,7 +33,7 @@ index 399aee03..2ce6eefb 100644
var DesktopManager = GObject.registerClass({
Properties: {
@@ -221,9 +236,7 @@ var DesktopManager = GObject.registerClass({
@@ -272,9 +287,7 @@ var DesktopManager = GObject.registerClass({
if (!this._unixMode) {
let desktopDir = DesktopIconsUtil.getDesktopDir();
@ -44,7 +44,16 @@ index 399aee03..2ce6eefb 100644
this._unixMode = fileInfo.get_attribute_uint32(Gio.FILE_ATTRIBUTE_UNIX_MODE);
this._setWritableByOthers((this._unixMode & S_IWOTH) != 0);
}
@@ -268,14 +281,22 @@ var DesktopManager = GObject.registerClass({
@@ -283,7 +296,7 @@ var DesktopManager = GObject.registerClass({
let items = [];
for (let item of await this._enumerateDesktop())
items.push(item);
- for (let item of this._getMounts())
+ for (let item of await this._getMounts())
items.push(item);
let tmpFileItems = new Map();
@@ -328,14 +341,22 @@ var DesktopManager = GObject.registerClass({
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT,
this._desktopEnumerateCancellable,
@ -71,6 +80,29 @@ index 399aee03..2ce6eefb 100644
while ((info = fileEnum.next_file(null)))
yield [fileEnum.get_child(info), info, Prefs.FileType.NONE];
}.bind(this);
@@ -359,19 +380,17 @@ var DesktopManager = GObject.registerClass({
this._monitorDesktopDir.connect('changed', (obj, file, otherFile, eventType) => this._updateDesktopIfChanged(file, otherFile, eventType));
}
- _getMounts() {
+ async _getMounts() {
let files = [];
if (!Prefs.settings.get_boolean('show-mount'))
return files;
- this._mountMonitor.get_mounts().forEach( mount => {
+ this._mountMonitor.get_mounts().forEach(async mount => {
if (this._isNetworkMount(mount))
return;
let file = mount.get_root();
- let info = file.query_info(DesktopIconsUtil.DEFAULT_ATTRIBUTES,
- Gio.FileQueryInfoFlags.NONE,
- null);
+ let info = await queryInfo(file);
files.push([file, info, Prefs.FileType.MOUNT_DISK]);
});
--
2.38.1

View File

@ -1,42 +0,0 @@
From f65b9f2df5bf913f8c152ea770795d2cdcb14c6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 7 Jan 2025 19:09:01 +0100
Subject: [PATCH] desktop-icons: Fix '%k' in .desktop files
In order to support Link-type .desktop files, we load the file
ourselves, and then create the AppInfo from the loaded keyfile
to avoid reading the file twice.
Unfortunately that means that the AppInfo loses the filename
information, which is necessary to substitute the '%k' macro.
In order to support both the macro and Link-type .desktop files,
we have to take the hit and let GIO read the file again.
---
extensions/desktop-icons/fileItem.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 1c9a1e55..c765967b 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -241,13 +241,14 @@ var FileItem = class {
if (this._isDesktopFile) {
try {
const keyFile = new GLib.KeyFile();
- keyFile.load_from_file(this._file.get_path(), GLib.KeyFileFlags.NONE);
+ const path = this._file.get_path();
+ keyFile.load_from_file(path, GLib.KeyFileFlags.NONE);
const type = keyFile.get_string(
GLib.KEY_FILE_DESKTOP_GROUP, GLib.KEY_FILE_DESKTOP_KEY_TYPE);
switch (type) {
case GLib.KEY_FILE_DESKTOP_TYPE_APPLICATION:
- this._desktopFile = Gio.DesktopAppInfo.new_from_keyfile(keyFile);
+ this._desktopFile = Gio.DesktopAppInfo.new_from_filename(path);
if (!this._desktopFile) {
log(`Couldnt parse ${this._displayName} as a desktop file, will treat it as a regular file.`);
this._isValidDesktopFile = false;
--
2.47.1

View File

@ -1,4 +1,4 @@
From b334c8c248f849be996963cdafb1b0b69476bdf1 Mon Sep 17 00:00:00 2001
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
@ -23,38 +23,38 @@ 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(-)
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 602fa7f..bd27e2a 100644
index 002803c..c7846bf 100644
--- a/extensions/desktop-icons/desktopGrid.js
+++ b/extensions/desktop-icons/desktopGrid.js
@@ -365,6 +365,7 @@ var DesktopGrid = class {
@@ -388,6 +388,7 @@ var DesktopGrid = GObject.registerClass({
}
_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
this._submenu.menu.removeAll();
let templates = Extension.templateManager.getTemplates();
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index a70cd98..c37e1e7 100644
index 10e3ce0..08bc82b 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -79,6 +79,7 @@ var DesktopManager = GObject.registerClass({
this._queryFileInfoCancellable = null;
@@ -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' });
@@ -86,6 +87,20 @@ var DesktopManager = GObject.registerClass({
Main.layoutManager._backgroundGroup.add_child(this._rubberBand);
this._grabHelper = new GrabHelper.GrabHelper(global.stage);
@@ -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) => {
@ -73,8 +73,8 @@ index a70cd98..c37e1e7 100644
this._addDesktopIcons();
this._monitorDesktopFolder();
@@ -108,30 +123,15 @@ var DesktopManager = GObject.registerClass({
this._initRubberBandColor();
@@ -133,57 +148,67 @@ var DesktopManager = GObject.registerClass({
this._rubberBandInitialY = y;
this._updateRubberBand(x, y);
this._rubberBand.show();
- this._grabHelper.grab({ actor: global.stage });
@ -87,7 +87,7 @@ index a70cd98..c37e1e7 100644
this._stageReleaseEventId = global.stage.connect('button-release-event', (actor, event) => {
this.endRubberBand();
});
- this._rubberBandId = global.stage.connect('motion-event', (actor, event) => {
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.
@ -104,13 +104,26 @@ index a70cd98..c37e1e7 100644
- }
- [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({
}
- 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() {
@ -131,7 +144,25 @@ index a70cd98..c37e1e7 100644
+ }
+ let [x, y] = event.get_coords();
+ this._updateRubberBand(x, y);
+ this._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(ungrab=true) {
@ -145,13 +176,12 @@ index a70cd98..c37e1e7 100644
- 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({
this._selection = new Set([...this._selection, ...this._currentSelection]);
@@ -825,10 +850,6 @@ var DesktopManager = GObject.registerClass({
global.stage.disconnect(this._stageReleaseEventId);
this._stageReleaseEventId = 0;
@ -159,20 +189,20 @@ index a70cd98..c37e1e7 100644
- 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)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 1cb47e8..90f326d 100644
index 1e8ea89..37ee54d 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -676,6 +676,7 @@ var FileItem = class {
@@ -747,6 +747,7 @@ var FileItem = GObject.registerClass({
}
_onPressButton(actor, event) {
+ Extension.desktopManager.endRubberBand();
this._updateClickState(event);
let button = this._eventButton(event);
let button = event.get_button();
if (button == 3) {
--
2.31.1

View File

@ -0,0 +1,242 @@
From a796215ddce14ebe80774b99e29d0d28109c818b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 6 Mar 2024 20:14:14 +0100
Subject: [PATCH] desktop-icons: Handle touch events
File icons currently only deal with button events. Split up the
current handlers and use them to handle touch events as well.
---
extensions/desktop-icons/fileItem.js | 181 +++++++++++++++++++--------
1 file changed, 128 insertions(+), 53 deletions(-)
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
index 37ee54db..26afddb2 100644
--- a/extensions/desktop-icons/fileItem.js
+++ b/extensions/desktop-icons/fileItem.js
@@ -140,6 +140,7 @@ var FileItem = GObject.registerClass({
this._container.connect('leave-event', (actor, event) => this._onLeave(actor, event));
this._container.connect('enter-event', (actor, event) => this._onEnter(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);
@@ -229,6 +230,10 @@ var FileItem = GObject.registerClass({
if (this._iconAllocationIdleId)
GLib.source_remove(this._iconAllocationIdleId);
+ if (this._longPressTimeoutId)
+ GLib.source_remove(this._longPressTimeoutId);
+ delete this._longPressTimeoutId;
+
/* Menu */
this._removeMenu();
}
@@ -731,58 +736,141 @@ var FileItem = GObject.registerClass({
}
_updateClickState(event) {
+ const eventType = event.type();
+ const isButton =
+ eventType === Clutter.EventType.BUTTON_PRESS ||
+ eventType === Clutter.EventType.BUTTON_RELEASE;
+ const button = isButton ? event.get_button() : 0;
+ const time = event.get_time();
+
let settings = Clutter.Settings.get_default();
- if ((event.get_button() == this._lastClickButton) &&
- ((event.get_time() - this._lastClickTime) < settings.double_click_time))
+ if (button === this._lastClickButton &&
+ (time - this._lastClickTime) < settings.double_click_time)
this._clickCount++;
else
this._clickCount = 1;
- this._lastClickTime = event.get_time();
- this._lastClickButton = event.get_button();
+ this._lastClickTime = time;
+ this._lastClickButton = button;
}
_getClickCount() {
return this._clickCount;
}
+ _handlePressEvent(event) {
+ const pressSequence = event.get_event_sequence();
+ if (this._pressSequence &&
+ pressSequence?.get_slot() !== this._pressSequence.get_slot())
+ return Clutter.EVENT_PROPAGATE;
+
+ this._primaryButtonPressed = true;
+ this._pressSequence = pressSequence;
+ this._pressDevice = event.get_device();
+
+ if (this._getClickCount() !== 1)
+ return Clutter.EVENT_STOP;
+
+ const [x, y] = event.get_coords();
+ this._buttonPressInitialX = x;
+ this._buttonPressInitialY = y;
+
+ const shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
+ const controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
+ if (controlPressed || shiftPressed)
+ this.emit('selected', true, false, !this._isSelected);
+ else if (!this._isSelected)
+ this.emit('selected', false, false, true);
+
+ return Clutter.EVENT_STOP;
+ }
+
+ _handleSecondaryPress() {
+ if (!this.isSelected)
+ this.emit('selected', false, false, true);
+ this._ensureMenu().toggle();
+ if (this._actionOpenWith) {
+ let allowOpenWith = Extension.desktopManager.getNumberOfSelectedItems() === 1;
+ this._actionOpenWith.setSensitive(allowOpenWith);
+ }
+ const specialFilesSelected =
+ Extension.desktopManager.checkIfSpecialFilesAreSelected();
+ if (this._actionCut)
+ this._actionCut.setSensitive(!specialFilesSelected);
+ if (this._actionCopy)
+ this._actionCopy.setSensitive(!specialFilesSelected);
+ if (this._actionTrash)
+ this._actionTrash.setSensitive(!specialFilesSelected);
+ return Clutter.EVENT_STOP;
+ }
+
+ _handleReleaseEvent(event) {
+ if (this._longPressTimeoutId)
+ GLib.source_remove(this._longPressTimeoutId);
+ delete this._longPressTimeoutId;
+
+ if (!this._primaryButtonPressed || this._pressDevice !== event.get_device())
+ return Clutter.EVENT_PROPAGATE;
+
+ const pressSequence = event.get_event_sequence();
+ if (this._pressSequence &&
+ pressSequence?.get_slot() !== this._pressSequence.get_slot())
+ return Clutter.EVENT_PROPAGATE;
+
+ // 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
+ this._primaryButtonPressed = false;
+ delete this._pressDevice;
+ delete this._pressSequence;
+
+ let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
+ let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
+ if (!controlPressed && !shiftPressed)
+ this.emit('selected', false, false, true);
+ if (this._getClickCount() === 1 && Prefs.CLICK_POLICY_SINGLE && !shiftPressed && !controlPressed)
+ this.doOpen();
+ if (this._getClickCount() === 2 && !Prefs.CLICK_POLICY_SINGLE)
+ this.doOpen();
+ return Clutter.EVENT_STOP;
+ }
+
+ _onTouchEvent(actor, event) {
+ // on X11, let pointer emulation deal with touch
+ if (!Meta.is_wayland_compositor())
+ return Clutter.EVENT_PROPAGATE;
+
+ const type = event.type();
+ if (type === Clutter.EventType.TOUCH_BEGIN) {
+ Extension.desktopManager.endRubberBand();
+ this._updateClickState(event);
+
+ if (!this._handlePressEvent(event))
+ return Clutter.EVENT_PROPAGATE;
+
+ const { longPressDuration } = Clutter.Settings.get_default();
+ this._longPressTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
+ longPressDuration,
+ () => {
+ this._handleSecondaryPress();
+ delete this._longPressTimeoutId;
+ return GLib.SOURCE_REMOVE;
+ });
+
+ return Clutter.EVENT_STOP;
+ } else if (type === Clutter.EventType.TOUCH_END) {
+ return this._handleReleaseEvent(event);
+ }
+ return Clutter.EVENT_PROPAGATE;
+ }
+
_onPressButton(actor, event) {
Extension.desktopManager.endRubberBand();
this._updateClickState(event);
let button = event.get_button();
- if (button == 3) {
- if (!this.isSelected)
- this.emit('selected', false, false, true);
- this._ensureMenu().toggle();
- if (this._actionOpenWith) {
- let allowOpenWith = (Extension.desktopManager.getNumberOfSelectedItems() == 1);
- this._actionOpenWith.setSensitive(allowOpenWith);
- }
- let specialFilesSelected = Extension.desktopManager.checkIfSpecialFilesAreSelected();
- if (this._actionCut)
- this._actionCut.setSensitive(!specialFilesSelected);
- if (this._actionCopy)
- this._actionCopy.setSensitive(!specialFilesSelected);
- if (this._actionTrash)
- this._actionTrash.setSensitive(!specialFilesSelected);
- return Clutter.EVENT_STOP;
- } else if (button == 1) {
- if (this._getClickCount() == 1) {
- let [x, y] = event.get_coords();
- this._primaryButtonPressed = true;
- this._buttonPressInitialX = x;
- this._buttonPressInitialY = y;
- let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
- let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
- if (controlPressed || shiftPressed) {
- this.emit('selected', true, false, !this._isSelected);
- } else {
- if (!this._isSelected)
- this.emit('selected', false, false, true);
- }
- }
- return Clutter.EVENT_STOP;
- }
+ if (button == 3)
+ return this._handleSecondaryPress();
+ if (button == 1)
+ return this._handlePressEvent(event);
return Clutter.EVENT_PROPAGATE;
}
@@ -821,22 +909,9 @@ var FileItem = GObject.registerClass({
_onReleaseButton(actor, event) {
let button = event.get_button();
- 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
- if (this._primaryButtonPressed) {
- this._primaryButtonPressed = false;
- let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
- let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
- if (!controlPressed && !shiftPressed)
- this.emit('selected', false, false, true);
- if ((this._getClickCount() == 1) && Prefs.CLICK_POLICY_SINGLE && !shiftPressed && !controlPressed)
- this.doOpen();
- return Clutter.EVENT_STOP;
- }
- if ((this._getClickCount() == 2) && (!Prefs.CLICK_POLICY_SINGLE))
- this.doOpen();
- }
+ if (button == 1)
+ return this._handleReleaseEvent(event);
+
return Clutter.EVENT_PROPAGATE;
}
--
2.44.0

View File

@ -0,0 +1,40 @@
From 8389801814c84c797a29f986f15e7ea4dd27bccc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 6 Mar 2024 13:48:49 +0100
Subject: [PATCH] desktop-icons: Notify icon drags
Components like the message tray will use the signal to hide
their layout actor from picks, so that it does no interfere
with the DND operation.
---
extensions/desktop-icons/desktopManager.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index 75b2a22a..c3b3f7e4 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -547,17 +547,20 @@ var DesktopManager = GObject.registerClass({
this._draggableContainer.allocate_preferred_size(0, 0);
this._draggable.startDrag(x, y, global.get_current_time(), event.get_event_sequence());
+ Main.overview.beginItemDrag(this._draggableContainer);
}
_onDragCancelled() {
let event = Clutter.get_current_event();
let [x, y] = event.get_coords();
this._dragCancelled = true;
+ Main.overview.cancelledItemDrag(this._draggableContainer);
}
_onDragEnd() {
this._inDrag = false;
Main.layoutManager.uiGroup.remove_child(this._draggableContainer);
+ Main.overview.endItemDrag(this._draggableContainer);
}
_dragActorDropped(event) {
--
2.44.0

View File

@ -1,21 +1,19 @@
From 0a7248c75c084a83852aa3d0e7a36ccebd365b81 Mon Sep 17 00:00:00 2001
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 | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
po/ja.po | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/po/ja.po b/po/ja.po
index df5646d..4d780b9 100644
index 8eb7725..ddf1eb7 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -293,13 +293,8 @@ msgid "Workspace %d"
msgstr "ワークスペース %d"
#: desktopGrid.js:334
-#, fuzzy
@@ -897,11 +897,7 @@ msgstr "押し込み量 (ピクセル)"
#: desktopGrid.js:359
#, fuzzy
msgid "Display Settings"
-msgstr ""
-"#-#-#-#-# ja.po (gnome-shell-extensions master) #-#-#-#-#\n"
@ -27,5 +25,5 @@ index df5646d..4d780b9 100644
#: schemas/org.gnome.shell.extensions.desktop-icons.gschema.xml:11
#, fuzzy
--
2.29.2
2.32.0

View File

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

View File

@ -0,0 +1,60 @@
From 62289dff5cb2e615a277b72f034fa42f45aad639 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 15 Dec 2022 15:14:08 +0100
Subject: [PATCH] desktopManager: Hook into LayoutManager to create grids
Right now we track the `monitors-changed` signal to recreate the
per-monitor grids. Usually that's enough, but if something else
causes backgrounds to update, we'll end up without desktop icons
until some other change (settings, mounts, monitor/resolution
changes, ...) results in a reload of the grid.
To address this, hook into LayoutManager to always create the grid
when backgrounds are updated.
---
extensions/desktop-icons/desktopManager.js | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js
index 08bc82b7..74d0e6bd 100644
--- a/extensions/desktop-icons/desktopManager.js
+++ b/extensions/desktop-icons/desktopManager.js
@@ -83,7 +83,6 @@ var DesktopManager = GObject.registerClass({
this._discreteGpuAvailable = false;
this._rubberBandActive = false;
- this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', () => this._recreateDesktopIcons());
this._rubberBand = new St.Widget({ style_class: 'rubber-band' });
this._rubberBand.hide();
Main.layoutManager._backgroundGroup.add_child(this._rubberBand);
@@ -109,6 +108,13 @@ var DesktopManager = GObject.registerClass({
return origCapturedEvent.bind(this._grabHelper)(event);
};
+ this._origUpdateBackgrounds =
+ Main.layoutManager._updateBackgrounds;
+ Main.layoutManager._updateBackgrounds = () => {
+ this._origUpdateBackgrounds.call(Main.layoutManager);
+ this._recreateDesktopIcons();
+ };
+
this._addDesktopIcons();
this._monitorDesktopFolder();
@@ -843,9 +849,10 @@ var DesktopManager = GObject.registerClass({
GLib.source_remove(this._deleteChildrenId);
this._deleteChildrenId = 0;
- if (this._monitorsChangedId)
- Main.layoutManager.disconnect(this._monitorsChangedId);
- this._monitorsChangedId = 0;
+ if (this._origUpdateBackgrounds)
+ Main.layoutManager._updateBackgrounds = this._origUpdateBackgrounds;
+ delete this._origUpdateBackgrounds;
+
if (this._stageReleaseEventId)
global.stage.disconnect(this._stageReleaseEventId);
this._stageReleaseEventId = 0;
--
2.38.1

View File

@ -0,0 +1,29 @@
From 3edf3c0be7638bf9161c0d192dd3c2de1e3b9845 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 14 Dec 2023 14:41:04 +0100
Subject: [PATCH] docking: Only remove spacer if necessary
There may not be a main dock at the time when restoring the dash.
Handle that case by not removing a non-existent spacer, instead of
triggering an error.
---
extensions/dash-to-dock/docking.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/dash-to-dock/docking.js b/extensions/dash-to-dock/docking.js
index daa9de59..14e2ced6 100644
--- a/extensions/dash-to-dock/docking.js
+++ b/extensions/dash-to-dock/docking.js
@@ -1796,7 +1796,7 @@ var DockManager = class DashToDock_DockManager {
let overviewControls = Main.overview._overview._controls;
Main.overview._overview._controls.layout_manager._dash = this._oldDash;
- if (this.mainDock._dashSpacer) {
+ if (this.mainDock?._dashSpacer) {
Main.overview._overview._controls.remove_child(this.mainDock._dashSpacer);
}
--
2.43.0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,19 +1,19 @@
From 8da1760af68496c6073be4d6b3c8266b64347925 Mon Sep 17 00:00:00 2001
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 | 320 ++++++++++++++++++
extensions/heads-up-display/headsUpMessage.js | 150 ++++++++
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 | 175 ++++++++++
extensions/heads-up-display/prefs.js | 194 ++++++++
extensions/heads-up-display/stylesheet.css | 32 ++
meson.build | 1 +
8 files changed, 751 insertions(+)
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
@ -24,13 +24,12 @@ Subject: [PATCH] heads-up-display: Add extension for showing persistent heads
diff --git a/extensions/heads-up-display/extension.js b/extensions/heads-up-display/extension.js
new file mode 100644
index 00000000..e4ef9e85
index 00000000..7cebfa99
--- /dev/null
+++ b/extensions/heads-up-display/extension.js
@@ -0,0 +1,320 @@
@@ -0,0 +1,436 @@
+/* exported init enable disable */
+
+
+const Signals = imports.signals;
+
+const {
@ -41,10 +40,59 @@ index 00000000..e4ef9e85
+const Me = ExtensionUtils.getCurrentExtension();
+
+const Main = imports.ui.main;
+const Layout = imports.ui.layout;
+const HeadsUpMessage = Me.imports.headsUpMessage;
+
+const Gettext = imports.gettext.domain('gnome-shell-extensions');
+const _ = Gettext.gettext;
+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() {
@ -53,7 +101,6 @@ index 00000000..e4ef9e85
+
+ 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();
@ -71,10 +118,7 @@ index 00000000..e4ef9e85
+ disable() {
+ this._dismissMessage();
+
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+ this._stopWatchingForIdle();
+
+ if (this._sessionModeUpdatedId) {
+ Main.sessionMode.disconnect(this._sessionModeUpdatedId);
@ -91,6 +135,11 @@ index 00000000..e4ef9e85
+ 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;
@ -118,8 +167,8 @@ index 00000000..e4ef9e85
+ }
+
+ _onWindowMap(shellwm, actor) {
+ let windowObject = actor.meta_window;
+ let windowType = windowObject.get_window_type();
+ const windowObject = actor.meta_window;
+ const windowType = windowObject.get_window_type();
+
+ if (windowType != Meta.WindowType.NORMAL)
+ return;
@ -127,8 +176,8 @@ index 00000000..e4ef9e85
+ 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();
+ 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);
@ -147,17 +196,50 @@ index 00000000..e4ef9e85
+ _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();
+ }
+
+ _onIdleTimeoutChanged() {
+ _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)
@ -165,10 +247,7 @@ index 00000000..e4ef9e85
+ return;
+ }
+
+ if (this._idleWatchId) {
+ this._idleMonitor.remove_watch(this._idleWatchId);
+ this._idleWatchId = 0;
+ }
+ this._stopWatchingForIdle();
+
+ if (Main.sessionMode.hasOverview && Main.overview.visible) {
+ this._dismissMessage();
@ -185,12 +264,10 @@ index 00000000..e4ef9e85
+ if (this._settings.get_boolean('show-when-unlocked'))
+ supportedModes.push('user');
+
+ if (this._settings.get_boolean('show-when-unlocking'))
+ 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-when-locked'))
+ supportedModes.push('lock-screen');
+
+ if (this._settings.get_boolean('show-on-login-screen'))
+ supportedModes.push('gdm');
+
@ -200,8 +277,25 @@ index 00000000..e4ef9e85
+ return;
+ }
+
+ let heading = this._settings.get_string('message-heading');
+ let body = this._settings.get_string('message-body');
+ 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();
@ -231,22 +325,11 @@ index 00000000..e4ef9e85
+ 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._watchForIdle();
+ this._messageInhibitedUntilIdle = true;
+ this._updateMessage();
+ }
+
+ _onUserIdle() {
+ this._messageInhibitedUntilIdle = false;
+ this._updateMessage();
+ }
+
+ _dismissMessage() {
+ if (!this._message) {
+ return;
@ -263,7 +346,15 @@ index 00000000..e4ef9e85
+ if (!Main.messageTray)
+ return;
+
+ Main.messageTray.actor.set_translation(0, 0, 0);
+ if (this._updateMessageTrayId) {
+ global.stage.disconnect(this._updateMessageTrayId);
+ this._updateMessageTrayId = 0;
+ }
+
+ if (this._messageTrayConstraint) {
+ Main.messageTray.remove_constraint(this._messageTrayConstraint);
+ this._messageTrayConstraint = null;
+ }
+ }
+
+ _alignMessageTray() {
@ -275,10 +366,27 @@ index 00000000..e4ef9e85
+ return;
+ }
+
+ let panelBottom = Main.layoutManager.panelBox.y + Main.layoutManager.panelBox.height;
+ let messageBottom = this._message.y + this._message.height;
+ if (this._updateMessageTrayId)
+ return;
+
+ Main.messageTray.actor.set_translation(0, messageBottom - panelBottom, 0);
+ 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() {
@ -288,15 +396,22 @@ index 00000000..e4ef9e85
+ if (!Main.screenShield || !Main.screenShield._dialog)
+ return;
+
+ let dialog = Main.screenShield._dialog;
+ const dialog = Main.screenShield._dialog;
+
+ if (this._authPromptAllocatedId) {
+ dialog.disconnect(this._authPromptAllocatedId);
+ this._authPromptAllocatedId = 0;
+ }
+
+ dialog.style = null;
+ dialog._bannerView.style = null;
+ if (this._updateLoginDialogId) {
+ global.stage.disconnect(this._updateLoginDialogId);
+ this._updateLoginDialogId = 0;
+ }
+
+ if (this._loginDialogConstraint) {
+ dialog.remove_constraint(this._loginDialogConstraint);
+ this._loginDialogConstraint = null;
+ }
+ }
+
+ _adaptLoginDialogForMessage() {
@ -311,25 +426,26 @@ index 00000000..e4ef9e85
+ return;
+ }
+
+ let dialog = Main.screenShield._dialog;
+ 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 (dialog._logoBin.visible)
+ messageHeight -= dialog._logoBin.height;
+
+ if (messageHeight <= 0) {
+ dialog.style = null;
+ dialog._bannerView.style = null;
+ } else {
+ dialog.style = `margin-top: ${messageHeight}px;`;
+ if (!this._logindDialogConstraint) {
+ this._loginDialogConstraint = new HeadsUpConstraint({ primary: true });
+ dialog.add_constraint(this._loginDialogConstraint);
+ }
+
+ let bannerOnSide = dialog._bannerView.x + dialog._bannerView.width < dialog._authPrompt.actor.x;
+ this._loginDialogConstraint.offset = messageHeight;
+
+ if (bannerOnSide)
+ dialog._bannerView.style = `margin-bottom: ${messageHeight}px;`;
+ else
+ dialog._bannerView.style = `margin-top: ${messageHeight}px`;
+ }
+ global.stage.disconnect(this._updateLoginDialogId);
+ this._updateLoginDialogId = 0;
+ });
+ }
+
+ _adaptSessionForMessage() {
@ -338,8 +454,8 @@ index 00000000..e4ef9e85
+ 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));
+ const dialog = Main.screenShield._dialog;
+ this._authPromptAllocatedId = dialog._authPrompt.connect('notify::allocation', this._adaptLoginDialogForMessage.bind(this));
+ }
+ }
+ }
@ -350,11 +466,11 @@ index 00000000..e4ef9e85
+}
diff --git a/extensions/heads-up-display/headsUpMessage.js b/extensions/heads-up-display/headsUpMessage.js
new file mode 100644
index 00000000..d828d8c9
index 00000000..87a8c8ba
--- /dev/null
+++ b/extensions/heads-up-display/headsUpMessage.js
@@ -0,0 +1,150 @@
+const { Atk, Clutter, GObject, Pango, St } = imports.gi;
@@ -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;
@ -364,48 +480,64 @@ index 00000000..d828d8c9
+ _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) {
+ let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+ const maxWidth = this._widthCoverage * this._workArea.width
+
+ let [labelMinimumWidth, labelNaturalWidth] = super.vfunc_get_preferred_width(forHeight);
+
+ labelMinimumWidth = Math.min(labelMinimumWidth, .75 * workArea.width);
+ labelNaturalWidth = Math.min(labelNaturalWidth, .75 * workArea.width);
+ labelMinimumWidth = Math.min(labelMinimumWidth, maxWidth);
+ labelNaturalWidth = Math.min(labelNaturalWidth, maxWidth);
+
+ return [labelMinimumWidth, labelNaturalWidth];
+ }
+
+ vfunc_get_preferred_height(forWidth) {
+ let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+ let labelHeightUpperBound = .25 * workArea.height;
+ const labelHeightUpperBound = this._heightCoverage * this._workArea.height;
+ const numberOfLines = Math.floor(labelHeightUpperBound / this._lineHeight);
+ this._numberOfLines = Math.max(numberOfLines, 1);
+
+ 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);
+ const maxHeight = this._lineHeight * this._numberOfLines;
+
+ 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);
+ labelMinimumHeight = Math.min(labelMinimumHeight, maxHeight);
+ labelNaturalHeight = Math.min(labelNaturalHeight, maxHeight);
+
+ return [labelMinimumHeight, labelNaturalHeight];
+ }
+
+ vfunc_allocate(box, flags) {
+ if (!this.visible)
+ return;
+ destroy() {
+ if (this._workAreasChangedId) {
+ global.display.disconnect(this._workAreasChangedId);
+ this._workAreasChangedId = 0;
+ }
+
+ super.vfunc_allocate(box, flags);
+ super.destroy();
+ }
+});
+
@ -416,30 +548,19 @@ index 00000000..d828d8c9
+ 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));
+ 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 });
+ 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',
@ -455,24 +576,34 @@ index 00000000..d828d8c9
+ contentsBox.add_actor(this.bodyLabel);
+
+ this.setBody(body);
+ this.bodyLabel.clutter_text.label = this.bodyLabel;
+ }
+
+ vfunc_parent_set(oldParent) {
+ this._alignWithPanel();
+ }
+
+ _alignWithPanel() {
+ if (!this.visible)
+ if (this._afterUpdateId)
+ 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();
+ 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) {
+ let heading = text ? text.replace(/\n/g, ' ') : '';
+ const heading = text ? text.replace(/\n/g, ' ') : '';
+ this.headingLabel.text = heading;
+ this.headingLabel.visible = true;
+ } else {
@ -496,9 +627,14 @@ index 00000000..d828d8c9
+ this._panelAllocationId = 0;
+ }
+
+ if (this._messageTraySnappingId) {
+ Main.messageTray.disconnect(this._messageTraySnappingId);
+ this._messageTraySnappingId = 0;
+ if (this._afterUpdateId) {
+ global.stage.disconnect(this._afterUpdateId);
+ this._afterUpdateId = 0;
+ }
+
+ if (this.bodyLabel) {
+ this.bodyLabel.destroy();
+ this.bodyLabel = null;
+ }
+
+ super.destroy();
@ -597,10 +733,10 @@ index 00000000..ea1f3774
+</schemalist>
diff --git a/extensions/heads-up-display/prefs.js b/extensions/heads-up-display/prefs.js
new file mode 100644
index 00000000..b4b6f94c
index 00000000..a7106e07
--- /dev/null
+++ b/extensions/heads-up-display/prefs.js
@@ -0,0 +1,175 @@
@@ -0,0 +1,194 @@
+
+/* Desktop Icons GNOME Shell extension
+ *
@ -644,6 +780,10 @@ index 00000000..b4b6f94c
+ padding-bottom: 8px;
+ }
+
+ .contents {
+ padding: 20px;
+ }
+
+ .message-label {
+ font-weight: bold;
+ }
@ -653,74 +793,82 @@ index 00000000..b4b6f94c
+
+function init() {
+ settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.heads-up-display");
+ let cssProvider = new Gtk.CssProvider();
+ const 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);
+ const display = Gdk.Display.get_default();
+ Gtk.StyleContext.add_provider_for_display(display, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function buildPrefsWidget() {
+ ExtensionUtils.initTranslations();
+
+ let contents = new Gtk.Box({
+ const contents = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ border_width: 20,
+ spacing: 10,
+ visible: true,
+ });
+
+ 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")));
+ 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");
+
+ let outerMessageBox = new Gtk.Box({
+ const outerMessageBox = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ border_width: 0,
+ spacing: 5,
+ visible: true,
+ });
+ contents.add(outerMessageBox);
+ contents.append(outerMessageBox);
+
+ let messageLabel = new Gtk.Label({
+ const messageLabel = new Gtk.Label({
+ label: 'Message',
+ halign: Gtk.Align.START,
+ visible: true,
+ });
+ messageLabel.get_style_context().add_class("message-label");
+ outerMessageBox.add(messageLabel);
+ outerMessageBox.append(messageLabel);
+
+ let innerMessageBox = new Gtk.Box({
+ const innerMessageBox = new Gtk.Box({
+ orientation: Gtk.Orientation.VERTICAL,
+ border_width: 0,
+ spacing: 0,
+ visible: true,
+ });
+ innerMessageBox.get_style_context().add_class("border");
+ outerMessageBox.add(innerMessageBox);
+ outerMessageBox.append(innerMessageBox);
+
+ innerMessageBox.add(buildEntry('message-heading', _("Message Heading")));
+ innerMessageBox.add(buildTextView('message-body', _("Message Body")));
+ contents.show_all();
+ innerMessageBox.append(buildEntry('message-heading', _("Message Heading")));
+ innerMessageBox.append(buildTextView('message-body', _("Message Body")));
+ return contents;
+}
+
+function buildTextView(key, labelText) {
+ let textView = new Gtk.TextView({
+ 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);
+
+ let scrolledWindow = new Gtk.ScrolledWindow({
+ expand: true,
+ const scrolledWindow = new Gtk.ScrolledWindow({
+ hexpand: true,
+ vexpand: true,
+ visible: true,
+ });
+ let styleContext = scrolledWindow.get_style_context();
+ const styleContext = scrolledWindow.get_style_context();
+ styleContext.add_class("margins");
+
+ scrolledWindow.add(textView);
+ scrolledWindow.set_child(textView);
+ return scrolledWindow;
+}
+function buildEntry(key, labelText) {
+ let entry = new Gtk.Entry({ placeholder_text: labelText });
+ let styleContext = entry.get_style_context();
+ 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);
+
@ -730,15 +878,18 @@ index 00000000..b4b6f94c
+}
+
+function buildSpinButton(key, labelText) {
+ let hbox = new Gtk.Box({
+ const hbox = new Gtk.Box({
+ orientation: Gtk.Orientation.HORIZONTAL,
+ spacing: 10,
+ visible: true,
+ });
+ let label = new Gtk.Label({
+ const label = new Gtk.Label({
+ hexpand: true,
+ label: labelText,
+ visible: true,
+ xalign: 0,
+ });
+ let adjustment = new Gtk.Adjustment({
+ const adjustment = new Gtk.Adjustment({
+ value: 0,
+ lower: 0,
+ upper: 2147483647,
@ -746,34 +897,38 @@ index 00000000..b4b6f94c
+ page_increment: 60,
+ page_size: 60,
+ });
+ let spinButton = new Gtk.SpinButton({
+ 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.pack_start(label, true, true, 0);
+ hbox.add(spinButton);
+ hbox.append(label);
+ hbox.append(spinButton);
+ return hbox;
+}
+
+function buildSwitch(key, labelText) {
+ let hbox = new Gtk.Box({
+ const hbox = new Gtk.Box({
+ orientation: Gtk.Orientation.HORIZONTAL,
+ spacing: 10,
+ visible: true,
+ });
+ let label = new Gtk.Label({
+ const label = new Gtk.Label({
+ hexpand: true,
+ label: labelText,
+ visible: true,
+ xalign: 0,
+ });
+ let switcher = new Gtk.Switch({
+ const 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);
+ hbox.append(label);
+ hbox.append(switcher);
+ return hbox;
+}
diff --git a/extensions/heads-up-display/stylesheet.css b/extensions/heads-up-display/stylesheet.css
@ -815,10 +970,10 @@ index 00000000..93034469
+ text-align: center;
+}
diff --git a/meson.build b/meson.build
index ba84f8f3..c5fc86ef 100644
index 582535c4..ecc86fc8 100644
--- a/meson.build
+++ b/meson.build
@@ -44,6 +44,7 @@ classic_extensions = [
@@ -39,6 +39,7 @@ classic_extensions = [
default_extensions = classic_extensions
default_extensions += [
'drive-menu',
@ -827,5 +982,5 @@ index ba84f8f3..c5fc86ef 100644
'windowsNavigator',
'workspace-indicator'
--
2.32.0
2.33.1

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
From ce48dc2f4fba6a7084540df256cb5b3eb0da43da Mon Sep 17 00:00:00 2001
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
@ -10,7 +10,7 @@ which may be desirable in some circumstances.
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
index 79e2f42..3dfba46 100644
--- a/extensions/top-icons/extension.js
+++ b/extensions/top-icons/extension.js
@@ -63,7 +63,7 @@ class SysTray {
@ -23,5 +23,5 @@ index 79e2f423..3dfba469 100644
}
--
2.31.1
2.32.0

View File

@ -0,0 +1,46 @@
From a31f4b6ca703faab25c306dc33056763642a83cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 30 Sep 2022 18:16:16 +0200
Subject: [PATCH] window-list: Explicitly dispose settings on destroy
This will not only disconnect the signal handler, but also remove
any bindings. This works around a crash that happens if a setting
that triggers the binding changes at the same time as a setting
that rebuilds the window list; in that case, the binding handler
runs after gjs has dropped its wrapper object, but before the
binding is removed automaticalled when the object is finalized.
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/416
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/243>
---
extensions/window-list/extension.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 89413818..91ee3e6b 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -842,8 +842,8 @@ class WindowList extends St.Widget {
this._dndWindow = null;
this._settings = ExtensionUtils.getSettings();
- this._groupingModeChangedId = this._settings.connect(
- 'changed::grouping-mode', this._groupingModeChanged.bind(this));
+ this._settings.connect('changed::grouping-mode',
+ () => this._groupingModeChanged());
this._grouped = undefined;
this._groupingModeChanged();
}
@@ -1112,7 +1112,7 @@ class WindowList extends St.Widget {
Main.xdndHandler.disconnect(this._dragBeginId);
Main.xdndHandler.disconnect(this._dragEndId);
- this._settings.disconnect(this._groupingModeChangedId);
+ this._settings.run_dispose();
let windows = global.get_window_actors();
for (let i = 0; i < windows.length; i++)
--
2.39.1

View File

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

View File

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

View File

@ -0,0 +1,51 @@
From 64d4841a77293a45e769b868e1109b63811be7d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 2 Jul 2024 19:04:10 +0200
Subject: [PATCH] workspace-indicator: Re-fittsify workspace previews
For the window-list extension, it is important that the workspace
previews extend to the bottom edge for easier click targets.
That broke while merging the code with the workspace-indicator,
fix it again by moving the padding from the parent box into the
thumbnail children.
---
.../workspace-indicator/stylesheet-dark.css | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/extensions/workspace-indicator/stylesheet-dark.css b/extensions/workspace-indicator/stylesheet-dark.css
index fb0e8b1a..017d844a 100644
--- a/extensions/workspace-indicator/stylesheet-dark.css
+++ b/extensions/workspace-indicator/stylesheet-dark.css
@@ -11,7 +11,6 @@
}
.workspace-indicator .workspaces-box {
- padding: 5px;
spacing: 3px;
}
@@ -20,6 +19,20 @@
spacing: 6px;
}
+.workspace-indicator .workspace-box {
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+.workspace-indicator StButton:first-child:ltr > .workspace-box,
+.workspace-indicator StButton:last-child:rtl > .workspace-box {
+ padding-left: 5px;
+}
+.workspace-indicator StButton:last-child:ltr > .workspace-box,
+.workspace-indicator StButton:first-child:rtl > .workspace-box {
+ padding-right: 5px;
+}
+
.workspace-indicator-menu .workspace-box {
spacing: 6px;
}
--
2.45.2

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,188 +0,0 @@
From c32e7e78fbb310ac79e2aa1638d0ef50eb08a41c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 23 Nov 2023 21:08:31 +0100
Subject: [PATCH 1/3] apps-menu: Use stylesheet to set width
The `style` property is useful for computed CSS declarations,
but for regular styling the stylesheet is preferable.
Part-of:
<https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
---
extensions/apps-menu/extension.js | 1 -
extensions/apps-menu/stylesheet.css | 2 ++
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
index 1de00df3..3c8c1c9d 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -617,7 +617,6 @@ class ApplicationsButton extends PanelMenu.Button {
_display() {
this._applicationsButtons.clear();
- this.mainBox.style = 'width: 35em;';
this.mainBox.hide();
//Load categories
diff --git a/extensions/apps-menu/stylesheet.css b/extensions/apps-menu/stylesheet.css
index 5bd0d29e..e6d8d8a9 100644
--- a/extensions/apps-menu/stylesheet.css
+++ b/extensions/apps-menu/stylesheet.css
@@ -1,3 +1,5 @@
+.apps-menu {width: 26em;}
+
.apps-menu:ltr {
padding-right: 3px;
}
--
2.43.0
From c6e7573d84dfc5f7850f90220935107ac4027888 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 23 Nov 2023 15:38:25 +0100
Subject: [PATCH 2/3] apps-menu: Remove vertical separator
Ever since gnome-shell stopped using a stippled separator in the
calendar menu, the styling required by the separator has been
missing.
There haven't been any complaints about the invisible separator,
so we can just as well drop it altogether.
Part-of:
<https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
---
extensions/apps-menu/extension.js | 29 -----------------------------
1 file changed, 29 deletions(-)
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
index 3c8c1c9d..34fb24cf 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -425,15 +425,6 @@ class ApplicationsButton extends PanelMenu.Button {
}
}
- _createVertSeparator() {
- let separator = new St.DrawingArea({
- style_class: 'calendar-vertical-separator',
- pseudo_class: 'highlighted'
- });
- separator.connect('repaint', this._onVertSepRepaint.bind(this));
- return separator;
- }
-
_onDestroy() {
super._onDestroy();
@@ -464,21 +455,6 @@ class ApplicationsButton extends PanelMenu.Button {
return super._onMenuKeyPress(actor, event);
}
- _onVertSepRepaint(area) {
- let cr = area.get_context();
- let themeNode = area.get_theme_node();
- let [width, height] = area.get_surface_size();
- let stippleColor = themeNode.get_color('-stipple-color');
- let stippleWidth = themeNode.get_length('-stipple-width');
- let x = Math.floor(width / 2) + 0.5;
- cr.moveTo(x, 0);
- cr.lineTo(x, height);
- Clutter.cairo_set_source_color(cr, stippleColor);
- cr.setDash([1, 3], 1); // Hard-code for now
- cr.setLineWidth(stippleWidth);
- cr.stroke();
- }
-
_onOpenStateChanged(menu, open) {
if (open) {
if (this.reloadFlag) {
@@ -602,11 +578,6 @@ class ApplicationsButton extends PanelMenu.Button {
this.categoriesScrollBox.add_actor(this.categoriesBox);
this.mainBox.add(this.leftBox);
- this.mainBox.add(this._createVertSeparator(), {
- expand: false,
- x_fill: false,
- y_fill: true
- });
this.mainBox.add(this.applicationsScrollBox, {
expand: true,
x_fill: true,
--
2.43.0
From 9c01f6f056e29bebc4a291f9aa3844b473a8b89a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 23 Nov 2023 20:59:57 +0100
Subject: [PATCH 3/3] apps-menu: Use customized layout manager to limit height
To avoid continuous height changes while browsing through categories,
we let the list of categories determine the overall height, and rely
on scrolling for the list of apps within a category.
We currently achieve this by assigning a fixed height via the
`style` property. This has been found to trigger a crash when
running headless, as we end up querying an actor's height request
before a valid resource scale is available.
Instead, use a custom layout manager, which seems more elegant anyway.
Close:
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/472
Part-of:
<https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
---
extensions/apps-menu/extension.js | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
index 34fb24cf..68068cc4 100644
--- a/extensions/apps-menu/extension.js
+++ b/extensions/apps-menu/extension.js
@@ -348,6 +348,17 @@ class DesktopTarget {
}
Signals.addSignalMethods(DesktopTarget.prototype);
+let MainLayout = GObject.registerClass(
+class MainLayout extends Clutter.BoxLayout {
+ vfunc_get_preferred_height(container, forWidth) {
+ const mainChild = container.get_first_child();
+ const [minHeight, natHeight] =
+ mainChild.get_preferred_height(forWidth);
+
+ return [minHeight, natHeight + MENU_HEIGHT_OFFSET];
+ }
+});
+
let ApplicationsButton = GObject.registerClass(
class ApplicationsButton extends PanelMenu.Button {
_init(includeIcon) {
@@ -539,7 +550,7 @@ class ApplicationsButton extends PanelMenu.Button {
_createLayout() {
let section = new PopupMenu.PopupMenuSection();
this.menu.addMenuItem(section);
- this.mainBox = new St.BoxLayout({ vertical: false });
+ this.mainBox = new St.BoxLayout({ layoutManager: new MainLayout() });
this.leftBox = new St.BoxLayout({ vertical: true });
this.applicationsScrollBox = new St.ScrollView({
x_fill: true,
@@ -617,12 +628,6 @@ class ApplicationsButton extends PanelMenu.Button {
//Load applications
this._displayButtons(this._listApplications(null));
-
- let themeContext = St.ThemeContext.get_for_stage(global.stage);
- let scaleFactor = themeContext.scale_factor;
- let categoriesHeight = this.categoriesBox.height / scaleFactor;
- let height = Math.round(categoriesHeight) + MENU_HEIGHT_OFFSET;
- this.mainBox.style += `height: ${height}px`;
}
selectCategory(dir) {
--
2.43.0

View File

@ -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

View File

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

View File

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

View File

@ -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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
From 34d8854677513b016a08a04cdd9973b165146215 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 19 Mar 2024 13:16:50 +0100
Subject: [PATCH 1/2] window-list: Use more appropriate fallback icon
'icon-missing' is not an actual icon name. It somewhat works
because an invalid icon name will fallback to the correct
'image-missing', however for apps the generic app icon is
a better fallback.
---
extensions/window-list/extension.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 91ee3e6b..1f112548 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -188,7 +188,7 @@ class WindowTitle extends St.BoxLayout {
this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
} else {
this._icon.child = new St.Icon({
- icon_name: 'icon-missing',
+ icon_name: 'application-x-executable',
icon_size: ICON_TEXTURE_SIZE,
});
}
--
2.44.0
From 032cfb3593651c8344a59828a9c674f148329889 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 19 Mar 2024 14:07:12 +0100
Subject: [PATCH 2/2] window-list: Override with window icon if available
---
extensions/window-list/extension.js | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 1f112548..0c28692d 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -192,6 +192,23 @@ class WindowTitle extends St.BoxLayout {
icon_size: ICON_TEXTURE_SIZE,
});
}
+
+ // Override with window icon if available
+ if (this._hasWindowIcon()) {
+ const textureCache = St.TextureCache.get_default();
+ this._icon.child.gicon = textureCache.bind_cairo_surface_property(
+ this._metaWindow, 'icon');
+ }
+ }
+
+ _hasWindowIcon() {
+ // HACK: GI cannot handle CairoSurface, so this
+ // will throw if the icon property is null
+ try {
+ return this._metaWindow.icon !== null;
+ } catch (e) {
+ return true;
+ }
}
_onDestroy() {
--
2.44.0

View File

@ -1,7 +1,7 @@
From 7c3b0af4fde0b542089f2b0c84250404eef0ecca Mon Sep 17 00:00:00 2001
From c5e26a4c25754dc74e5f2aa9953bc2e30cfea94e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 17 May 2017 19:13:50 +0200
Subject: [PATCH 1/5] extensions: Resurrect systemMonitor extension
Subject: [PATCH 1/6] extensions: Resurrect systemMonitor extension
The extension was removed upstream because:
- it hooks into the message tray that was removed
@ -26,7 +26,7 @@ This reverts commit c9a6421f362cd156cf731289eadc11f44f6970ac.
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
new file mode 100644
index 0000000..7b09df0
index 00000000..7b09df01
--- /dev/null
+++ b/extensions/systemMonitor/extension.js
@@ -0,0 +1,376 @@
@ -408,7 +408,7 @@ index 0000000..7b09df0
+}
diff --git a/extensions/systemMonitor/meson.build b/extensions/systemMonitor/meson.build
new file mode 100644
index 0000000..48504f6
index 00000000..48504f63
--- /dev/null
+++ b/extensions/systemMonitor/meson.build
@@ -0,0 +1,5 @@
@ -419,7 +419,7 @@ index 0000000..48504f6
+)
diff --git a/extensions/systemMonitor/metadata.json.in b/extensions/systemMonitor/metadata.json.in
new file mode 100644
index 0000000..fa75007
index 00000000..fa750074
--- /dev/null
+++ b/extensions/systemMonitor/metadata.json.in
@@ -0,0 +1,11 @@
@ -436,7 +436,7 @@ index 0000000..fa75007
+}
diff --git a/extensions/systemMonitor/stylesheet.css b/extensions/systemMonitor/stylesheet.css
new file mode 100644
index 0000000..13f95ec
index 00000000..13f95ec7
--- /dev/null
+++ b/extensions/systemMonitor/stylesheet.css
@@ -0,0 +1,35 @@
@ -476,39 +476,41 @@ index 0000000..13f95ec
+ font-weight: bold;
+}
diff --git a/meson.build b/meson.build
index 6e8c41f..6764f9a 100644
index fa9e622a..70dbf007 100644
--- a/meson.build
+++ b/meson.build
@@ -55,6 +55,7 @@ all_extensions += [
@@ -51,6 +51,7 @@ all_extensions += [
'dash-to-panel',
'native-window-placement',
'no-hot-corner',
'panel-favorites',
+ 'systemMonitor',
'top-icons',
'updates-dialog',
'user-theme',
'user-theme'
--
2.21.0
2.41.0
From ddf4d70df56321366a2cb8b89689d59be4dbb718 Mon Sep 17 00:00:00 2001
From efe89316c5ae1721306defcdbb80227fe61414c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 17 May 2019 22:55:48 +0000
Subject: [PATCH 2/5] systemMonitor: Modernise code
Subject: [PATCH 2/6] systemMonitor: Modernise code
- port to ES6 classes
- replace Lang.bind()
- replace Tweener
- use standard align/expand properties
- destructure imports
- fix style issues (stray/missing spaces/semi-colons, indent, ...)
---
extensions/systemMonitor/extension.js | 377 +++++++++++++-------------
1 file changed, 192 insertions(+), 185 deletions(-)
extensions/systemMonitor/extension.js | 422 +++++++++++++-------------
1 file changed, 212 insertions(+), 210 deletions(-)
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
index 7b09df0..89f8916 100644
index 7b09df01..f7c6a4a9 100644
--- a/extensions/systemMonitor/extension.js
+++ b/extensions/systemMonitor/extension.js
@@ -1,22 +1,16 @@
@@ -1,56 +1,57 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
-const Clutter = imports.gi.Clutter;
@ -523,7 +525,7 @@ index 7b09df0..89f8916 100644
+
+const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
-const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
@ -535,8 +537,10 @@ index 7b09df0..89f8916 100644
const INDICATOR_UPDATE_INTERVAL = 500;
const INDICATOR_NUM_GRID_LINES = 3;
@@ -24,32 +18,38 @@ const ITEM_LABEL_SHOW_TIME = 0.15;
const ITEM_LABEL_HIDE_TIME = 0.1;
-const ITEM_LABEL_SHOW_TIME = 0.15;
-const ITEM_LABEL_HIDE_TIME = 0.1;
+const ITEM_LABEL_SHOW_TIME = 150;
+const ITEM_LABEL_HIDE_TIME = 100;
const ITEM_HOVER_TIMEOUT = 300;
-const Indicator = new Lang.Class({
@ -549,7 +553,11 @@ index 7b09df0..89f8916 100644
- this.drawing_area = new St.DrawingArea({ reactive: true });
- this.drawing_area.connect('repaint', Lang.bind(this, this._draw));
- this.drawing_area.connect('button-press-event', function() {
+ this._drawingArea = new St.DrawingArea({ reactive: true });
+ this._drawingArea = new St.DrawingArea({
+ reactive: true,
+ x_expand: true,
+ y_expand: true,
+ });
+ this._drawingArea.connect('repaint', this._draw.bind(this));
+ this._drawingArea.connect('button-press-event', () => {
let app = Shell.AppSystem.get_default().lookup_app('gnome-system-monitor.desktop');
@ -565,10 +573,10 @@ index 7b09df0..89f8916 100644
+ style_class: 'extension-systemMonitor-indicator-area',
+ reactive: true,
+ track_hover: true,
+ x_fill: true,
+ y_fill: true
+ });
+ this.actor.add_actor(this._drawingArea);
+
+ this.actor.connect('destroy', this._onDestroy.bind(this));
- this._timeout = Mainloop.timeout_add(INDICATOR_UPDATE_INTERVAL, Lang.bind(this, function () {
- this._updateValues();
@ -576,9 +584,6 @@ index 7b09df0..89f8916 100644
- return true;
- }));
- },
+ this.actor.connect('destroy', this._onDestroy.bind(this));
- showLabel: function() {
+ this._timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
+ INDICATOR_UPDATE_INTERVAL,
+ () => {
@ -587,12 +592,15 @@ index 7b09df0..89f8916 100644
+ return GLib.SOURCE_CONTINUE;
+ });
+ }
+
- showLabel: function() {
- if (this.label == null)
+ showLabel() {
if (this.label == null)
+ if (this.label === null)
return;
@@ -58,12 +58,10 @@ const Indicator = new Lang.Class({
this.label.opacity = 0;
@@ -58,12 +59,10 @@ const Indicator = new Lang.Class({
let [stageX, stageY] = this.actor.get_transformed_position();
@ -608,7 +616,7 @@ index 7b09df0..89f8916 100644
let x = stageX + xOffset;
@@ -73,48 +71,51 @@ const Indicator = new Lang.Class({
@@ -73,116 +72,113 @@ const Indicator = new Lang.Class({
let y = stageY - this.label.get_height() - yOffset;
this.label.set_position(x, y);
@ -618,21 +626,22 @@ index 7b09df0..89f8916 100644
- transition: 'easeOutQuad',
- });
- },
-
- setLabelText: function(text) {
+ Tweener.addTween(this.label, {
+ this.label.ease({
+ opacity: 255,
+ time: ITEM_LABEL_SHOW_TIME,
+ transition: 'easeOutQuad',
+ duration: ITEM_LABEL_SHOW_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
+ setLabelText(text) {
if (this.label == null)
- setLabelText: function(text) {
- if (this.label == null)
- this.label = new St.Label({ style_class: 'extension-systemMonitor-indicator-label'});
+ setLabelText(text) {
+ if (this.label === null) {
+ this.label = new St.Label({
+ style_class: 'extension-systemMonitor-indicator-label'
+ style_class: 'extension-systemMonitor-indicator-label',
+ });
+ }
this.label.set_text(text);
Main.layoutManager.addChrome(this.label);
@ -655,11 +664,11 @@ index 7b09df0..89f8916 100644
+ }
+ hideLabel() {
+ Tweener.addTween(this.label, {
+ this.label.ease({
+ opacity: 0,
+ time: ITEM_LABEL_HIDE_TIME,
+ transition: 'easeOutQuad',
+ onComplete: () => this.label.hide()
+ duration: ITEM_LABEL_HIDE_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => this.label.hide(),
+ });
+ }
+
@ -669,30 +678,32 @@ index 7b09df0..89f8916 100644
- this.label.destroy();
- },
+ }
+
+ _onDestroy() {
+ GLib.source_remove(this._timeout);
+
+ if (this.label)
+ this.label.destroy();
+ }
- _initValues: function() {
- },
+ _initValues() {
+ }
+ _onDestroy() {
+ GLib.source_remove(this._timeout);
- _updateValues: function() {
- },
+ _updateValues() {
+ if (this.label)
+ this.label.destroy();
+ }
+
+ _initValues() {
+ }
- _draw: function(area) {
+ _updateValues() {
+ }
+
+ _draw(area) {
let [width, height] = area.get_surface_size();
let themeNode = this.actor.get_theme_node();
let cr = area.get_context();
@@ -123,12 +124,12 @@ const Indicator = new Lang.Class({
- //draw the background grid
+ // draw the background grid
let color = themeNode.get_color(this.gridColor);
let gridOffset = Math.floor(height / (INDICATOR_NUM_GRID_LINES + 1));
for (let i = 1; i <= INDICATOR_NUM_GRID_LINES; ++i) {
@ -707,23 +718,61 @@ index 7b09df0..89f8916 100644
+ cr.setDash([4, 1], 0);
cr.stroke();
//draw the foreground
@@ -155,12 +156,12 @@ const Indicator = new Lang.Class({
- //draw the foreground
+ // draw the foreground
- function makePath(values, reverse, nudge) {
- if (nudge == null) {
- nudge = 0;
- }
- //if we are going in reverse, we are completing the bottom of a chart, so use lineTo
+ function makePath(values, reverse, nudge = 0) {
+ // if we are going in reverse, we are completing the bottom of a chart, so use lineTo
if (reverse) {
cr.lineTo(values.length - 1, (1 - values[values.length - 1]) * height + nudge);
- for (let k = values.length - 2; k >= 0; --k) {
+ for (let k = values.length - 2; k >= 0; --k)
cr.lineTo(k, (1 - values[k]) * height + nudge);
- }
} else {
cr.moveTo(0, (1 - values[0]) * height + nudge);
- for (let k = 1; k < values.length; ++k) {
+ for (let k = 1; k < values.length; ++k)
cr.lineTo(k, (1 - values[k]) * height + nudge);
- }
-
}
}
let renderStats = this.renderStats;
// Make sure we don't have more sample points than pixels
- renderStats.map(Lang.bind(this, function(k){
+ renderStats.map(k => {
+ renderStats.forEach(k => {
let stat = this.stats[k];
if (stat.values.length > width) {
- if (stat.values.length > width) {
+ if (stat.values.length > width)
stat.values = stat.values.slice(stat.values.length - width, stat.values.length);
}
- }
- }));
+ });
for (let i = 0; i < renderStats.length; ++i) {
let stat = this.stats[renderStats[i]];
@@ -178,10 +179,10 @@ const Indicator = new Lang.Class({
// We outline at full opacity and fill with 40% opacity
let outlineColor = themeNode.get_color(stat.color);
- let color = new Clutter.Color(outlineColor);
- color.alpha = color.alpha * .4;
+ let fillColor = new Clutter.Color(outlineColor);
+ fillColor.alpha *= .4;
// Render the background between us and the next level
makePath(stat.values, false);
// If there is a process below us, render the cpu between us and it, otherwise,
// render to the bottom of the chart
- if (i == renderStats.length - 1) {
+ if (i === renderStats.length - 1) {
cr.lineTo(stat.values.length - 1, height);
cr.lineTo(0, height);
cr.closePath();
} else {
@ -732,21 +781,23 @@ index 7b09df0..89f8916 100644
makePath(nextStat.values, true);
}
- cr.closePath()
- Clutter.cairo_set_source_color(cr, color);
+ cr.closePath();
Clutter.cairo_set_source_color(cr, color);
+ Clutter.cairo_set_source_color(cr, fillColor);
cr.fill();
@@ -193,40 +194,42 @@ const Indicator = new Lang.Class({
// Render the outline of this level
@@ -193,41 +189,43 @@ const Indicator = new Lang.Class({
cr.stroke();
}
}
-});
-
+};
-const CpuIndicator = new Lang.Class({
- Name: 'SystemMonitor.CpuIndicator',
- Extends: Indicator,
+};
-
- _init: function() {
- this.parent();
+const CpuIndicator = class extends Indicator {
@ -764,7 +815,7 @@ index 7b09df0..89f8916 100644
+ 'cpu-total': 0,
+ 'cpu-user': 1,
+ 'cpu-sys': 2,
+ 'cpu-iowait': 3
+ 'cpu-iowait': 3,
+ };
+ this.renderStats = this.renderStats.sort((a, b) => {
return renderStatOrder[a] - renderStatOrder[b];
@ -776,8 +827,9 @@ index 7b09df0..89f8916 100644
+ }
- _initValues: function() {
- this._prev = new GTop.glibtop_cpu;
+ _initValues() {
this._prev = new GTop.glibtop_cpu;
+ this._prev = new GTop.glibtop_cpu();
GTop.glibtop_get_cpu(this._prev);
this.stats = {
@ -789,18 +841,20 @@ index 7b09df0..89f8916 100644
- },
-
- _updateValues: function() {
- let cpu = new GTop.glibtop_cpu;
+ 'cpu-user': { color: '-cpu-user-color', values: [] },
+ 'cpu-sys': { color: '-cpu-sys-color', values: [] },
+ 'cpu-iowait': { color: '-cpu-iowait-color', values: [] },
+ 'cpu-total': { color: '-cpu-total-color', values: [] }
+ 'cpu-total': { color: '-cpu-total-color', values: [] },
+ };
+ }
+
+ _updateValues() {
let cpu = new GTop.glibtop_cpu;
+ let cpu = new GTop.glibtop_cpu();
let t = 0.0;
GTop.glibtop_get_cpu(cpu);
@@ -246,37 +249,34 @@ const CpuIndicator = new Lang.Class({
let total = cpu.total - this._prev.total;
@@ -246,37 +244,34 @@ const CpuIndicator = new Lang.Class({
this._prev = cpu;
}
@ -834,8 +888,9 @@ index 7b09df0..89f8916 100644
+ }
- _initValues: function() {
- this.mem = new GTop.glibtop_mem;
+ _initValues() {
this.mem = new GTop.glibtop_mem;
+ this.mem = new GTop.glibtop_mem();
this.stats = {
- 'mem-user': { color: "-mem-user-color", values: [] },
- 'mem-other': { color: "-mem-other-color", values: [] },
@ -844,7 +899,7 @@ index 7b09df0..89f8916 100644
- },
+ 'mem-user': { color: '-mem-user-color', values: [] },
+ 'mem-other': { color: '-mem-other-color', values: [] },
+ 'mem-cached': { color: '-mem-cached-color', values: [] }
+ 'mem-cached': { color: '-mem-cached-color', values: [] },
+ };
+ }
@ -853,7 +908,7 @@ index 7b09df0..89f8916 100644
GTop.glibtop_get_mem(this.mem);
let t = this.mem.user / this.mem.total;
@@ -286,90 +286,97 @@ const MemoryIndicator = new Lang.Class({
@@ -286,90 +281,97 @@ const MemoryIndicator = new Lang.Class({
t += this.mem.cached / this.mem.total;
this.stats['mem-cached'].values.push(t);
}
@ -926,12 +981,12 @@ index 7b09df0..89f8916 100644
+ this._box = new St.BoxLayout({
+ style_class: 'extension-systemMonitor-container',
+ x_align: Clutter.ActorAlign.START,
+ x_expand: true
+ x_expand: true,
+ });
+ this._indicators = [];
+
+ for (let i = 0; i < INDICATORS.length; i++) {
+ let indicator = new (INDICATORS[i])();
+ let indicator = new INDICATORS[i]();
+
+ indicator.actor.connect('notify::hover', () => {
+ this._onHover(indicator);
@ -1026,13 +1081,119 @@ index 7b09df0..89f8916 100644
function init() {
return new Extension();
--
2.21.0
2.41.0
From e7ea49cd416e8ede9767f5ade46a06764d1e9a5b Mon Sep 17 00:00:00 2001
From fe1916c1b29ab64c73179ab4c86e106ff69f977d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 26 May 2021 19:50:37 +0200
Subject: [PATCH 3/6] systemMonitor: Make label property private
There is no good reason to use a public property, and the name will
clash when we subclass St.Button.
---
extensions/systemMonitor/extension.js | 35 ++++++++++++++-------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
index f7c6a4a9..bde25a1d 100644
--- a/extensions/systemMonitor/extension.js
+++ b/extensions/systemMonitor/extension.js
@@ -19,6 +19,7 @@ const ITEM_HOVER_TIMEOUT = 300;
const Indicator = class {
constructor() {
+ this._label = null;
this._initValues();
this._drawingArea = new St.DrawingArea({
reactive: true,
@@ -51,28 +52,28 @@ const Indicator = class {
}
showLabel() {
- if (this.label === null)
+ if (this._label === null)
return;
- this.label.opacity = 0;
- this.label.show();
+ this._label.opacity = 0;
+ this._label.show();
let [stageX, stageY] = this.actor.get_transformed_position();
let itemWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
- let labelWidth = this.label.width;
+ let labelWidth = this._label.width;
let xOffset = Math.floor((itemWidth - labelWidth) / 2);
let x = stageX + xOffset;
- let node = this.label.get_theme_node();
+ let node = this._label.get_theme_node();
let yOffset = node.get_length('-y-offset');
- let y = stageY - this.label.get_height() - yOffset;
+ let y = stageY - this._label.get_height() - yOffset;
- this.label.set_position(x, y);
- this.label.ease({
+ this._label.set_position(x, y);
+ this._label.ease({
opacity: 255,
duration: ITEM_LABEL_SHOW_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -80,23 +81,23 @@ const Indicator = class {
}
setLabelText(text) {
- if (this.label === null) {
- this.label = new St.Label({
+ if (this._label === null) {
+ this._label = new St.Label({
style_class: 'extension-systemMonitor-indicator-label',
});
}
- this.label.set_text(text);
- Main.layoutManager.addChrome(this.label);
- this.label.hide();
+ this._label.set_text(text);
+ Main.layoutManager.addChrome(this._label);
+ this._label.hide();
}
hideLabel() {
- this.label.ease({
+ this._label.ease({
opacity: 0,
duration: ITEM_LABEL_HIDE_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => this.label.hide(),
+ onComplete: () => this._label.hide(),
});
}
@@ -107,8 +108,8 @@ const Indicator = class {
_onDestroy() {
GLib.source_remove(this._timeout);
- if (this.label)
- this.label.destroy();
+ if (this._label)
+ this._label.destroy();
}
_initValues() {
--
2.41.0
From b8457707c2b05b88d443587b729e1893cf8b8d3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 17 May 2017 19:31:58 +0200
Subject: [PATCH 3/5] systemMonitor: Move indicators to calendar
Subject: [PATCH 4/6] systemMonitor: Move indicators to calendar
The message tray joined the invisible choir, so we have to find
a new home for the extension UI. The message list in the calendar
@ -1040,45 +1201,59 @@ drop-down looks like the best option, given that it replaced the
old tray (and also took over the old keyboard shortcut to bring
it up quickly).
---
extensions/systemMonitor/extension.js | 65 ++++++++++++-------------
extensions/systemMonitor/stylesheet.css | 14 ------
2 files changed, 31 insertions(+), 48 deletions(-)
extensions/systemMonitor/extension.js | 106 +++++++++++-------------
extensions/systemMonitor/stylesheet.css | 14 ----
2 files changed, 50 insertions(+), 70 deletions(-)
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
index 89f8916..0188960 100644
index bde25a1d..1fd01ab4 100644
--- a/extensions/systemMonitor/extension.js
+++ b/extensions/systemMonitor/extension.js
@@ -3,9 +3,11 @@
@@ -2,10 +2,11 @@
/* exported init */
const { Clutter, GLib, GTop, Shell, St } = imports.gi;
+const Signals = imports.signals;
-const { Clutter, GLib, GTop, Shell, St } = imports.gi;
+const { Clutter, GLib, GObject, GTop, Shell, St } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
+const MessageList = imports.ui.messageList;
const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
@@ -21,22 +23,25 @@ const ITEM_HOVER_TIMEOUT = 300;
const Indicator = class {
constructor() {
const _ = Gettext.gettext;
@@ -17,30 +18,38 @@ const ITEM_LABEL_SHOW_TIME = 150;
const ITEM_LABEL_HIDE_TIME = 100;
const ITEM_HOVER_TIMEOUT = 300;
-const Indicator = class {
- constructor() {
+const Indicator = GObject.registerClass({
+ Signals: {
+ 'close': {},
+ 'expanded': {},
+ 'unexpanded': {},
+ },
+}, class Indicator extends St.Button {
+ _init() {
this._label = null;
this._initValues();
- this._drawingArea = new St.DrawingArea({ reactive: true });
+ this._drawingArea = new St.DrawingArea();
this._drawingArea = new St.DrawingArea({
- reactive: true,
x_expand: true,
y_expand: true,
});
this._drawingArea.connect('repaint', this._draw.bind(this));
- this._drawingArea.connect('button-press-event', () => {
+
+ this.actor = new St.Button({
+ super._init({
+ style_class: 'message message-content extension-systemMonitor-indicator-area',
+ child: this._drawingArea,
+ x_expand: true,
+ x_fill: true,
+ y_fill: true,
+ can_focus: true
+ can_focus: true,
+ });
+
+ this.actor.connect('clicked', () => {
+ this.connect('clicked', () => {
let app = Shell.AppSystem.get_default().lookup_app('gnome-system-monitor.desktop');
app.open_new_window(-1);
- return true;
@ -1088,66 +1263,125 @@ index 89f8916..0188960 100644
- style_class: 'extension-systemMonitor-indicator-area',
- reactive: true,
- track_hover: true,
- x_fill: true,
- y_fill: true
+ Main.overview.hide();
+ Main.panel.closeCalendar();
});
- this.actor.add_actor(this._drawingArea);
this.actor.connect('destroy', this._onDestroy.bind(this));
- this.actor.connect('destroy', this._onDestroy.bind(this));
+ this.connect('destroy', this._onDestroy.bind(this));
@@ -71,6 +76,7 @@ const Indicator = class {
let y = stageY - this.label.get_height() - yOffset;
this._timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
INDICATOR_UPDATE_INTERVAL,
@@ -58,9 +67,9 @@ const Indicator = class {
this._label.opacity = 0;
this._label.show();
this.label.set_position(x, y);
+ this.label.get_parent().set_child_above_sibling(this.label, null);
Tweener.addTween(this.label, {
- let [stageX, stageY] = this.actor.get_transformed_position();
+ let [stageX, stageY] = this.get_transformed_position();
- let itemWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
+ let itemWidth = this.allocation.x2 - this.allocation.x1;
let labelWidth = this._label.width;
let xOffset = Math.floor((itemWidth - labelWidth) / 2);
@@ -73,6 +82,7 @@ const Indicator = class {
let y = stageY - this._label.get_height() - yOffset;
this._label.set_position(x, y);
+ this._label.get_parent().set_child_above_sibling(this._label, null);
this._label.ease({
opacity: 255,
time: ITEM_LABEL_SHOW_TIME,
@@ -98,6 +104,14 @@ const Indicator = class {
duration: ITEM_LABEL_SHOW_TIME,
@@ -101,8 +111,12 @@ const Indicator = class {
});
}
- destroy() {
- this.actor.destroy();
+ /* MessageList.Message boilerplate */
+ canClose() {
+ return false;
+ }
+
+ clear() {
+ }
+
destroy() {
this.actor.destroy();
}
@@ -195,6 +209,7 @@ const Indicator = class {
_onDestroy() {
@@ -120,7 +134,7 @@ const Indicator = class {
_draw(area) {
let [width, height] = area.get_surface_size();
- let themeNode = this.actor.get_theme_node();
+ let themeNode = this.get_theme_node();
let cr = area.get_context();
// draw the background grid
@@ -190,11 +204,12 @@ const Indicator = class {
cr.stroke();
}
}
};
+Signals.addSignalMethods(Indicator.prototype); // For MessageList.Message compat
-};
+});
const CpuIndicator = class extends Indicator {
constructor() {
@@ -300,11 +315,7 @@ class Extension {
-const CpuIndicator = class extends Indicator {
- constructor() {
- super();
+const CpuIndicator = GObject.registerClass(
+class CpuIndicator extends Indicator {
+ _init() {
+ super._init();
this.gridColor = '-grid-color';
this.renderStats = ['cpu-user', 'cpu-sys', 'cpu-iowait'];
@@ -245,11 +260,12 @@ const CpuIndicator = class extends Indicator {
this._prev = cpu;
}
-};
+});
-const MemoryIndicator = class extends Indicator {
- constructor() {
- super();
+const MemoryIndicator = GObject.registerClass(
+class MemoryIndicator extends Indicator {
+ _init() {
+ super._init();
this.gridColor = '-grid-color';
this.renderStats = ['mem-user', 'mem-other', 'mem-cached'];
@@ -282,7 +298,7 @@ const MemoryIndicator = class extends Indicator {
t += this.mem.cached / this.mem.total;
this.stats['mem-cached'].values.push(t);
}
-};
+});
const INDICATORS = [CpuIndicator, MemoryIndicator];
@@ -296,49 +312,27 @@ class Extension {
}
enable() {
- this._box = new St.BoxLayout({
- style_class: 'extension-systemMonitor-container',
- x_align: Clutter.ActorAlign.START,
- x_expand: true
- x_expand: true,
- });
- this._indicators = [];
+ this._section = new MessageList.MessageListSection(_('System Monitor'));
this._indicators = [];
for (let i = 0; i < INDICATORS.length; i++) {
@@ -313,32 +324,18 @@ class Extension {
indicator.actor.connect('notify::hover', () => {
let indicator = new INDICATORS[i]();
- indicator.actor.connect('notify::hover', () => {
+ indicator.connect('notify::hover', () => {
this._onHover(indicator);
});
- this._box.add_actor(indicator.actor);
- this._indicators.push(indicator);
+ this._section.addMessage(indicator, false);
this._indicators.push(indicator);
}
- this._boxHolder = new St.BoxLayout({
@ -1162,24 +1396,29 @@ index 89f8916..0188960 100644
- this._boxHolder.add_child(this._box);
- this._boxHolder.add_child(menuButton);
+ Main.panel.statusArea.dateMenu._messageList._addSection(this._section);
+ this._section.actor.get_parent().set_child_at_index(this._section.actor, 0);
+ this._section.get_parent().set_child_at_index(this._section, 0);
}
disable() {
this._indicators.forEach(i => i.destroy());
- this._indicators.forEach(i => i.destroy());
-
- let menuButton = Main.messageTray._messageTrayMenuButton.actor;
- this._boxHolder.remove_child(menuButton);
- Main.messageTray.actor.add_child(menuButton);
-
- this._box.destroy();
- this._boxHolder.destroy();
+ Main.panel.statusArea.dateMenu._messageList._removeSection(this._section);
+ this._section.destroy();
}
_onHover(item) {
- if (item.actor.get_hover()) {
+ if (item.get_hover()) {
if (this._showLabelTimeoutId)
return;
diff --git a/extensions/systemMonitor/stylesheet.css b/extensions/systemMonitor/stylesheet.css
index 13f95ec..978ac12 100644
index 13f95ec7..978ac12a 100644
--- a/extensions/systemMonitor/stylesheet.css
+++ b/extensions/systemMonitor/stylesheet.css
@@ -1,17 +1,4 @@
@ -1209,13 +1448,13 @@ index 13f95ec..978ac12 100644
.extension-systemMonitor-indicator-label {
--
2.21.0
2.41.0
From f73fe9cfb5f9dbd6647e4eb30a9af0fb7ff79219 Mon Sep 17 00:00:00 2001
From bc05d47dbd45f761b14d90f60fd16259486bcb53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 18 May 2017 16:20:07 +0200
Subject: [PATCH 4/5] systemMonitor: Handle clicks on section title
Subject: [PATCH 5/6] systemMonitor: Handle clicks on section title
While on 3.24.x only the event section still has a clickable title,
it's a generic message list feature in previous versions. It's easy
@ -1224,20 +1463,21 @@ the generic baseclass.
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions3
---
extensions/systemMonitor/extension.js | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
extensions/systemMonitor/extension.js | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/extensions/systemMonitor/extension.js b/extensions/systemMonitor/extension.js
index 0188960..b4d5a9d 100644
index 1fd01ab4..57bdb51f 100644
--- a/extensions/systemMonitor/extension.js
+++ b/extensions/systemMonitor/extension.js
@@ -303,6 +303,21 @@ const MemoryIndicator = class extends Indicator {
@@ -300,6 +300,22 @@ class MemoryIndicator extends Indicator {
}
};
});
+const SystemMonitorSection = GObject.registerClass(
+class SystemMonitorSection extends MessageList.MessageListSection {
+ constructor() {
+ super(_('System Monitor'));
+ _init() {
+ super._init(_('System Monitor'));
+ }
+
+ _onTitleClicked() {
@ -1248,28 +1488,28 @@ index 0188960..b4d5a9d 100644
+ if (app)
+ app.open_new_window(-1);
+ }
+}
+});
+
const INDICATORS = [CpuIndicator, MemoryIndicator];
class Extension {
@@ -315,7 +330,7 @@ class Extension {
@@ -312,7 +328,7 @@ class Extension {
}
enable() {
- this._section = new MessageList.MessageListSection(_('System Monitor'));
+ this._section = new SystemMonitorSection();
this._indicators = [];
for (let i = 0; i < INDICATORS.length; i++) {
let indicator = new INDICATORS[i]();
--
2.21.0
2.41.0
From df76e98d6bbac7dccc86f66e82eac2977fb5ed87 Mon Sep 17 00:00:00 2001
From 597086c27823a7eb0b2124bfbe2c0572bbd1783d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 18 May 2017 18:00:17 +0200
Subject: [PATCH 5/5] systemMonitor: Provide classic styling
Subject: [PATCH 6/6] systemMonitor: Provide classic styling
The indicator tooltips currently don't work out in classic mode
(dark text on dark background), so provide some mode-specific
@ -1284,7 +1524,7 @@ Fixes: #4
diff --git a/extensions/systemMonitor/classic.css b/extensions/systemMonitor/classic.css
new file mode 100644
index 0000000..946863d
index 00000000..946863dc
--- /dev/null
+++ b/extensions/systemMonitor/classic.css
@@ -0,0 +1,6 @@
@ -1295,7 +1535,7 @@ index 0000000..946863d
+ border: 1px solid #a1a1a1;
+}
diff --git a/extensions/systemMonitor/meson.build b/extensions/systemMonitor/meson.build
index 48504f6..b6548b1 100644
index 48504f63..b6548b14 100644
--- a/extensions/systemMonitor/meson.build
+++ b/extensions/systemMonitor/meson.build
@@ -3,3 +3,7 @@ extension_data += configure_file(
@ -1307,5 +1547,5 @@ index 48504f6..b6548b1 100644
+ extension_data += files('classic.css')
+endif
--
2.21.0
2.41.0

View File

@ -1,366 +1,7 @@
From f5fca95984f387a4abf10bff27b06f59d366353f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 25 Sep 2024 02:23:41 +0200
Subject: [PATCH 1/4] window-list: Split out AppTitle class
Even though it's just a box with icon and label, it's cleaner to
have a dedicated class.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/337>
---
extensions/window-list/extension.js | 69 ++++++++++++++++++-----------
1 file changed, 43 insertions(+), 26 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 0baaeecb..3f13bb82 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -206,6 +206,46 @@ class WindowTitle {
}
}
+class AppTitle {
+ constructor(app) {
+ this.actor = new St.BoxLayout({
+ style_class: 'window-button-box',
+ x_expand: true,
+ y_expand: true,
+ });
+
+ this._app = app;
+
+ const icon = new St.Bin({
+ style_class: 'window-button-icon',
+ child: app.create_icon_texture(ICON_TEXTURE_SIZE),
+ });
+ this.actor.add_child(icon);
+
+ let label = new St.Label({
+ text: app.get_name(),
+ y_align: Clutter.ActorAlign.CENTER,
+ });
+ this.actor.add_child(label);
+ this.label_actor = label;
+
+ this._textureCache = St.TextureCache.get_default();
+ this._iconThemeChangedId =
+ this._textureCache.connect('icon-theme-changed', () => {
+ icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
+ });
+
+ this.actor.connect('destroy', this._onDestroy.bind(this));
+ }
+
+ _onDestroy() {
+ if (this._iconThemeChangedId)
+ this._textureCache.disconnect(this._iconThemeChangedId);
+ this._iconThemeChangedId = 0;
+ this._textureCache = null;
+ }
+}
+
class BaseButton {
constructor(perMonitor, monitorIndex) {
@@ -519,24 +559,8 @@ class AppButton extends BaseButton {
});
stack.add_actor(this._singleWindowTitle);
- this._multiWindowTitle = new St.BoxLayout({
- style_class: 'window-button-box',
- x_expand: true
- });
- stack.add_actor(this._multiWindowTitle);
-
- this._icon = new St.Bin({
- style_class: 'window-button-icon',
- child: app.create_icon_texture(ICON_TEXTURE_SIZE)
- });
- this._multiWindowTitle.add(this._icon);
-
- let label = new St.Label({
- text: app.get_name(),
- y_align: Clutter.ActorAlign.CENTER
- });
- this._multiWindowTitle.add(label);
- this._multiWindowTitle.label_actor = label;
+ this._multiWindowTitle = new AppTitle(app);
+ stack.add_actor(this._multiWindowTitle.actor);
this._menuManager = new PopupMenu.PopupMenuManager(this);
this._menu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.BOTTOM);
@@ -551,12 +575,6 @@ class AppButton extends BaseButton {
this._appContextMenu.actor.hide();
Main.uiGroup.add_actor(this._appContextMenu.actor);
- this._textureCache = St.TextureCache.get_default();
- this._iconThemeChangedId =
- this._textureCache.connect('icon-theme-changed', () => {
- this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
- });
-
this._windowsChangedId =
this.app.connect('windows-changed',
this._windowsChanged.bind(this));
@@ -605,7 +623,7 @@ class AppButton extends BaseButton {
_windowsChanged() {
let windows = this.getWindowList();
this._singleWindowTitle.visible = windows.length == 1;
- this._multiWindowTitle.visible = !this._singleWindowTitle.visible;
+ this._multiWindowTitle.actor.visible = !this._singleWindowTitle.visible;
if (this._singleWindowTitle.visible) {
if (!this._windowTitle) {
@@ -684,7 +702,6 @@ class AppButton extends BaseButton {
_onDestroy() {
super._onDestroy();
- this._textureCache.disconnect(this._iconThemeChangedId);
this._windowTracker.disconnect(this._notifyFocusId);
this.app.disconnect(this._windowsChangedId);
this._menu.destroy();
--
2.47.1
From 5875892c2579f622ca4bcc54e5f25801869e14ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 25 Sep 2024 02:55:14 +0200
Subject: [PATCH 2/4] window-list: Simplify app button
Depending on the number of windows, the button either shows the
title of the lone window, or the app title for multiple windows.
While we always recreate the single-window title, we only create
the app title once and hide it as necessary. Avoiding re-creating
a simple actor 50% of mode transitions isn't worth the additional
complexity, so just handle both single- and multi-window titles
the same way.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/337>
---
extensions/window-list/extension.js | 73 ++++++++++-------------------
1 file changed, 26 insertions(+), 47 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 3f13bb82..0723e9e2 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -549,19 +549,6 @@ class AppButton extends BaseButton {
this.app = app;
this._updateVisibility();
- let stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
- this.actor.set_child(stack);
-
- this._singleWindowTitle = new St.Bin({
- x_expand: true,
- y_fill: true,
- x_align: St.Align.START
- });
- stack.add_actor(this._singleWindowTitle);
-
- this._multiWindowTitle = new AppTitle(app);
- stack.add_actor(this._multiWindowTitle.actor);
-
this._menuManager = new PopupMenu.PopupMenuManager(this);
this._menu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.BOTTOM);
this._menu.connect('open-state-changed', _onMenuStateChanged);
@@ -570,11 +557,6 @@ class AppButton extends BaseButton {
this._menuManager.addMenu(this._menu);
Main.uiGroup.add_actor(this._menu.actor);
- this._appContextMenu = new AppContextMenu(this.actor, this);
- this._appContextMenu.connect('open-state-changed', _onMenuStateChanged);
- this._appContextMenu.actor.hide();
- Main.uiGroup.add_actor(this._appContextMenu.actor);
-
this._windowsChangedId =
this.app.connect('windows-changed',
this._windowsChanged.bind(this));
@@ -621,38 +603,35 @@ class AppButton extends BaseButton {
}
_windowsChanged() {
- let windows = this.getWindowList();
- this._singleWindowTitle.visible = windows.length == 1;
- this._multiWindowTitle.actor.visible = !this._singleWindowTitle.visible;
-
- if (this._singleWindowTitle.visible) {
- if (!this._windowTitle) {
- this.metaWindow = windows[0];
- this._windowTitle = new WindowTitle(this.metaWindow);
- this._singleWindowTitle.child = this._windowTitle.actor;
- this._windowContextMenu = new WindowContextMenu(this.actor, this.metaWindow);
- this._windowContextMenu.connect('open-state-changed',
- _onMenuStateChanged);
- Main.uiGroup.add_actor(this._windowContextMenu.actor);
- this._windowContextMenu.actor.hide();
- this._contextMenuManager.addMenu(this._windowContextMenu);
- }
- this._contextMenuManager.removeMenu(this._appContextMenu);
- this._contextMenu = this._windowContextMenu;
- this.actor.label_actor = this._windowTitle.label_actor;
+ const windows = this.getWindowList();
+ const singleWindowMode = windows.length === 1;
+
+ if (this._singleWindowMode === singleWindowMode)
+ return;
+
+ this._singleWindowMode = singleWindowMode;
+
+ if (this.actor.child)
+ this.actor.child.destroy();
+ if (this._contextMenu)
+ this._contextMenu.destroy();
+
+ if (this._singleWindowMode) {
+ const [window] = windows;
+ this._titleWidget = new WindowTitle(window);
+ this._contextMenu = new WindowContextMenu(this.actor, window);
} else {
- if (this._windowTitle) {
- this.metaWindow = null;
- this._singleWindowTitle.child = null;
- this._windowTitle = null;
- this._windowContextMenu.destroy();
- this._windowContextMenu = null;
- }
- this._contextMenu = this._appContextMenu;
- this._contextMenuManager.addMenu(this._appContextMenu);
- this.actor.label_actor = this._multiWindowTitle.label_actor;
+ this._titleWidget = new AppTitle(this.app);
+ this._contextMenu = new AppContextMenu(this.actor);
}
+ this.actor.child = this._titleWidget.actor;
+ this.actor.label_actor = this._titleWidget.label_actor;
+
+ this._contextMenu.connect('open-state-changed', _onMenuStateChanged);
+ Main.uiGroup.add_child(this._contextMenu.actor);
+ this._contextMenu.actor.hide();
+ this._contextMenuManager.addMenu(this._contextMenu);
}
_onClicked(actor, button) {
--
2.47.1
From 68fe36c199c9d68ed8ad739e9419f052a253afa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 3 Oct 2024 17:19:31 +0200
Subject: [PATCH 3/4] window-list: Split out common TitleWidget class
Both app- and window title use the same structure, so add a shared
base class.
---
extensions/window-list/extension.js | 55 ++++++++++++++---------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 0723e9e2..9cbfd4fb 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -134,19 +134,32 @@ class WindowContextMenu extends PopupMenu.PopupMenu {
}
}
-class WindowTitle {
- constructor(metaWindow) {
- this._metaWindow = metaWindow;
+class TitleWidget {
+ constructor() {
this.actor = new St.BoxLayout({
style_class: 'window-button-box',
x_expand: true,
y_expand: true
});
- this._icon = new St.Bin({ style_class: 'window-button-icon' });
- this.actor.add(this._icon);
- this.label_actor = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
- this.actor.add(this.label_actor);
+ this._icon = new St.Bin({
+ style_class: 'window-button-icon',
+ });
+ this.actor.add_child(this._icon);
+
+ this._label = new St.Label({
+ y_align: Clutter.ActorAlign.CENTER,
+ });
+ this.actor.add_child(this._label);
+ this.label_actor = this._label;
+ }
+}
+
+class WindowTitle extends TitleWidget {
+ constructor(metaWindow) {
+ super();
+
+ this._metaWindow = metaWindow;
this._textureCache = St.TextureCache.get_default();
this._iconThemeChangedId =
@@ -181,9 +194,9 @@ class WindowTitle {
return;
if (this._metaWindow.minimized)
- this.label_actor.text = '[%s]'.format(this._metaWindow.title);
+ this._label.text = '[%s]'.format(this._metaWindow.title);
else
- this.label_actor.text = this._metaWindow.title;
+ this._label.text = this._metaWindow.title;
}
_updateIcon() {
@@ -206,33 +219,19 @@ class WindowTitle {
}
}
-class AppTitle {
+class AppTitle extends TitleWidget {
constructor(app) {
- this.actor = new St.BoxLayout({
- style_class: 'window-button-box',
- x_expand: true,
- y_expand: true,
- });
+ super();
this._app = app;
- const icon = new St.Bin({
- style_class: 'window-button-icon',
- child: app.create_icon_texture(ICON_TEXTURE_SIZE),
- });
- this.actor.add_child(icon);
-
- let label = new St.Label({
- text: app.get_name(),
- y_align: Clutter.ActorAlign.CENTER,
- });
- this.actor.add_child(label);
- this.label_actor = label;
+ this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
+ this._label.text = app.get_name();
this._textureCache = St.TextureCache.get_default();
this._iconThemeChangedId =
this._textureCache.connect('icon-theme-changed', () => {
- icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
+ this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
});
this.actor.connect('destroy', this._onDestroy.bind(this));
--
2.47.1
From 822d2ba9a8545f2af2664768c1ca9a7938059088 Mon Sep 17 00:00:00 2001
From 984a2672b4c4c41d9dab85c068f76efa98f81a56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 17 Dec 2024 01:09:34 +0100
Subject: [PATCH 4/4] window-list: Add attention indicator
Subject: [PATCH] window-list: Add attention indicator
Some X11 clients still rely on the traditional urgent/demand-attention
hints instead of notifications to request the user's attention.
@ -375,40 +16,53 @@ Closes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/543
2 files changed, 95 insertions(+), 4 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 9cbfd4fb..11ac393b 100644
index bb9ca80f..477ed8fe 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -136,22 +136,46 @@ class WindowContextMenu extends PopupMenu.PopupMenu {
class TitleWidget {
constructor() {
- this.actor = new St.BoxLayout({
- style_class: 'window-button-box',
+ this.actor = new St.Widget({
@@ -160,23 +160,30 @@ const TitleWidget = GObject.registerClass({
GObject.ParamFlags.READWRITE,
false),
},
-}, class TitleWidget extends St.BoxLayout {
+}, class TitleWidget extends St.Widget {
_init() {
super._init({
+ layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true
});
+ const hbox = new St.BoxLayout({
+ style_class: 'window-button-box',
+ x_expand: true,
+ y_expand: true,
+ });
+ this.actor.add_child(hbox);
+
+ const hbox = new St.BoxLayout({
style_class: 'window-button-box',
x_expand: true,
y_expand: true,
});
+ this.add_child(hbox);
this._icon = new St.Bin({
style_class: 'window-button-icon',
});
- this.actor.add_child(this._icon);
- this.add_child(this._icon);
+ hbox.add_child(this._icon);
this._label = new St.Label({
y_align: Clutter.ActorAlign.CENTER,
});
- this.actor.add_child(this._label);
- this.add_child(this._label);
+ hbox.add_child(this._label);
this.label_actor = this._label;
this.bind_property('abstract-label',
@@ -189,11 +196,28 @@ const TitleWidget = GObject.registerClass({
x_expand: true,
y_expand: true,
});
- this.add_child(this._abstractLabel);
+ hbox.add_child(this._abstractLabel);
this.bind_property('abstract-label',
this._abstractLabel, 'visible',
GObject.BindingFlags.SYNC_CREATE);
+
+ this._attentionIndicator = new St.Widget({
+ style_class: 'window-button-attention-indicator',
@ -418,21 +72,21 @@ index 9cbfd4fb..11ac393b 100644
+ scale_x: 0,
+ });
+ this._attentionIndicator.set_pivot_point(0.5, 0.5);
+ this.actor.add_child(this._attentionIndicator);
+ this.add_child(this._attentionIndicator);
+ }
+
+ setNeedsAttention(enable) {
+ Tweener.addTween(this._attentionIndicator, {
+ this._attentionIndicator.ease({
+ scaleX: enable ? 0.4 : 0,
+ time: 0.3,
+ duration: 300,
+ });
}
}
});
@@ -181,7 +205,12 @@ class WindowTitle extends TitleWidget {
this._notifyMinimizedId =
this._metaWindow.connect('notify::minimized',
this._minimizedChanged.bind(this));
@@ -219,7 +243,12 @@ class WindowTitle extends TitleWidget {
'notify::title', this._updateTitle.bind(this));
this._notifyMinimizedId = this._metaWindow.connect(
'notify::minimized', this._minimizedChanged.bind(this));
+ this._notifyDemandsAttentionId = this._metaWindow.connect(
+ 'notify::demands-attention', this._updateNeedsAttention.bind(this));
+ this._notifyUrgentId = this._metaWindow.connect(
@ -442,7 +96,7 @@ index 9cbfd4fb..11ac393b 100644
}
_minimizedChanged() {
@@ -189,6 +218,11 @@ class WindowTitle extends TitleWidget {
@@ -227,6 +256,11 @@ class WindowTitle extends TitleWidget {
this._updateTitle();
}
@ -454,24 +108,24 @@ index 9cbfd4fb..11ac393b 100644
_updateTitle() {
if (!this._metaWindow.title)
return;
@@ -216,6 +250,8 @@ class WindowTitle extends TitleWidget {
@@ -272,6 +306,8 @@ class WindowTitle extends TitleWidget {
this._metaWindow.disconnect(this._notifyMinimizedId);
this._metaWindow.disconnect(this._notifyWmClass);
this._metaWindow.disconnect(this._notifyAppId);
+ this._metaWindow.disconnect(this._notifyDemandsAttentionId);
+ this._metaWindow.disconnect(this._notifyUrgentId);
}
}
});
@@ -224,6 +260,7 @@ class AppTitle extends TitleWidget {
super();
@@ -281,6 +317,7 @@ class AppTitle extends TitleWidget {
super._init();
this._app = app;
+ this._windows = new Map();
this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
this._label.text = app.get_name();
@@ -234,6 +271,10 @@ class AppTitle extends TitleWidget {
@@ -291,6 +328,10 @@ class AppTitle extends TitleWidget {
this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE);
});
@ -479,10 +133,10 @@ index 9cbfd4fb..11ac393b 100644
+ 'windows-changed', this._onWindowsChanged.bind(this));
+ this._onWindowsChanged();
+
this.actor.connect('destroy', this._onDestroy.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
}
@@ -242,6 +283,47 @@ class AppTitle extends TitleWidget {
@@ -299,6 +340,47 @@ class AppTitle extends TitleWidget {
this._textureCache.disconnect(this._iconThemeChangedId);
this._iconThemeChangedId = 0;
this._textureCache = null;
@ -528,15 +182,15 @@ index 9cbfd4fb..11ac393b 100644
+ [...this._windows.keys()].some(w => w.urgent || w.demandsAttention);
+ this.setNeedsAttention(needsAttention);
}
}
});
diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css
index 79d56bad..2c98aafe 100644
index 4c06ebc0..45b42065 100644
--- a/extensions/window-list/stylesheet.css
+++ b/extensions/window-list/stylesheet.css
@@ -134,3 +134,12 @@
.notification {
font-weight: normal;
@@ -103,3 +103,12 @@
border-radius: 99px;
margin: 6px;
}
+
+.window-button-attention-indicator {

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
From f8ec838485ae81cf2e8ab2b899ad4154c7c06fbd Mon Sep 17 00:00:00 2001
From 0d9210e9c19c1bd9535ffb75b4834c2ccd8db6c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 21 Apr 2022 16:34:50 +0200
Subject: [PATCH 1/2] window-list: Fix primary button action on touch
@ -18,23 +18,23 @@ Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 1f854aa2..fedc4195 100644
index e122cf5f..43885378 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -358,7 +358,7 @@ class WindowButton extends BaseButton {
@@ -381,7 +381,7 @@ class WindowButton extends BaseButton {
return;
}
- if (button == 1)
- if (button === 1)
+ if (!button || button === 1)
_minimizeOrActivateWindow(this.metaWindow);
else
_openMenu(this._contextMenu);
@@ -601,7 +601,7 @@ class AppButton extends BaseButton {
@@ -623,7 +623,7 @@ class AppButton extends BaseButton {
if (contextMenuWasOpen)
this._contextMenu.close();
- if (button == 1) {
- if (button === 1) {
+ if (!button || button === 1) {
if (menuWasOpen)
return;
@ -43,7 +43,7 @@ index 1f854aa2..fedc4195 100644
2.36.1
From d3cf07f8065935736e8a79d06ec79c971c453453 Mon Sep 17 00:00:00 2001
From b080bb7ee88d0e5b35dc4a967d2e44eab7921b6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 5 May 2022 20:55:20 +0200
Subject: [PATCH 2/2] window-list: Open menu on long press
@ -55,25 +55,15 @@ https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/146
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/233>
---
extensions/window-list/extension.js | 45 +++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
extensions/window-list/extension.js | 42 +++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index fedc4195..0baaeecb 100644
index 43885378..3d1cd053 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -229,6 +229,9 @@ class BaseButton {
this.actor.connect('clicked', this._onClicked.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('popup-menu', this._onPopupMenu.bind(this));
+ this.actor.connect('button-press-event', this._onButtonPress.bind(this));
+ this.actor.connect('button-release-event', this._onButtonRelease.bind(this));
+ this.actor.connect('touch-event', this._onTouch.bind(this));
this._contextMenuManager = new PopupMenu.PopupMenuManager(this);
@@ -250,6 +253,48 @@ class BaseButton {
return this.actor.has_style_class_name('focused');
@@ -266,6 +266,48 @@ const BaseButton = GObject.registerClass({
this._updateVisibility();
}
+ _setLongPressTimeout() {
@ -98,24 +88,24 @@ index fedc4195..0baaeecb 100644
+ delete this._longPressTimeoutId;
+ }
+
+ _onButtonPress(button, event) {
+ if (event.get_button() === 1)
+ vfunc_button_press_event(buttonEvent) {
+ if (buttonEvent.button === 1)
+ this._setLongPressTimeout();
+ return Clutter.EVENT_PROPAGATE;
+ return super.vfunc_button_press_event(buttonEvent);
+ }
+
+ _onButtonRelease() {
+ vfunc_button_release_event(buttonEvent) {
+ this._removeLongPressTimeout();
+ return Clutter.EVENT_PROPAGATE;
+
+ return super.vfunc_button_release_event(buttonEvent);
+ }
+
+ _onTouch(event) {
+ const type = event.get_type();
+ if (type === Clutter.EventType.TOUCH_BEGIN)
+ vfunc_touch_event(touchEvent) {
+ if (touchEvent.type === Clutter.EventType.TOUCH_BEGIN)
+ this._setLongPressTimeout();
+ else if (type === Clutter.EventType.TOUCH_END)
+ else if (touchEvent.type === Clutter.EventType.TOUCH_END)
+ this._removeLongPressTimeout();
+ return Clutter.EVENT_PROPAGATE;
+ return super.vfunc_touch_event(touchEvent);
+ }
+
activate() {

File diff suppressed because it is too large Load Diff