diff --git a/.gitignore b/.gitignore index ef691f5..d89451c 100644 --- a/.gitignore +++ b/.gitignore @@ -229,3 +229,4 @@ gnome-shell-2.31.5.tar.bz2 /gnome-shell-46.2.tar.xz /gnome-shell-46.3.1.tar.xz /gnome-shell-47.alpha.tar.xz +/gnome-shell-47.rc.tar.xz diff --git a/gnome-shell.spec b/gnome-shell.spec index 6be2ac9..913d263 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -8,7 +8,7 @@ %endif Name: gnome-shell -Version: 47~alpha +Version: 47~rc Release: %autorelease Summary: Window management and application launching for GNOME @@ -42,7 +42,6 @@ Patch: 0001-main-Dump-stack-on-segfaults-by-default.patch Patch: 0001-st-texture-cache-purge-on-resume.patch Patch: fix-some-js-warnings.patch Patch: 0001-data-Update-generated-stylesheets.patch -Patch: portal-notify.patch Patch: 0001-theme-Welcome-Illustration.patch %define eds_version 3.45.1 @@ -52,7 +51,7 @@ Patch: 0001-theme-Welcome-Illustration.patch %define gjs_version 1.73.1 %define gtk4_version 4.0.0 %define adwaita_version 1.5.0 -%define mutter_version 47~alpha +%define mutter_version 47~rc %define polkit_version 0.100 %define gsettings_desktop_schemas_version 47~alpha %define ibus_version 1.5.2 @@ -87,6 +86,8 @@ BuildRequires: pkgconfig(gtk4) >= %{gtk4_version} BuildRequires: gettext >= 0.19.6 BuildRequires: python3 +# for rst2man +BuildRequires: python3-docutils # for barriers BuildRequires: libXfixes-devel >= 5.0 # used in unused BigThemeImage @@ -228,7 +229,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta %doc NEWS README.md %{_bindir}/gnome-shell %{_bindir}/gnome-extensions -%{_bindir}/gnome-shell-extension-prefs %{_bindir}/gnome-shell-extension-tool %{_bindir}/gnome-shell-test-tool %{_datadir}/glib-2.0/schemas/*.xml diff --git a/portal-notify.patch b/portal-notify.patch deleted file mode 100644 index 33b27ad..0000000 --- a/portal-notify.patch +++ /dev/null @@ -1,511 +0,0 @@ -From d77ed9ad5fdadcdefcc41fecf8200bd2bf47282d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Wed, 12 Jun 2024 13:13:41 +0200 -Subject: [PATCH 1/3] network: Split out CaptivePortalHandler class - -The handling of captive portals is going to be extended a bit, -so split out a proper class instead of mixing it in with the -indicator code. ---- - js/ui/status/network.js | 151 +++++++++++++++++++++++----------------- - 1 file changed, 87 insertions(+), 64 deletions(-) - -diff --git a/js/ui/status/network.js b/js/ui/status/network.js -index 404733b74c..d34e947073 100644 ---- a/js/ui/status/network.js -+++ b/js/ui/status/network.js -@@ -14,6 +14,7 @@ import * as Main from '../main.js'; - import * as PopupMenu from '../popupMenu.js'; - import * as MessageTray from '../messageTray.js'; - import * as ModemManager from '../../misc/modemManager.js'; -+import * as Signals from '../../misc/signals.js'; - import * as Util from '../../misc/util.js'; - - import {Spinner} from '../animation.js'; -@@ -1944,12 +1945,84 @@ class NMModemToggle extends NMDeviceToggle { - } - }); - -+class CaptivePortalHandler extends Signals.EventEmitter { -+ constructor(checkUri) { -+ super(); -+ -+ this._checkUri = checkUri; -+ this._connectivityQueue = new Set(); -+ this._portalHelperProxy = null; -+ } -+ -+ addConnection(path) { -+ if (this._connectivityQueue.has(path)) -+ return; -+ -+ this._launchPortalHelper(path).catch(logError); -+ } -+ -+ removeConnection(path) { -+ if (this._connectivityQueue.delete(path)) -+ this._portalHelperProxy?.CloseAsync(path); -+ } -+ -+ _portalHelperDone(parameters) { -+ const [path, result] = parameters; -+ -+ if (result === PortalHelperResult.CANCELLED) { -+ // Keep the connection in the queue, so the user is not -+ // spammed with more logins until we next flush the queue, -+ // which will happen once they choose a better connection -+ // or we get to full connectivity through other means -+ } else if (result === PortalHelperResult.COMPLETED) { -+ this.removeConnection(path); -+ } else if (result === PortalHelperResult.RECHECK) { -+ this.emit('recheck', path); -+ } else { -+ log(`Invalid result from portal helper: ${result}`); -+ } -+ } -+ -+ async _launchPortalHelper(path) { -+ const timestamp = global.get_current_time(); -+ if (!this._portalHelperProxy) { -+ this._portalHelperProxy = new Gio.DBusProxy({ -+ g_connection: Gio.DBus.session, -+ g_name: 'org.gnome.Shell.PortalHelper', -+ g_object_path: '/org/gnome/Shell/PortalHelper', -+ g_interface_name: PortalHelperInfo.name, -+ g_interface_info: PortalHelperInfo, -+ }); -+ this._portalHelperProxy.connectSignal('Done', -+ (proxy, emitter, params) => { -+ this._portalHelperDone(params); -+ }); -+ -+ try { -+ await this._portalHelperProxy.init_async( -+ GLib.PRIORITY_DEFAULT, null); -+ } catch (e) { -+ console.error(`Error launching the portal helper: ${e.message}`); -+ } -+ } -+ -+ this._portalHelperProxy?.AuthenticateAsync(path, this._checkUri, timestamp).catch(logError); -+ this._connectivityQueue.add(path); -+ } -+ -+ clear() { -+ for (const item of this._connectivityQueue) -+ this._portalHelperProxy?.CloseAsync(item); -+ this._connectivityQueue.clear(); -+ } -+} -+ - export const Indicator = GObject.registerClass( - class Indicator extends SystemIndicator { - _init() { - super._init(); - -- this._connectivityQueue = new Set(); -+ this._portalHandler = null; - - this._mainConnection = null; - -@@ -2004,6 +2077,16 @@ class Indicator extends SystemIndicator { - this, 'visible', - GObject.BindingFlags.SYNC_CREATE); - -+ const {connectivityCheckUri} = this._client; -+ this._portalHandler = new CaptivePortalHandler(connectivityCheckUri); -+ this._portalHandler.connect('recheck', async (o, path) => { -+ try { -+ const state = await this._client.check_connectivity_async(null); -+ if (state >= NM.ConnectivityState.FULL) -+ this._portalHandler.removeConnection(path); -+ } catch (e) { } -+ }); -+ - this._client.connectObject( - 'notify::primary-connection', () => this._syncMainConnection(), - 'notify::activating-connection', () => this._syncMainConnection(), -@@ -2066,42 +2149,10 @@ class Indicator extends SystemIndicator { - this._notification?.destroy(); - } - -- _flushConnectivityQueue() { -- for (let item of this._connectivityQueue) -- this._portalHelperProxy?.CloseAsync(item); -- this._connectivityQueue.clear(); -- } -- -- _closeConnectivityCheck(path) { -- if (this._connectivityQueue.delete(path)) -- this._portalHelperProxy?.CloseAsync(path); -- } -- -- async _portalHelperDone(parameters) { -- let [path, result] = parameters; -- -- if (result === PortalHelperResult.CANCELLED) { -- // Keep the connection in the queue, so the user is not -- // spammed with more logins until we next flush the queue, -- // which will happen once they choose a better connection -- // or we get to full connectivity through other means -- } else if (result === PortalHelperResult.COMPLETED) { -- this._closeConnectivityCheck(path); -- } else if (result === PortalHelperResult.RECHECK) { -- try { -- const state = await this._client.check_connectivity_async(null); -- if (state >= NM.ConnectivityState.FULL) -- this._closeConnectivityCheck(path); -- } catch (e) { } -- } else { -- log(`Invalid result from portal helper: ${result}`); -- } -- } -- -- async _syncConnectivity() { -+ _syncConnectivity() { - if (this._mainConnection == null || - this._mainConnection.state !== NM.ActiveConnectionState.ACTIVATED) { -- this._flushConnectivityQueue(); -+ this._portalHandler.clear(); - return; - } - -@@ -2116,35 +2167,7 @@ class Indicator extends SystemIndicator { - if (!isPortal || Main.sessionMode.isGreeter) - return; - -- let path = this._mainConnection.get_path(); -- if (this._connectivityQueue.has(path)) -- return; -- -- let timestamp = global.get_current_time(); -- if (!this._portalHelperProxy) { -- this._portalHelperProxy = new Gio.DBusProxy({ -- g_connection: Gio.DBus.session, -- g_name: 'org.gnome.Shell.PortalHelper', -- g_object_path: '/org/gnome/Shell/PortalHelper', -- g_interface_name: PortalHelperInfo.name, -- g_interface_info: PortalHelperInfo, -- }); -- this._portalHelperProxy.connectSignal('Done', -- (proxy, emitter, params) => { -- this._portalHelperDone(params).catch(logError); -- }); -- -- try { -- await this._portalHelperProxy.init_async( -- GLib.PRIORITY_DEFAULT, null); -- } catch (e) { -- console.error(`Error launching the portal helper: ${e.message}`); -- } -- } -- -- this._portalHelperProxy?.AuthenticateAsync(path, this._client.connectivity_check_uri, timestamp).catch(logError); -- -- this._connectivityQueue.add(path); -+ this._portalHandler.addConnection(this._mainConnection.get_path()); - } - - _updateIcon() { --- -2.45.2 - - -From cd489e54948e3f2900a1f4e354fd4bb43c62db6d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Wed, 12 Jun 2024 13:13:41 +0200 -Subject: [PATCH 2/3] status/network: Show notification when detecting captive - portal - -When NetworkManager detects limited connectivity, we currently -pop up the portal helper window immediately. This can both be -disruptive when it happens unexpectedly, and unnoticeable -when it happens during screen lock. - -In any case, it seems better to not pop up a window without -explicit user action, so instead show a notification that -launches the portal window when activated. - -Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7688 ---- - js/ui/status/network.js | 38 ++++++++++++++++++++++++++++++++++---- - 1 file changed, 34 insertions(+), 4 deletions(-) - -diff --git a/js/ui/status/network.js b/js/ui/status/network.js -index d34e947073..5d1e168fb5 100644 ---- a/js/ui/status/network.js -+++ b/js/ui/status/network.js -@@ -1951,19 +1951,43 @@ class CaptivePortalHandler extends Signals.EventEmitter { - - this._checkUri = checkUri; - this._connectivityQueue = new Set(); -+ this._notifications = new Map(); - this._portalHelperProxy = null; - } - -- addConnection(path) { -- if (this._connectivityQueue.has(path)) -+ addConnection(name, path) { -+ if (this._connectivityQueue.has(path) || this._notifications.has(path)) - return; - -- this._launchPortalHelper(path).catch(logError); -+ const source = MessageTray.getSystemSource(); -+ -+ const notification = new MessageTray.Notification({ -+ title: _('Sign Into Wi–Fi Network'), -+ body: name, -+ source, -+ }); -+ notification.connect('activated', -+ () => this._onNotificationActivated(path).catch(logError)); -+ notification.connect('destroy', -+ () => this._notifications.delete(path)); -+ this._notifications.set(path, notification); -+ source.addNotification(notification); - } - -+ - removeConnection(path) { - if (this._connectivityQueue.delete(path)) - this._portalHelperProxy?.CloseAsync(path); -+ this._notifications.get(path)?.destroy( -+ MessageTray.NotificationDestroyedReason.SOURCE_CLOSED); -+ this._notifications.delete(path); -+ } -+ -+ _onNotificationActivated(path) { -+ this._launchPortalHelper(path).catch(logError); -+ -+ Main.overview.hide(); -+ Main.panel.closeCalendar(); - } - - _portalHelperDone(parameters) { -@@ -2014,6 +2038,10 @@ class CaptivePortalHandler extends Signals.EventEmitter { - for (const item of this._connectivityQueue) - this._portalHelperProxy?.CloseAsync(item); - this._connectivityQueue.clear(); -+ -+ for (const n of this._notifications.values()) -+ n.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED); -+ this._notifications.clear(); - } - } - -@@ -2167,7 +2195,9 @@ class Indicator extends SystemIndicator { - if (!isPortal || Main.sessionMode.isGreeter) - return; - -- this._portalHandler.addConnection(this._mainConnection.get_path()); -+ this._portalHandler.addConnection( -+ this._mainConnection.get_id(), -+ this._mainConnection.get_path()); - } - - _updateIcon() { --- -2.45.2 - - -From 52b8a150dd96086a48ba2ac7668b22e6429767fd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Wed, 12 Jun 2024 13:13:41 +0200 -Subject: [PATCH 3/3] build: Add option to disable portal-helper - -The portal login window uses WebKit, which is a security-sensitive -component that not all vendors want to support. - -Support that case with a build option, and update the captive -portal handler to use the user's default browser if the portal-helper -is disabled. ---- - data/icons/meson.build | 10 +++++++++- - data/meson.build | 2 +- - js/meson.build | 14 ++++++++------ - js/misc/config.js.in | 2 ++ - js/misc/meson.build | 1 + - js/ui/status/network.js | 15 +++++++++++---- - meson.build | 5 +++++ - meson_options.txt | 6 ++++++ - src/meson.build | 2 +- - 9 files changed, 44 insertions(+), 13 deletions(-) - -diff --git a/data/icons/meson.build b/data/icons/meson.build -index eff6e4b530..277df017b2 100644 ---- a/data/icons/meson.build -+++ b/data/icons/meson.build -@@ -1 +1,9 @@ --install_subdir('hicolor', install_dir: icondir) -+excluded_icons=[] -+if not have_portal_helper -+ excluded_icons += [ -+ 'scalable/apps/org.gnome.Shell.CaptivePortal.svg', -+ 'symbolic/apps/org.gnome.Shell.CaptivePortal-symbolic.svg', -+ ] -+endif -+install_subdir('hicolor', -+ install_dir: icondir, exclude_files: excluded_icons) -diff --git a/data/meson.build b/data/meson.build -index 8654dfeca7..ed13b6baea 100644 ---- a/data/meson.build -+++ b/data/meson.build -@@ -6,7 +6,7 @@ desktop_files = [ - ] - service_files = [] - --if have_networkmanager -+if have_portal_helper - desktop_files += 'org.gnome.Shell.PortalHelper.desktop' - service_files += 'org.gnome.Shell.PortalHelper.service' - endif -diff --git a/js/meson.build b/js/meson.build -index 4809f82b83..e594e23627 100644 ---- a/js/meson.build -+++ b/js/meson.build -@@ -8,9 +8,11 @@ js_resources = gnome.compile_resources( - dependencies: [config_js] - ) - --portal_resources = gnome.compile_resources( -- 'portal-resources', 'portal-resources.gresource.xml', -- source_dir: ['.', meson.current_build_dir()], -- c_name: 'portal_js_resources', -- dependencies: [config_js] --) -+if have_portal_helper -+ portal_resources = gnome.compile_resources( -+ 'portal-resources', 'portal-resources.gresource.xml', -+ source_dir: ['.', meson.current_build_dir()], -+ c_name: 'portal_js_resources', -+ dependencies: [config_js] -+ ) -+endif -diff --git a/js/misc/config.js.in b/js/misc/config.js.in -index ad8d46d841..ce319e0f84 100644 ---- a/js/misc/config.js.in -+++ b/js/misc/config.js.in -@@ -7,6 +7,8 @@ export const PACKAGE_NAME = '@PACKAGE_NAME@'; - export const PACKAGE_VERSION = '@PACKAGE_VERSION@'; - /* 1 if networkmanager is available, 0 otherwise */ - export const HAVE_NETWORKMANAGER = @HAVE_NETWORKMANAGER@; -+/* 1 if portal helper is enabled, 0 otherwise */ -+export const HAVE_PORTAL_HELPER = @HAVE_PORTAL_HELPER@; - /* gettext package */ - export const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@'; - /* locale dir */ -diff --git a/js/misc/meson.build b/js/misc/meson.build -index 5aceefac42..5fc8ca433f 100644 ---- a/js/misc/meson.build -+++ b/js/misc/meson.build -@@ -4,6 +4,7 @@ jsconf.set('PACKAGE_VERSION', meson.project_version()) - jsconf.set('GETTEXT_PACKAGE', meson.project_name()) - jsconf.set('LIBMUTTER_API_VERSION', mutter_api_version) - jsconf.set10('HAVE_NETWORKMANAGER', have_networkmanager) -+jsconf.set10('HAVE_PORTAL_HELPER', have_portal_helper) - jsconf.set('datadir', datadir) - jsconf.set('libexecdir', libexecdir) - -diff --git a/js/ui/status/network.js b/js/ui/status/network.js -index 5d1e168fb5..cdc9ba8928 100644 ---- a/js/ui/status/network.js -+++ b/js/ui/status/network.js -@@ -10,6 +10,7 @@ import Polkit from 'gi://Polkit'; - import Shell from 'gi://Shell'; - import St from 'gi://St'; - -+import * as Config from '../../misc/config.js'; - import * as Main from '../main.js'; - import * as PopupMenu from '../popupMenu.js'; - import * as MessageTray from '../messageTray.js'; -@@ -1967,7 +1968,7 @@ class CaptivePortalHandler extends Signals.EventEmitter { - source, - }); - notification.connect('activated', -- () => this._onNotificationActivated(path).catch(logError)); -+ () => this._onNotificationActivated(path)); - notification.connect('destroy', - () => this._notifications.delete(path)); - this._notifications.set(path, notification); -@@ -1984,7 +1985,13 @@ class CaptivePortalHandler extends Signals.EventEmitter { - } - - _onNotificationActivated(path) { -- this._launchPortalHelper(path).catch(logError); -+ const context = global.create_app_launch_context( -+ global.get_current_time(), -1); -+ -+ if (Config.HAVE_PORTAL_HELPER) -+ this._launchPortalHelper(path, context).catch(logError); -+ else -+ Gio.AppInfo.launch_default_for_uri(this._checkUri, context); - - Main.overview.hide(); - Main.panel.closeCalendar(); -@@ -2007,8 +2014,7 @@ class CaptivePortalHandler extends Signals.EventEmitter { - } - } - -- async _launchPortalHelper(path) { -- const timestamp = global.get_current_time(); -+ async _launchPortalHelper(path, context) { - if (!this._portalHelperProxy) { - this._portalHelperProxy = new Gio.DBusProxy({ - g_connection: Gio.DBus.session, -@@ -2030,6 +2036,7 @@ class CaptivePortalHandler extends Signals.EventEmitter { - } - } - -+ const {timestamp} = context; - this._portalHelperProxy?.AuthenticateAsync(path, this._checkUri, timestamp).catch(logError); - this._connectivityQueue.add(path); - } -diff --git a/meson.build b/meson.build -index 035f54732a..4721bd6017 100644 ---- a/meson.build -+++ b/meson.build -@@ -107,6 +107,11 @@ else - have_networkmanager = false - endif - -+have_portal_helper = get_option('portal_helper') -+if have_portal_helper and not have_networkmanager -+ error('Portal helper requires networkmanager support') -+endif -+ - if get_option('camera_monitor') - libpipewire_dep = dependency('libpipewire-0.3', version: pipewire_req) - have_pipewire = true -diff --git a/meson_options.txt b/meson_options.txt -index 6e83d92f2e..01e0d5803b 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -40,6 +40,12 @@ option('networkmanager', - description: 'Enable NetworkManager support' - ) - -+option('portal_helper', -+ type: 'boolean', -+ value: true, -+ description: 'Enable build-in network portal login' -+) -+ - option('systemd', - type: 'boolean', - value: true, -diff --git a/src/meson.build b/src/meson.build -index 752104e120..a3bf542480 100644 ---- a/src/meson.build -+++ b/src/meson.build -@@ -286,7 +286,7 @@ executable('gnome-shell', 'main.c', - install: true - ) - --if have_networkmanager -+if have_portal_helper - executable('gnome-shell-portal-helper', - 'gnome-shell-portal-helper.c', portal_resources, - c_args: tools_cflags, --- -2.45.2 - diff --git a/sources b/sources index ccc9297..72aedb5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-shell-47.alpha.tar.xz) = 72fbd6be1115f7130a0eefaef526181e5bef1a26ef815f4c005606a77e0c50e001e76db588abcea625dccf0eec455e54f88afed76f60e134a3172106790d87fc +SHA512 (gnome-shell-47.rc.tar.xz) = 409e6151db35feea9c99b384c835378b5967de4777c48d493fa8568ad7ab3ea72ef3946287add2d160a408553693928f0c2a87d5e520a4bca5fc81588929b4e2