diff --git a/SOURCES/0001-shell-window-tracker-Help-mutter-finding-app-info-s-.patch b/SOURCES/0001-shell-window-tracker-Help-mutter-finding-app-info-s-.patch new file mode 100644 index 0000000..4a9992f --- /dev/null +++ b/SOURCES/0001-shell-window-tracker-Help-mutter-finding-app-info-s-.patch @@ -0,0 +1,56 @@ +From b1be295de28f45762a525d3ad3f91729295a7511 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Fri, 18 Oct 2024 13:20:23 +0200 +Subject: [PATCH] shell/window-tracker: Help mutter finding app info's for + windows + +--- + src/shell-window-tracker.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/src/shell-window-tracker.c b/src/shell-window-tracker.c +index bc14040d9b..8fbcca4269 100644 +--- a/src/shell-window-tracker.c ++++ b/src/shell-window-tracker.c +@@ -651,6 +651,20 @@ shell_window_tracker_on_n_workspaces_changed (MetaWorkspaceManager *workspace_ma + } + } + ++static GAppInfo * ++on_find_app_info (MetaDisplay *display, ++ MetaWindow *window, ++ ShellWindowTracker *tracker) ++{ ++ g_autoptr (ShellApp) app = NULL; ++ ++ app = get_app_for_window (tracker, window); ++ if (!app) ++ return NULL; ++ ++ return g_object_ref (G_APP_INFO (shell_app_get_app_info (app))); ++} ++ + static void + init_window_tracking (ShellWindowTracker *self) + { +@@ -665,6 +679,17 @@ init_window_tracking (ShellWindowTracker *self) + g_signal_connect(display, "window-created", + G_CALLBACK (on_window_created), self); + ++ if (g_signal_lookup ("find-app-info", META_TYPE_DISPLAY)) ++ { ++ g_debug ("Mutter app finding with the help of gnome-shell"); ++ g_signal_connect (display, "find-app-info", ++ G_CALLBACK (on_find_app_info), self); ++ } ++ else ++ { ++ g_debug ("No mutter app finding with the help of gnome-shell"); ++ } ++ + shell_window_tracker_on_n_workspaces_changed (workspace_manager, NULL, self); + } + +-- +2.44.0.501.g19981daefd.dirty + diff --git a/SOURCES/fix-inhibit-shortcut-permission.patch b/SOURCES/fix-inhibit-shortcut-permission.patch new file mode 100644 index 0000000..d20d91b --- /dev/null +++ b/SOURCES/fix-inhibit-shortcut-permission.patch @@ -0,0 +1,107 @@ +From 3a89e8597f6f3e7fa468bae93768f8253a3141e7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 6 Oct 2022 14:30:20 +0200 +Subject: [PATCH 1/2] inhibitShortcutsDialog: Don't override resource + +PermissionStore's Set() method takes a complete permission +table, so when setting an app's permission, we are implicitly +removing all previously set entries for other apps. + +Switch to the SetPermission() method which sets the permission +for a single app. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5937 + +Part-of: + +--- + ...g.freedesktop.impl.portal.PermissionStore.xml | 7 +++++++ + js/ui/inhibitShortcutsDialog.js | 16 ++++++---------- + 2 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/data/dbus-interfaces/org.freedesktop.impl.portal.PermissionStore.xml b/data/dbus-interfaces/org.freedesktop.impl.portal.PermissionStore.xml +index 75fbc468a8..55d3fc30cb 100644 +--- a/data/dbus-interfaces/org.freedesktop.impl.portal.PermissionStore.xml ++++ b/data/dbus-interfaces/org.freedesktop.impl.portal.PermissionStore.xml +@@ -13,6 +13,13 @@ + + + ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/js/ui/inhibitShortcutsDialog.js b/js/ui/inhibitShortcutsDialog.js +index c59544eaf9..8ef5861261 100644 +--- a/js/ui/inhibitShortcutsDialog.js ++++ b/js/ui/inhibitShortcutsDialog.js +@@ -1,5 +1,5 @@ + /* exported InhibitShortcutsDialog */ +-const { Clutter, Gio, GLib, GObject, Gtk, Meta, Pango, Shell, St } = imports.gi; ++const {Clutter, Gio, GObject, Gtk, Meta, Pango, Shell, St} = imports.gi; + + const Dialog = imports.ui.dialog; + const ModalDialog = imports.ui.modalDialog; +@@ -57,15 +57,11 @@ var InhibitShortcutsDialog = GObject.registerClass({ + if (!this._shouldUsePermStore() || this._permStore == null) + return; + +- let permissions = {}; +- permissions[this._app.get_id()] = [grant]; +- let data = GLib.Variant.new('av', {}); +- +- this._permStore.SetRemote(APP_PERMISSIONS_TABLE, +- true, +- APP_PERMISSIONS_ID, +- permissions, +- data, ++ this._permStore.SetPermissionRemote(APP_PERMISSIONS_TABLE, ++ true, ++ APP_PERMISSIONS_ID, ++ this._app.get_id(), ++ [grant], + (result, error) => { + if (error != null) + log(error.message); +-- +2.43.0 + + +From 1391efb2356d1b1eac631df2f5fbd61a7a72bf52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 18 Nov 2022 22:40:31 +0100 +Subject: [PATCH 2/2] inhibitShorcutsDialog: Fix permission check + +Each permission entry is an array of strings, so checking that against +the expected string itself will always fail. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6107 + +Part-of: + +--- + js/ui/inhibitShortcutsDialog.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/ui/inhibitShortcutsDialog.js b/js/ui/inhibitShortcutsDialog.js +index 8ef5861261..4cd2793c3d 100644 +--- a/js/ui/inhibitShortcutsDialog.js ++++ b/js/ui/inhibitShortcutsDialog.js +@@ -145,7 +145,7 @@ var InhibitShortcutsDialog = GObject.registerClass({ + let [permissions] = res; + if (permissions[appId] === undefined) // Not found + this._dialog.open(); +- else if (permissions[appId] == GRANTED) ++ else if (permissions[appId][0] === GRANTED) + this._emitResponse(DialogResponse.ALLOW); + else + this._emitResponse(DialogResponse.DENY); +-- +2.43.0 + diff --git a/SOURCES/optional-portal-helper.patch b/SOURCES/optional-portal-helper.patch deleted file mode 100644 index 956562b..0000000 --- a/SOURCES/optional-portal-helper.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff --git a/js/portalHelper/main.js b/js/portalHelper/main.js -index 25f866281..a221c3b88 100644 ---- a/js/portalHelper/main.js -+++ b/js/portalHelper/main.js -@@ -4,10 +4,17 @@ imports.gi.versions.Soup = '2.4'; - - const Format = imports.format; - const Gettext = imports.gettext; --const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi; -+const { Gio, GLib, GObject, Gtk, Pango, Soup } = imports.gi; - - const _ = Gettext.gettext; - -+let WebKit; -+try { -+ WebKit = imports.gi.WebKit2; -+} catch { -+ WebKit = null; -+} -+ - const Config = imports.misc.config; - const { loadInterfaceXML } = imports.misc.fileUtils; - -@@ -346,6 +353,11 @@ function initEnvironment() { - function main(argv) { - initEnvironment(); - -+ if (!WebKit) { -+ log('WebKit2 typelib is not installed, captive portal helper will be disabled'); -+ return 1; -+ } -+ - if (!WebKit.WebContext.new_ephemeral) { - log('WebKitGTK 2.16 is required for the portal-helper, see https://bugzilla.gnome.org/show_bug.cgi?id=780453'); - return 1; -diff --git a/js/ui/status/network.js b/js/ui/status/network.js -index 01c83c86b..8c5bd8dcb 100644 ---- a/js/ui/status/network.js -+++ b/js/ui/status/network.js -@@ -2070,7 +2070,9 @@ class Indicator extends PanelMenu.SystemIndicator { - new PortalHelperProxy(Gio.DBus.session, 'org.gnome.Shell.PortalHelper', - '/org/gnome/Shell/PortalHelper', (proxy, error) => { - if (error) { -- log('Error launching the portal helper: %s'.format(error)); -+ // Timeout is expected if WebKit is unavailable -+ if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.TIMED_OUT)) -+ log('Error launching the portal helper: ' + error); - return; - } - - diff --git a/SOURCES/portal-notify.patch b/SOURCES/portal-notify.patch new file mode 100644 index 0000000..0b1028c --- /dev/null +++ b/SOURCES/portal-notify.patch @@ -0,0 +1,499 @@ +From 4a03da36817c8d22a32a63d5c115efcf49ce85f5 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 | 152 ++++++++++++++++++++++------------------ + 1 file changed, 84 insertions(+), 68 deletions(-) + +diff --git a/js/ui/status/network.js b/js/ui/status/network.js +index b407d8e78d..6d070f6d88 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -51,7 +51,7 @@ var PortalHelperResult = { + }; + + const PortalHelperIface = loadInterfaceXML('org.gnome.Shell.PortalHelper'); +-const PortalHelperProxy = Gio.DBusProxy.makeProxyWrapper(PortalHelperIface); ++const PortalHelperInfo = Gio.DBusInterfaceInfo.new_for_xml(PortalHelperIface); + + function signalToIcon(value) { + if (value < 20) +@@ -1707,6 +1707,77 @@ var DeviceCategory = class extends PopupMenu.PopupMenuSection { + } + }; + ++class CaptivePortalHandler { ++ constructor(checkUri) { ++ 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?.CloseRemote(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?.AuthenticateRemote(path, this._checkUri, timestamp); ++ this._connectivityQueue.add(path); ++ } ++ ++ clear() { ++ for (const item of this._connectivityQueue) ++ this._portalHelperProxy?.CloseRemote(item); ++ this._connectivityQueue.clear(); ++ } ++} ++Signals.addSignalMethods(CaptivePortalHandler.prototype); ++ + var NMApplet = GObject.registerClass( + class Indicator extends PanelMenu.SystemIndicator { + _init() { +@@ -1763,6 +1834,16 @@ class Indicator extends PanelMenu.SystemIndicator { + this._vpnSection.connect('icon-changed', this._updateIcon.bind(this)); + this.menu.addMenuItem(this._vpnSection.item); + ++ 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._readConnections(); + this._readDevices(); + this._syncNMState(); +@@ -2074,51 +2155,10 @@ class Indicator extends PanelMenu.SystemIndicator { + this._syncConnectivity(); + } + +- _flushConnectivityQueue() { +- if (this._portalHelperProxy) { +- for (let item of this._connectivityQueue) +- this._portalHelperProxy.CloseRemote(item); +- } +- +- this._connectivityQueue = []; +- } +- +- _closeConnectivityCheck(path) { +- let index = this._connectivityQueue.indexOf(path); +- +- if (index >= 0) { +- if (this._portalHelperProxy) +- this._portalHelperProxy.CloseRemote(path); +- +- this._connectivityQueue.splice(index, 1); +- } +- } +- +- async _portalHelperDone(proxy, emitter, 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 he chooses 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: %s'.format(result)); +- } +- } +- + _syncConnectivity() { + if (this._mainConnection == null || + this._mainConnection.state != NM.ActiveConnectionState.ACTIVATED) { +- this._flushConnectivityQueue(); ++ this._portalHandler.clear(); + return; + } + +@@ -2133,31 +2173,7 @@ class Indicator extends PanelMenu.SystemIndicator { + if (!isPortal || Main.sessionMode.isGreeter) + return; + +- let path = this._mainConnection.get_path(); +- for (let item of this._connectivityQueue) { +- if (item == path) +- return; +- } +- +- let timestamp = global.get_current_time(); +- if (this._portalHelperProxy) { +- this._portalHelperProxy.AuthenticateRemote(path, '', timestamp); +- } else { +- new PortalHelperProxy(Gio.DBus.session, 'org.gnome.Shell.PortalHelper', +- '/org/gnome/Shell/PortalHelper', (proxy, error) => { +- if (error) { +- log('Error launching the portal helper: %s'.format(error)); +- return; +- } +- +- this._portalHelperProxy = proxy; +- proxy.connectSignal('Done', this._portalHelperDone.bind(this)); +- +- proxy.AuthenticateRemote(path, '', timestamp); +- }); +- } +- +- this._connectivityQueue.push(path); ++ this._portalHandler.addConnection(this._mainConnection.get_path()); + } + + _updateIcon() { +-- +2.45.2 + + +From 7d1a2442c957df3a31ab544da9b4e1365b8c2348 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 6d070f6d88..5913467454 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -1711,19 +1711,43 @@ class CaptivePortalHandler { + constructor(checkUri) { + 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.Source( ++ _('System'), ++ 'emblem-system-symbolic'); ++ Main.messageTray.add(source); ++ ++ const notification = new MessageTray.Notification( ++ source, _('Sign Into Wi–Fi Network'), name); ++ notification.connect('activated', ++ () => this._onNotificationActivated(path)); ++ notification.connect('destroy', ++ () => this._notifications.delete(path)); ++ this._notifications.set(path, notification); ++ source.showNotification(notification); + } + ++ + removeConnection(path) { + if (this._connectivityQueue.delete(path)) + this._portalHelperProxy?.CloseRemote(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) { +@@ -1774,6 +1798,10 @@ class CaptivePortalHandler { + for (const item of this._connectivityQueue) + this._portalHelperProxy?.CloseRemote(item); + this._connectivityQueue.clear(); ++ ++ for (const n of this._notifications.values()) ++ n.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED); ++ this._notifications.clear(); + } + } + Signals.addSignalMethods(CaptivePortalHandler.prototype); +@@ -2173,7 +2201,9 @@ class Indicator extends PanelMenu.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 cda2810d13bb9b5294759a8268cfbb27d83190f1 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 | 13 ++++++++++--- + meson.build | 5 +++++ + meson_options.txt | 6 ++++++ + src/meson.build | 2 +- + 9 files changed, 43 insertions(+), 12 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 4a1e16d467..01cf828310 100644 +--- a/data/meson.build ++++ b/data/meson.build +@@ -4,7 +4,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 e54e280441..0882af6d01 100644 +--- a/js/misc/config.js.in ++++ b/js/misc/config.js.in +@@ -8,6 +8,8 @@ var PACKAGE_VERSION = '@PACKAGE_VERSION@'; + var HAVE_BLUETOOTH = @HAVE_BLUETOOTH@; + /* 1 if networkmanager is available, 0 otherwise */ + var HAVE_NETWORKMANAGER = @HAVE_NETWORKMANAGER@; ++/* 1 if portal helper is enabled, 0 otherwise */ ++var HAVE_PORTAL_HELPER = @HAVE_PORTAL_HELPER@; + /* gettext package */ + var GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@'; + /* locale dir */ +diff --git a/js/misc/meson.build b/js/misc/meson.build +index 2702c3dbc9..5f5f6c390f 100644 +--- a/js/misc/meson.build ++++ b/js/misc/meson.build +@@ -5,6 +5,7 @@ jsconf.set('GETTEXT_PACKAGE', meson.project_name()) + jsconf.set('LIBMUTTER_API_VERSION', mutter_api_version) + jsconf.set10('HAVE_BLUETOOTH', bt_dep.found()) + 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 5913467454..27a5eeb823 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -4,6 +4,7 @@ const { Clutter, Gio, GLib, GObject, Meta, NM, Polkit, St } = imports.gi; + const Signals = imports.signals; + + const Animation = imports.ui.animation; ++const Config = imports.misc.config; + const Main = imports.ui.main; + const PanelMenu = imports.ui.panelMenu; + const PopupMenu = imports.ui.popupMenu; +@@ -1744,7 +1745,13 @@ class CaptivePortalHandler { + } + + _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(); +@@ -1767,8 +1774,7 @@ class CaptivePortalHandler { + } + } + +- 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, +@@ -1790,6 +1796,7 @@ class CaptivePortalHandler { + } + } + ++ const {timestamp} = context; + this._portalHelperProxy?.AuthenticateRemote(path, this._checkUri, timestamp); + this._connectivityQueue.add(path); + } +diff --git a/meson.build b/meson.build +index ff841dccf2..8feac29224 100644 +--- a/meson.build ++++ b/meson.build +@@ -116,6 +116,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('systemd') + libsystemd_dep = dependency('libsystemd') + systemd_dep = dependency('systemd') +diff --git a/meson_options.txt b/meson_options.txt +index ef76b73c34..7666fc5421 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -28,6 +28,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 d235c37438..3e1accf2e7 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -250,7 +250,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/screencast-bus-name.patch b/SOURCES/screencast-bus-name.patch new file mode 100644 index 0000000..323ca60 --- /dev/null +++ b/SOURCES/screencast-bus-name.patch @@ -0,0 +1,34 @@ +From b8ae8f713a15b00ec447a23294948fc463220130 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Mon, 6 May 2024 21:58:09 +0100 +Subject: [PATCH] screencast: Correct expected bus name for streams +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously, this only worked because GDBusConnection was not filtering +signals by their sender correctly (GNOME/glib#3268). + +Thanks: Alicia Boya García +Signed-off-by: Simon McVittie +Part-of: +--- + js/dbusServices/screencast/screencastService.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/dbusServices/screencast/screencastService.js b/js/dbusServices/screencast/screencastService.js +index 708a15c84..0321b4d69 100644 +--- a/js/dbusServices/screencast/screencastService.js ++++ b/js/dbusServices/screencast/screencastService.js +@@ -161,7 +161,7 @@ var Recorder = class { + }); + + this._streamProxy = new ScreenCastStreamProxy(Gio.DBus.session, +- 'org.gnome.ScreenCast.Stream', ++ 'org.gnome.Mutter.ScreenCast', + streamPath); + + this._streamProxy.connectSignal('PipeWireStreamAdded', +-- +2.45.0 + diff --git a/SPECS/gnome-shell.spec b/SPECS/gnome-shell.spec index 131897f..417a557 100644 --- a/SPECS/gnome-shell.spec +++ b/SPECS/gnome-shell.spec @@ -1,8 +1,14 @@ %global tarball_version %%(echo %{version} | tr '~' '.') +%if 0%{?rhel} +%global portal_helper 0 +%else +%global portal_helper 1 +%endif + Name: gnome-shell Version: 40.10 -Release: 18%{?dist} +Release: 22%{?dist} Summary: Window management and application launching for GNOME License: GPLv2+ @@ -58,9 +64,12 @@ Patch54: 0001-st-icon-Only-get-resource-scale-after-peeking-theme-.patch Patch55: 0001-window-tracker-Only-emit-tracked-windows-changed-on-.patch Patch56: owe-support.patch Patch57: 0001-windowMenu-Ignore-release.patch -Patch58: optional-portal-helper.patch +Patch58: portal-notify.patch Patch59: 0001-extensionSystem-Support-locking-down-extension-insta.patch Patch60: 0001-windowPreview-Override-with-window-icon-if-available.patch +Patch61: screencast-bus-name.patch +Patch62: fix-inhibit-shortcut-permission.patch +Patch63: 0001-shell-window-tracker-Help-mutter-finding-app-info-s-.patch %define eds_version 3.33.1 %define gnome_desktop_version 3.35.91 @@ -207,7 +216,14 @@ easy to use experience. %autosetup -S git -n %{name}-%{tarball_version} %build -%meson -Dextensions_app=false +%meson \ + -Dextensions_app=false \ +%if %{portal_helper} + -Dportal_helper=true \ +%else + -Dportal_helper=false \ +%endif + %{nil} %meson_build %install @@ -236,7 +252,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_datadir}/applications/org.gnome.Shell.Extensions.desktop %{_datadir}/applications/org.gnome.Shell.desktop %{_datadir}/applications/evolution-calendar.desktop -%{_datadir}/applications/org.gnome.Shell.PortalHelper.desktop %{_datadir}/bash-completion/completions/gnome-extensions %{_datadir}/gnome-control-center/keybindings/50-gnome-shell-system.xml %{_datadir}/gnome-shell/ @@ -245,7 +260,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_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.Notifications.service -%{_datadir}/dbus-1/services/org.gnome.Shell.PortalHelper.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.Introspect.xml @@ -269,7 +283,6 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_libexecdir}/gnome-shell-calendar-server %{_libexecdir}/gnome-shell-perf-helper %{_libexecdir}/gnome-shell-hotplug-sniffer -%{_libexecdir}/gnome-shell-portal-helper %{_libexecdir}/gnome-shell-overrides-migration.sh # Co own these directories instead of pulling in GConf # after all, we are trying to get rid of GConf with these files @@ -279,7 +292,29 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_mandir}/man1/gnome-extensions.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 +%{_libexecdir}/gnome-shell-portal-helper +%endif + %changelog +* Fri Oct 18 2024 Jonas Ådahl - 40.10-22 +- Help mutter finding app info for windows + Resolves: RHEL-63000 + +* Wed Jul 10 2024 Florian Müllner - 40.10-21 +- Only open portal login in response to user action + Resolves: RHEL-39098 + +* Wed May 15 2024 Florian Müllner - 40.10-20 +- Fix inhibit-shortcut permissions + Resolves: #RHEL-2031 + +* Wed May 15 2024 Michael Catanzaro - 40.10-19 +- Use correct bus name for screencast service + Related: RHEL-35775 + * Tue Mar 19 2024 Florian Müllner - 40.10-18 - Use window icon in overview if available Resolves: RHEL-24713