Only open captive portal login in response to user action
This also adds a `portal_helper` build option that supersedes the downstream patch to make WebKit optional. Resolves: https://issues.redhat.com/browse/RHEL-46629
This commit is contained in:
parent
fe424db921
commit
4a276ed986
@ -1,6 +1,12 @@
|
|||||||
%global tarball_version %%(echo %{version} | tr '~' '.')
|
%global tarball_version %%(echo %{version} | tr '~' '.')
|
||||||
%global major_version %%(cut -d "." -f 1 <<<%{tarball_version})
|
%global major_version %%(cut -d "." -f 1 <<<%{tarball_version})
|
||||||
|
|
||||||
|
%if 0%{?rhel}
|
||||||
|
%global portal_helper 0
|
||||||
|
%else
|
||||||
|
%global portal_helper 1
|
||||||
|
%endif
|
||||||
|
|
||||||
Name: gnome-shell
|
Name: gnome-shell
|
||||||
Version: 46.3.1
|
Version: 46.3.1
|
||||||
Release: %autorelease
|
Release: %autorelease
|
||||||
@ -16,9 +22,6 @@ Patch: gnome-shell-favourite-apps-firefox.patch
|
|||||||
Patch: gnome-shell-favourite-apps-terminal.patch
|
Patch: gnome-shell-favourite-apps-terminal.patch
|
||||||
Patch: gnome-shell-enabled-extensions-background-logos.patch
|
Patch: gnome-shell-enabled-extensions-background-logos.patch
|
||||||
|
|
||||||
# No portal helper if WebKitGTK is not installed
|
|
||||||
Patch: optional-portal-helper.patch
|
|
||||||
|
|
||||||
# Some users might have a broken PAM config, so we really need this
|
# Some users might have a broken PAM config, so we really need this
|
||||||
# downstream patch to stop trying on configuration errors.
|
# downstream patch to stop trying on configuration errors.
|
||||||
Patch: 0001-gdm-Work-around-failing-fingerprint-auth.patch
|
Patch: 0001-gdm-Work-around-failing-fingerprint-auth.patch
|
||||||
@ -40,6 +43,7 @@ Patch: 0001-st-texture-cache-purge-on-resume.patch
|
|||||||
Patch: fix-some-js-warnings.patch
|
Patch: fix-some-js-warnings.patch
|
||||||
Patch: 0001-data-Update-generated-stylesheets.patch
|
Patch: 0001-data-Update-generated-stylesheets.patch
|
||||||
Patch: 0001-data-App-icon-for-captive-portal.patch
|
Patch: 0001-data-App-icon-for-captive-portal.patch
|
||||||
|
Patch: portal-notify.patch
|
||||||
|
|
||||||
%define eds_version 3.45.1
|
%define eds_version 3.45.1
|
||||||
%define gnome_desktop_version 44.0-7
|
%define gnome_desktop_version 44.0-7
|
||||||
@ -151,9 +155,9 @@ Requires: xdg-desktop-portal-gnome
|
|||||||
# needed by the welcome dialog
|
# needed by the welcome dialog
|
||||||
Recommends: gnome-tour
|
Recommends: gnome-tour
|
||||||
|
|
||||||
%if !0%{?rhel}
|
%if %{portal_helper}
|
||||||
# needed for captive portal helper
|
# needed for captive portal helper
|
||||||
Recommends: webkitgtk6.0%{?_isa}
|
Requires: webkitgtk6.0%{?_isa}
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# https://github.com/containers/composefs/pull/229#issuecomment-1838735764
|
# https://github.com/containers/composefs/pull/229#issuecomment-1838735764
|
||||||
@ -192,7 +196,14 @@ easy to use experience.
|
|||||||
%autosetup -S git -n %{name}-%{tarball_version}
|
%autosetup -S git -n %{name}-%{tarball_version}
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%meson -Dextensions_app=false
|
%meson \
|
||||||
|
-Dextensions_app=false \
|
||||||
|
%if %{portal_helper}
|
||||||
|
-Dportal_helper=true \
|
||||||
|
%else
|
||||||
|
-Dportal_helper=false \
|
||||||
|
%endif
|
||||||
|
%{nil}
|
||||||
%meson_build
|
%meson_build
|
||||||
|
|
||||||
%install
|
%install
|
||||||
@ -207,7 +218,10 @@ mkdir -p %{buildroot}%{_datadir}/gnome-shell/search-providers
|
|||||||
%check
|
%check
|
||||||
desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.desktop
|
desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.desktop
|
||||||
desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Extensions.desktop
|
desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Extensions.desktop
|
||||||
|
|
||||||
|
%if %{portal_helper}
|
||||||
desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.PortalHelper.desktop
|
desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.PortalHelper.desktop
|
||||||
|
%endif
|
||||||
|
|
||||||
%files -f %{name}.lang
|
%files -f %{name}.lang
|
||||||
%license COPYING
|
%license COPYING
|
||||||
@ -221,7 +235,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%{_datadir}/glib-2.0/schemas/00_org.gnome.shell.gschema.override
|
%{_datadir}/glib-2.0/schemas/00_org.gnome.shell.gschema.override
|
||||||
%{_datadir}/applications/org.gnome.Shell.Extensions.desktop
|
%{_datadir}/applications/org.gnome.Shell.Extensions.desktop
|
||||||
%{_datadir}/applications/org.gnome.Shell.desktop
|
%{_datadir}/applications/org.gnome.Shell.desktop
|
||||||
%{_datadir}/applications/org.gnome.Shell.PortalHelper.desktop
|
|
||||||
%{_datadir}/bash-completion/completions/gnome-extensions
|
%{_datadir}/bash-completion/completions/gnome-extensions
|
||||||
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-launchers.xml
|
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-launchers.xml
|
||||||
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-screenshots.xml
|
%{_datadir}/gnome-control-center/keybindings/50-gnome-shell-screenshots.xml
|
||||||
@ -232,7 +245,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%{_datadir}/dbus-1/services/org.gnome.Shell.Extensions.service
|
%{_datadir}/dbus-1/services/org.gnome.Shell.Extensions.service
|
||||||
%{_datadir}/dbus-1/services/org.gnome.Shell.HotplugSniffer.service
|
%{_datadir}/dbus-1/services/org.gnome.Shell.HotplugSniffer.service
|
||||||
%{_datadir}/dbus-1/services/org.gnome.Shell.Notifications.service
|
%{_datadir}/dbus-1/services/org.gnome.Shell.Notifications.service
|
||||||
%{_datadir}/dbus-1/services/org.gnome.Shell.PortalHelper.service
|
|
||||||
%{_datadir}/dbus-1/services/org.gnome.Shell.Screencast.service
|
%{_datadir}/dbus-1/services/org.gnome.Shell.Screencast.service
|
||||||
%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Extensions.xml
|
%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Extensions.xml
|
||||||
%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Introspect.xml
|
%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Introspect.xml
|
||||||
@ -241,9 +253,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Screenshot.xml
|
%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Screenshot.xml
|
||||||
%{_datadir}/dbus-1/interfaces/org.gnome.ShellSearchProvider.xml
|
%{_datadir}/dbus-1/interfaces/org.gnome.ShellSearchProvider.xml
|
||||||
%{_datadir}/dbus-1/interfaces/org.gnome.ShellSearchProvider2.xml
|
%{_datadir}/dbus-1/interfaces/org.gnome.ShellSearchProvider2.xml
|
||||||
%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Shell.CaptivePortal.svg
|
|
||||||
%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Shell.Extensions.svg
|
%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Shell.Extensions.svg
|
||||||
%{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Shell.CaptivePortal-symbolic.svg
|
|
||||||
%{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Shell.Extensions-symbolic.svg
|
%{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Shell.Extensions-symbolic.svg
|
||||||
%{_userunitdir}/org.gnome.Shell-disable-extensions.service
|
%{_userunitdir}/org.gnome.Shell-disable-extensions.service
|
||||||
%{_userunitdir}/org.gnome.Shell.target
|
%{_userunitdir}/org.gnome.Shell.target
|
||||||
@ -253,9 +263,16 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.Porta
|
|||||||
%{_libexecdir}/gnome-shell-calendar-server
|
%{_libexecdir}/gnome-shell-calendar-server
|
||||||
%{_libexecdir}/gnome-shell-perf-helper
|
%{_libexecdir}/gnome-shell-perf-helper
|
||||||
%{_libexecdir}/gnome-shell-hotplug-sniffer
|
%{_libexecdir}/gnome-shell-hotplug-sniffer
|
||||||
%{_libexecdir}/gnome-shell-portal-helper
|
|
||||||
%{_mandir}/man1/gnome-extensions.1*
|
%{_mandir}/man1/gnome-extensions.1*
|
||||||
%{_mandir}/man1/gnome-shell.1*
|
%{_mandir}/man1/gnome-shell.1*
|
||||||
|
|
||||||
|
%if %{portal_helper}
|
||||||
|
%{_datadir}/applications/org.gnome.Shell.PortalHelper.desktop
|
||||||
|
%{_datadir}/dbus-1/services/org.gnome.Shell.PortalHelper.service
|
||||||
|
%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Shell.CaptivePortal.svg
|
||||||
|
%{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Shell.CaptivePortal-symbolic.svg
|
||||||
|
%{_libexecdir}/gnome-shell-portal-helper
|
||||||
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
%autochangelog
|
%autochangelog
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
diff --git a/js/portalHelper/main.js b/js/portalHelper/main.js
|
|
||||||
index 7000089fa..d9a768a3f 100644
|
|
||||||
--- a/js/portalHelper/main.js
|
|
||||||
+++ b/js/portalHelper/main.js
|
|
||||||
@@ -3,7 +3,13 @@ import Gio from 'gi://Gio';
|
|
||||||
import GLib from 'gi://GLib';
|
|
||||||
import GObject from 'gi://GObject';
|
|
||||||
import Gtk from 'gi://Gtk?version=4.0';
|
|
||||||
-import WebKit from 'gi://WebKit?version=6.0';
|
|
||||||
+
|
|
||||||
+let WebKit;
|
|
||||||
+try {
|
|
||||||
+ WebKit = (await import('gi://WebKit?version=6.0')).default;
|
|
||||||
+} catch {
|
|
||||||
+ WebKit = null;
|
|
||||||
+}
|
|
||||||
|
|
||||||
import * as Gettext from 'gettext';
|
|
||||||
import {programInvocationName, programArgs} from 'system';
|
|
||||||
@@ -365,5 +371,9 @@ class WebPortalHelper extends Adw.Application {
|
|
||||||
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
|
||||||
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
|
||||||
|
|
||||||
-const app = new WebPortalHelper();
|
|
||||||
-await app.runAsync([programInvocationName, ...programArgs]);
|
|
||||||
+if (WebKit) {
|
|
||||||
+ const app = new WebPortalHelper();
|
|
||||||
+ await app.runAsync([programInvocationName, ...programArgs]);
|
|
||||||
+} else {
|
|
||||||
+ log('WebKit typelib is not installed, captive portal helper will be disabled');
|
|
||||||
+}
|
|
||||||
diff --git a/js/ui/status/network.js b/js/ui/status/network.js
|
|
||||||
index 322d7d91a..afca42e31 100644
|
|
||||||
--- a/js/ui/status/network.js
|
|
||||||
+++ b/js/ui/status/network.js
|
|
||||||
@@ -2147,7 +2147,9 @@ class Indicator extends SystemIndicator {
|
|
||||||
await this._portalHelperProxy.init_async(
|
|
||||||
GLib.PRIORITY_DEFAULT, null);
|
|
||||||
} catch (e) {
|
|
||||||
- console.error(`Error launching the portal helper: ${e.message}`);
|
|
||||||
+ // Timeout is expected if WebKit is unavailable
|
|
||||||
+ if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.TIMED_OUT))
|
|
||||||
+ console.error(`Error launching the portal helper: ${e.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
511
portal-notify.patch
Normal file
511
portal-notify.patch
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
From 9e43e0f7172b448d449764ab20dbe0540316f388 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
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 44242a1a79a4d9b0311b735d484c996584bee0e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
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..39140d0ce4 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 = new 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 b25485ef256068b53a852070bcb5fcf4c4a62875 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||||
|
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 0307613e70..8b376a6d6b 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 39140d0ce4..5832d96dc6 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 923a5228ec..d554045c5b 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -101,6 +101,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 c81bd1a42a..d4445743bd 100644
|
||||||
|
--- a/src/meson.build
|
||||||
|
+++ b/src/meson.build
|
||||||
|
@@ -258,7 +258,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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user