gnome-shell/post-changes-for-passwordless-gdm-backport.patch
Joan Torres Lopez 3a10d80b78
Add post-changes for passwordless GDM backport
These are downstream changes to reshape the backport to fit the old
gnome-shell version.

Resolves: https://redhat.atlassian.net/browse/RHEL-169914
2026-04-30 11:16:50 +02:00

2867 lines
97 KiB
Diff

From 183d2cce2a34a0d6fca990c2264bae60cdfc5de4 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Wed, 25 Mar 2026 18:58:29 +0100
Subject: [PATCH 01/30] gdm: Update styles from login-lock to login-dialog
login-lock is used in newer versions, but in this version login-dialog
is used.
---
data/theme/gnome-shell-sass/_widgets.scss | 1 +
.../widgets/_login-dialog.scss | 307 +++++++++++++++++-
.../gnome-shell-sass/widgets/_qr-code.scss | 4 +-
3 files changed, 296 insertions(+), 16 deletions(-)
diff --git a/data/theme/gnome-shell-sass/_widgets.scss b/data/theme/gnome-shell-sass/_widgets.scss
index a8d0aa9f4d..1651d9ca3b 100644
--- a/data/theme/gnome-shell-sass/_widgets.scss
+++ b/data/theme/gnome-shell-sass/_widgets.scss
@@ -46,6 +46,7 @@
@import 'widgets/tiled-previews';
@import 'widgets/keyboard';
@import 'widgets/looking-glass';
+@import 'widgets/qr-code';
// Lock / login screens
@import 'widgets/login-dialog';
@import 'widgets/screen-shield';
diff --git a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss
index 307a751628..f3aeed4bf3 100644
--- a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss
+++ b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss
@@ -1,5 +1,7 @@
/* Login Dialog */
+$_gdm_fg: $osd_fg_color;
+
.login-dialog-banner-view {
padding-top: 24px;
max-width: 23em;
@@ -70,8 +72,10 @@
}
}
+ .next-button,
.cancel-button,
.switch-user-button,
+ .login-dialog-auth-menu-button,
.login-dialog-session-list-button {
padding: 0;
border-radius: 99px;
@@ -83,10 +87,40 @@
StIcon { icon-size: $base_icon_size; }
}
+ .next-button {
+ background-color: transparent !important;
+ }
+
+ .switch-user-button {
+ min-width: 8.5em;
+ min-height: 2.5em;
+ @include fontsize($base_font_size - 1);
+ font-weight: bold;
+ }
+
.caps-lock-warning-label,
.login-dialog-message-warning {
color: $osd_fg_color;
}
+
+ .login-dialog-prompt-layout {
+ &.web-login-active {
+ width: 23em * 1.5;
+ }
+ }
+
+ .login-dialog-prompt-entry-area {
+ margin: 0.5em $base_margin * 5;
+ }
+
+ .login-dialog-prompt-entry {
+ border-radius: $base_border_radius * 1.5;
+ padding-right: 2.5em; // Make room for button-well inside entry
+ }
+
+ .login-dialog-default-button-well {
+ margin-right: 0.4em;
+ }
}
.login-dialog-bottom-button-group {
@@ -118,30 +152,185 @@
padding-top: 1em;
}
-.login-dialog-auth-list-view { -st-vfade-offset: 1em; }
+.login-dialog-auth-menu-button-popup {
+ padding: $base_padding * 3;
+ margin-right: $base_padding * 2;
+
+ .login-dialog-auth-menu-item-section {
+ padding-top: $base_padding;
+
+ &:first-child {
+ padding-top: 0;
+ }
+
+ &-label {
+ @include fontsize($base_font_size - 1);
+ font-weight: bold;
+ color: $_gdm_fg;
+ }
+ }
+
+ .login-dialog-auth-menu-item-icon {
+ color: $_gdm_fg;
+ icon-size: $base_icon_size;
+ margin-right: $base_margin * 2;
+ }
+
+ .login-dialog-auth-menu-item-box {
+ spacing: $base_padding * .5;
+
+ &-name {
+ color: $_gdm_fg;
+ @include fontsize($base_font_size);
+ font-weight: bold;
+ }
+
+ &-description {
+ color: $_gdm_fg;
+ @include fontsize($base_font_size - 1);
+ }
+ }
+}
+
+.login-dialog-auth-menu-button-indicator {
+ background-color: transparent !important;
+ border-width: 0;
+ margin-bottom: 32px;
+ margin-left: 32px;
+
+ .login-dialog-auth-menu-button-indicator-icons {
+ spacing: $base_padding * 3;
+
+ .login-dialog-auth-menu-button-indicator-icon {
+ icon-size: 2em;
+ }
+ }
+
+ .login-dialog-auth-menu-button-indicator-description {
+ @include fontsize($base_font_size);
+ margin-left: $base_padding * 2;
+ min-width: 20em;
+ }
+}
+
+.login-dialog-button-box {
+ height: 4em;
+}
+
+.login-dialog-auth-list-view {
+ -st-vfade-offset: 1em;
+ max-height: 13em;
+}
+
.login-dialog-auth-list {
- spacing: 6px;
- margin-left: 2em;
+ spacing: $base_padding * 1.5;
+ width: 23em;
+ margin-left: $base_margin * 5;
}
-.login-dialog-auth-list-title {
- margin-left: 2em;
+.login-dialog {
+ .login-dialog-auth-list-title,
+ .login-dialog-auth-list-item {
+ border-radius: $base_border_radius * 1.5;
+ color: darken($_gdm_fg, 30%);
+ &:focus, &:selected { background-color: $selected_bg_color; color: $selected_fg_color; }
+ }
+
+ .login-dialog-auth-list-title {
+ background-color: transparentize($_gdm_fg, .97) !important;
+ color: $_gdm_fg !important;
+ padding: $base_padding;
+ margin: 0.5em $base_margin * 5;
+ }
+
+ .login-dialog-auth-list-item {
+ min-height: 3em;
+ padding: $base_padding * 1.5;
+ margin-bottom: $base_margin;
+ background-color: transparentize($_gdm_fg, .94);
+ }
}
-.login-dialog-auth-list-item {
- border-radius: $base_border_radius + 4px;
- padding: 6px;
- color: darken($osd_fg_color,30%);
- &:focus, &:selected { background-color: $selected_bg_color; color: $selected_fg_color; }
+.unlock-dialog {
+ .login-dialog-auth-list-item {
+ border: none;
+ color: $osd_fg_color;
+ background-color: transparentize($osd_fg_color, 0.94);
+ &:hover, &:focus, &:selected { background-color: transparentize($osd_fg_color, 0.84); }
+ &:active { background-color: transparentize($osd_fg_color, 0.78); }
+ border-radius: $base_border_radius * 1.5;
+ min-height: 3em;
+ padding: $base_padding * 1.5;
+ margin-bottom: $base_margin;
+ }
+
+ .login-dialog-auth-list-title {
+ background-color: transparent !important;
+ border: none;
+ color: $osd_fg_color !important;
+ padding: $base_padding;
+ }
}
-.login-dialog-auth-list-label {
+.login-dialog-auth-list-title-label {
@include fontsize($base_font_size + 2);
font-weight: bold;
- padding-left: 15px;
+ padding: $base_padding;
+ text-align: center;
+}
- &:ltr { padding-left: 14px; text-align: left; }
- &:rtl { padding-right: 14px; text-align: right; }
+.login-dialog-auth-list-item-title,
+.login-dialog-auth-list-item-subtitle {
+ @include fontsize($base_font_size);
+ text-align: center;
+ padding: $base_padding * 0.3 0;
+}
+
+.login-dialog-auth-list-item-title {
+ color: $_gdm_fg;
+ font-weight: bold;
+}
+
+.login-dialog-auth-list-item-subtitle {
+ color: darken($_gdm_fg, 20%);
+ font-weight: 500;
+}
+
+.login-dialog-item-icon {
+ width: 1.3em;
+ height: 1.3em;
+ color: $_gdm_fg;
+ padding: $base_padding * 0.7 $base_padding;
+ border-radius: $base_border_radius;
+
+ &:hover {
+ background-color: $system_bg_color;
+ }
+
+ &-popup {
+ &.popup-menu {
+ min-width: 0;
+ }
+
+ &-box {
+ padding: $base_padding 0;
+ }
+
+ &-box &-labels {
+ spacing: $base_padding * 0.5;
+ font-weight: bold;
+ text-align: center;
+
+ & > :first-child {
+ color: darken($fg_color, 30%);
+ font-weight: 500;
+ }
+
+ & > :last-child {
+ color: $fg_color;
+ }
+ }
+ }
}
.login-dialog-user-list-view { -st-vfade-offset: 1em; }
@@ -207,3 +396,93 @@
@include fontsize($base_font_size + 1);
padding-top: 1em;
}
+
+.web-login-spinner {
+ background-color: rgba(0, 0, 0, 0.5);
+ border: 5px rgba(0, 0, 0, 0.0);
+ border-radius: 50px;
+}
+
+.web-login-title-label {
+ @include fontsize($base_font_size);
+ color: darken($_gdm_fg,30%);
+ text-align: center;
+}
+
+.web-login-url-label {
+ @include fontsize($base_font_size);
+ font-family: monospace;
+ color: $_gdm_fg;
+ text-align: center;
+
+ &.web-login-url-label-long {
+ @include fontsize($base_font_size - 2);
+ }
+}
+
+.web-login-code-title-label {
+ @include fontsize($base_font_size);
+ color: $_gdm_fg;
+ text-align: center;
+}
+
+.web-login-code-label {
+ @include fontsize($base_font_size);
+ color: $_gdm_fg;
+ font-weight: bold;
+ text-align: center;
+}
+
+.web-login-prompt {
+ padding-top: $base_padding;
+ padding-bottom: $base_padding;
+ padding-left: $base_padding * 4.5;
+ padding-right: $base_padding * 4.5;
+ spacing: 1.75em;
+}
+
+.web-login-button-label {
+ @include fontsize($base_font_size + 2);
+ color: $_gdm_fg;
+ min-width: 12em;
+ text-align: center;
+ font-weight: bold;
+ padding-bottom: 0.1em;
+}
+
+.login-dialog,
+.unlock-dialog {
+ .web-login-intro-button,
+ .web-login-prompt-button {
+ border-radius: $base_border_radius * 4 !important;
+ padding: $base_padding * 1.5 $base_padding * 3;
+ background-color: transparentize($_gdm_fg, .94);
+ }
+
+ .web-login-intro-button {
+ width: 10em;
+ }
+
+ .web-login-prompt-button {
+ width: 7em;
+ margin: $base_margin * 6 $base_margin * 2;
+ }
+}
+
+.login-dialog {
+ .web-login-intro-button,
+ .web-login-prompt-button {
+ &:hover, &:focus {
+ background-color: $selected_bg_color;
+ }
+ }
+}
+
+.unlock-dialog {
+ .web-login-intro-button,
+ .web-login-prompt-button {
+ &:hover, &:focus {
+ background-color: transparentize($osd_fg_color, .84);
+ }
+ }
+}
diff --git a/data/theme/gnome-shell-sass/widgets/_qr-code.scss b/data/theme/gnome-shell-sass/widgets/_qr-code.scss
index da04425bd6..0d733453f2 100644
--- a/data/theme/gnome-shell-sass/widgets/_qr-code.scss
+++ b/data/theme/gnome-shell-sass/widgets/_qr-code.scss
@@ -7,8 +7,8 @@
background-color: $qrcode_bg_color;
border-color: $qrcode_bg_color;
} @else {
- background-color: $system_fg_color;
- border-color: $system_fg_color;
+ background-color: $osd_fg_color;
+ border-color: $osd_fg_color;
color: $system_bg_color;
}
}
--
2.51.0
From a6a9baab3e92e3adb9172227051e83c4d145e1df Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 14:52:58 +0100
Subject: [PATCH 02/30] gdm: Fix importing using the old gjs style
---
js/gdm/authMenuButton.js | 13 +++++--------
js/gdm/authServices.js | 18 +++++++-----------
js/gdm/authServicesLegacy.js | 18 ++++++++----------
js/gdm/authServicesSSSDSwitchable.js | 10 ++++------
js/gdm/webLogin.js | 14 +++++++-------
js/misc/fingerprintManager.js | 10 ++++------
js/misc/passkeyDeviceManager.js | 3 +--
js/ui/qrCode.js | 10 +++-------
8 files changed, 39 insertions(+), 57 deletions(-)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index 9b7cebf6d8..f7f458dec8 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -1,4 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/* exported AuthMenuButton, AuthMenuButtonIndicator */
/*
* Copyright 2024 Red Hat, Inc
*
@@ -43,15 +44,11 @@
* deactivates any other active item in the same section.
*/
-import Atk from 'gi://Atk';
-import Clutter from 'gi://Clutter';
-import GObject from 'gi://GObject';
-import Shell from 'gi://Shell';
-import St from 'gi://St';
+const { Atk, Clutter, GObject, Shell, St } = imports.gi;
-import * as BoxPointer from '../ui/boxpointer.js';
-import * as Main from '../ui/main.js';
-import * as PopupMenu from '../ui/popupMenu.js';
+const BoxPointer = imports.ui.boxpointer;
+const Main = imports.ui.main;
+const PopupMenu = imports.ui.popupMenu;
const VISIBILITY_ANIMATION_TIME = 200;
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index 0a94f493a2..0cafd2831c 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -1,16 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-import * as FingerprintManager from '../misc/fingerprintManager.js';
-import * as Params from '../misc/params.js';
-import {registerDestroyableType} from '../misc/signalTracker.js';
-import * as PasskeyDeviceManager from '../misc/passkeyDeviceManager.js';
-import * as SmartcardManager from '../misc/smartcardManager.js';
-import {logErrorUnlessCancelled} from '../misc/errorUtils.js';
-import * as Util from './util.js';
-import Gdm from 'gi://Gdm';
-import GLib from 'gi://GLib';
-import Gio from 'gi://Gio';
-import GObject from 'gi://GObject';
+const { Gdm, Gio, GLib, GObject } = imports.gi;
+
+const FingerprintManager = imports.misc.fingerprintManager;
+const Params = imports.misc.params;
+const PasskeyDeviceManager = imports.misc.passkeyDeviceManager;
+const SmartcardManager = imports.misc.smartcardManager;
+const Util = imports.gdm.util;
Gio._promisify(Gdm.Client.prototype, 'open_reauthentication_channel');
Gio._promisify(Gdm.Client.prototype, 'get_user_verifier');
diff --git a/js/gdm/authServicesLegacy.js b/js/gdm/authServicesLegacy.js
index c1ff1242dc..dd134db4b9 100644
--- a/js/gdm/authServicesLegacy.js
+++ b/js/gdm/authServicesLegacy.js
@@ -1,13 +1,11 @@
-import GLib from 'gi://GLib';
-import GObject from 'gi://GObject';
-
-import * as Constants from './constants.js';
-import {FingerprintReaderType} from '../misc/fingerprintManager.js';
-import {logErrorUnlessCancelled} from '../misc/errorUtils.js';
-import * as OVirt from './oVirt.js';
-import * as Util from './util.js';
-import * as Vmware from './vmware.js';
-import {AuthServices} from './authServices.js';
+const { GLib, GObject } = imports.gi;
+
+const {AuthServices} = imports.gdm.authServices;
+const Constants = imports.gdm.constants;
+const {FingerprintReaderType} = imports.misc.fingerprintManager;
+const OVirt = imports.gdm.oVirt;
+const Util = imports.gdm.util;
+const Vmware = imports.gdm.vmware;
const FINGERPRINT_ERROR_TIMEOUT_WAIT = 15;
const FINGERPRINT_READY_TIMEOUT_MS = 500;
diff --git a/js/gdm/authServicesSSSDSwitchable.js b/js/gdm/authServicesSSSDSwitchable.js
index de03dec1d7..4f74a2040d 100644
--- a/js/gdm/authServicesSSSDSwitchable.js
+++ b/js/gdm/authServicesSSSDSwitchable.js
@@ -1,10 +1,8 @@
-import GLib from 'gi://GLib';
-import GObject from 'gi://GObject';
+const { GLib, GObject } = imports.gi;
-import * as Constants from './constants.js';
-import {logErrorUnlessCancelled} from '../misc/errorUtils.js';
-import * as Util from './util.js';
-import {AuthServices} from './authServices.js';
+const {AuthServices} = imports.gdm.authServices;
+const Constants = imports.gdm.constants;
+const Util = imports.gdm.util;
const MechanismsStatus = {
WAITING: 0,
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index 8f2a0d8767..ef4f28b592 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -3,13 +3,13 @@
// A widget showing a URL for web login
/* exported WebLoginPrompt */
-import Clutter from 'gi://Clutter';
-import GObject from 'gi://GObject';
-import Pango from 'gi://Pango';
-import St from 'gi://St';
-import {Spinner} from '../ui/animation.js';
-import * as Params from '../misc/params.js';
-import {QrCode} from '../ui/qrCode.js';
+const { Clutter, Gio, GnomeQR, GObject, Pango, St } = imports.gi;
+
+const Params = imports.misc.params;
+const { Spinner } = imports.ui.animation;
+const { QrCode } = imports.ui.qrCode;
+
+Gio._promisify(GnomeQR, 'generate_qr_code_async');
const QR_CODE_SIZE = 150;
const WEB_LOGIN_SPINNER_SIZE = 35;
diff --git a/js/misc/fingerprintManager.js b/js/misc/fingerprintManager.js
index 6ef2d68d3a..cdeb3579d1 100644
--- a/js/misc/fingerprintManager.js
+++ b/js/misc/fingerprintManager.js
@@ -1,13 +1,11 @@
-import Gio from 'gi://Gio';
-import GLib from 'gi://GLib';
-import GObject from 'gi://GObject';
+const { Gio, GLib, GObject } = imports.gi;
-import {loadInterfaceXML} from './fileUtils.js';
+const FileUtils = imports.misc.fileUtils;
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(
- loadInterfaceXML('net.reactivated.Fprint.Manager'));
+ FileUtils.loadInterfaceXML('net.reactivated.Fprint.Manager'));
const FprintDeviceInfo = Gio.DBusInterfaceInfo.new_for_xml(
- loadInterfaceXML('net.reactivated.Fprint.Device'));
+ FileUtils.loadInterfaceXML('net.reactivated.Fprint.Device'));
export const FingerprintReaderType = {
NONE: 0,
diff --git a/js/misc/passkeyDeviceManager.js b/js/misc/passkeyDeviceManager.js
index 20799975aa..2aa81d2ce6 100644
--- a/js/misc/passkeyDeviceManager.js
+++ b/js/misc/passkeyDeviceManager.js
@@ -1,5 +1,4 @@
-import GObject from 'gi://GObject';
-import GUdev from 'gi://GUdev';
+const { GObject, GUdev } = imports.gi;
let _passkeyDeviceManager = null;
diff --git a/js/ui/qrCode.js b/js/ui/qrCode.js
index caf0999f34..d1fac46847 100644
--- a/js/ui/qrCode.js
+++ b/js/ui/qrCode.js
@@ -1,10 +1,6 @@
-import Clutter from 'gi://Clutter';
-import Cogl from 'gi://Cogl';
-import GObject from 'gi://GObject';
-import Gio from 'gi://Gio';
-import GnomeQR from 'gi://GnomeQR';
-import St from 'gi://St';
-import {logErrorUnlessCancelled} from '../misc/errorUtils.js';
+/* exported QrCode */
+
+const { Clutter, Cogl, Gio, GnomeQR, GObject, St } = imports.gi;
Gio._promisify(GnomeQR, 'generate_qr_code_async');
--
2.51.0
From 12ea582a78b26f37c9c7bdd12af35718cbbae961 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 14:58:42 +0100
Subject: [PATCH 03/30] gdm: Fix using the old gjs style for classes and
functions
---
js/gdm/authList.js | 45 +++++++++-------------
js/gdm/authMenuButton.js | 57 +++++++++++-----------------
js/gdm/authServices.js | 20 ++++------
js/gdm/authServicesLegacy.js | 15 ++++----
js/gdm/authServicesSSSDSwitchable.js | 15 ++++----
js/gdm/constants.js | 22 ++++++-----
js/gdm/util.js | 9 +++--
js/gdm/webLogin.js | 20 +++++-----
js/misc/fingerprintManager.js | 30 +++++++--------
js/misc/passkeyDeviceManager.js | 23 +++++------
js/ui/qrCode.js | 40 +++++++++----------
11 files changed, 131 insertions(+), 165 deletions(-)
diff --git a/js/gdm/authList.js b/js/gdm/authList.js
index 3f1b2817f9..6eb34f6d97 100644
--- a/js/gdm/authList.js
+++ b/js/gdm/authList.js
@@ -57,13 +57,10 @@ const ItemIconPopup = class extends PopupMenu.PopupMenu {
}
};
+const ItemIcon = GObject.registerClass(
class ItemIcon extends St.Button {
- static {
- GObject.registerClass(this);
- }
-
- constructor(iconName, iconTitle, iconSubtitle) {
- super({
+ _init(iconName, iconTitle, iconSubtitle) {
+ super._init({
style_class: 'login-dialog-item-icon',
iconName,
});
@@ -71,21 +68,17 @@ class ItemIcon extends St.Button {
this._popup = new ItemIconPopup(this, iconTitle, iconSubtitle);
Main.uiGroup.add_child(this._popup.actor);
}
-}
+});
-class AuthListItem extends St.Button {
- static [GObject.signals] = {
+const AuthListItem = GObject.registerClass({
+ Signals: {
'activate': {},
- };
-
- static {
- GObject.registerClass(this);
- }
-
- constructor(key, content) {
+ },
+}, class AuthListItem extends St.Button {
+ _init(key, content) {
const {title, subtitle, iconName, iconTitle, iconSubtitle} = content;
- super({
+ super._init({
style_class: 'login-dialog-auth-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
@@ -168,20 +161,16 @@ class AuthListItem extends St.Button {
this.remove_style_pseudo_class('selected');
}
}
-}
+});
-export class AuthList extends St.BoxLayout {
- static [GObject.signals] = {
+var AuthList = GObject.registerClass({
+ Signals: {
'activate': {param_types: [GObject.TYPE_STRING]},
'item-added': {param_types: [AuthListItem.$gtype]},
- };
-
- static {
- GObject.registerClass(this);
}
-
- constructor() {
- super({
+}, class AuthList extends St.BoxLayout {
+ _init() {
+ super._init({
orientation: Clutter.Orientation.VERTICAL,
style_class: 'login-dialog-auth-list-layout',
y_align: Clutter.ActorAlign.CENTER,
@@ -278,4 +267,4 @@ export class AuthList extends St.BoxLayout {
this._box.destroy_all_children();
this._items.clear();
}
-}
+});
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index f7f458dec8..e58c331b45 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -71,13 +71,10 @@ class AuthMenuItemSection extends PopupMenu.PopupMenuSection {
}
}
+const AuthMenuItem = GObject.registerClass(
class AuthMenuItem extends PopupMenu.PopupBaseMenuItem {
- static {
- GObject.registerClass(this);
- }
-
- constructor(item, params = {}) {
- super(params);
+ _init(item, params = {}) {
+ super._init(params);
if (item.description && item.iconName) {
const icon = new St.Icon({
@@ -117,42 +114,37 @@ class AuthMenuItem extends PopupMenu.PopupBaseMenuItem {
this.setOrnament(PopupMenu.Ornament.HIDDEN);
}
-}
+});
-export class AuthMenuButton extends St.Button {
- static [GObject.properties] = {
+var AuthMenuButton = GObject.registerClass({
+ Properties: {
'title': GObject.ParamSpec.string(
- 'title', null, null,
+ 'title', 'title', 'title',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
''),
'icon-name': GObject.ParamSpec.string(
- 'icon-name', null, null,
+ 'icon-name', 'icon-name', 'icon-name',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
''),
'read-only': GObject.ParamSpec.boolean(
- 'read-only', null, null,
+ 'read-only', 'read-only', 'read-only',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
false),
'section-order': GObject.ParamSpec.jsobject(
- 'section-order', null, null,
+ 'section-order', 'section-order', 'section-order',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY),
'animate-visibility': GObject.ParamSpec.boolean(
- 'animate-visibility', null, null,
+ 'animate-visibility', 'animate-visibility', 'animate-visibility',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
false),
- };
-
- static [GObject.signals] = {
+ },
+ Signals: {
'active-item-changed': {param_types: [GObject.TYPE_STRING]},
- };
-
- static {
- GObject.registerClass(this);
- }
-
- constructor(params) {
+ },
+}, class AuthMenuButton extends St.Button {
+ _init(params) {
params.sectionOrder ??= [];
- super({
+ super._init({
...params,
style_class: 'login-dialog-button login-dialog-auth-menu-button',
reactive: true,
@@ -452,16 +444,13 @@ export class AuthMenuButton extends St.Button {
closeMenu() {
this._menu.close();
}
-}
+});
-export class AuthMenuButtonIndicator extends AuthMenuButton {
- static {
- GObject.registerClass(this);
- }
-
- constructor(params = {}) {
+var AuthMenuButtonIndicator = GObject.registerClass(
+class AuthMenuButtonIndicator extends AuthMenuButton {
+ _init(params = {}) {
params.readOnly ??= true;
- super(params);
+ super._init(params);
this.add_style_class_name('login-dialog-auth-menu-button-indicator');
}
@@ -526,4 +515,4 @@ export class AuthMenuButtonIndicator extends AuthMenuButton {
// Override to force visibility even when there's only one item
_updateVisibility() {
}
-}
+});
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index 0cafd2831c..ce4f0729b3 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -1,4 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/* exported AuthServices */
const { Gdm, Gio, GLib, GObject } = imports.gi;
@@ -16,8 +17,8 @@ Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_answer_query');
Gio._promisify(Gdm.UserVerifierChoiceListProxy.prototype, 'call_select_choice');
Gio._promisify(Gdm.UserVerifierCustomJSONProxy.prototype, 'call_reply');
-export class AuthServices extends GObject.Object {
- static [GObject.signals] = {
+var AuthServices = GObject.registerClass({
+ Signals: {
'destroy': {},
'queue-message': {
param_types: [GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_UINT],
@@ -51,13 +52,8 @@ export class AuthServices extends GObject.Object {
GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_JSOBJECT,
],
},
- };
-
- static {
- GObject.registerClass(this);
- registerDestroyableType(this);
- }
-
+ },
+}, class AuthServices extends GObject.Object {
static SupportedRoles = [];
static RoleToService = {};
@@ -65,8 +61,8 @@ export class AuthServices extends GObject.Object {
return roles.some(r => this.SupportedRoles.includes(r));
}
- constructor(params) {
- super();
+ _init(params) {
+ super._init();
params = Params.parse(params, {
client: null,
enabledRoles: [],
@@ -502,4 +498,4 @@ export class AuthServices extends GObject.Object {
throw new GObject.NotImplementedError(
`_handleCanStartService in ${this.constructor.name}`);
}
-}
+});
diff --git a/js/gdm/authServicesLegacy.js b/js/gdm/authServicesLegacy.js
index dd134db4b9..8922546474 100644
--- a/js/gdm/authServicesLegacy.js
+++ b/js/gdm/authServicesLegacy.js
@@ -1,3 +1,5 @@
+/* exported AuthServicesLegacy */
+
const { GLib, GObject } = imports.gi;
const {AuthServices} = imports.gdm.authServices;
@@ -28,7 +30,8 @@ const Mechanisms = [
},
];
-export class AuthServicesLegacy extends AuthServices {
+var AuthServicesLegacy = GObject.registerClass({
+}, class AuthServicesLegacy extends AuthServices {
static SupportedRoles = [
Constants.PASSWORD_ROLE_NAME,
Constants.SMARTCARD_ROLE_NAME,
@@ -41,12 +44,8 @@ export class AuthServicesLegacy extends AuthServices {
[Constants.FINGERPRINT_ROLE_NAME]: Constants.FINGERPRINT_SERVICE_NAME,
};
- static {
- GObject.registerClass(this);
- }
-
- constructor(params) {
- super(params);
+ _init(params) {
+ super._init(params);
this._updateEnabledMechanisms();
@@ -378,4 +377,4 @@ export class AuthServicesLegacy extends AuthServices {
};
this.emit('reset', {softReset: true});
}
-}
+});
diff --git a/js/gdm/authServicesSSSDSwitchable.js b/js/gdm/authServicesSSSDSwitchable.js
index 4f74a2040d..4b4761d105 100644
--- a/js/gdm/authServicesSSSDSwitchable.js
+++ b/js/gdm/authServicesSSSDSwitchable.js
@@ -1,3 +1,5 @@
+/* exported AuthServicesSwitchable */
+
const { GLib, GObject } = imports.gi;
const {AuthServices} = imports.gdm.authServices;
@@ -10,7 +12,8 @@ const MechanismsStatus = {
FOUND: 2,
};
-export class AuthServicesSSSDSwitchable extends AuthServices {
+var AuthServicesSSSDSwitchable = GObject.registerClass({
+}, class AuthServicesSSSDSwitchable extends AuthServices {
static SupportedRoles = [
Constants.PASSWORD_ROLE_NAME,
Constants.SMARTCARD_ROLE_NAME,
@@ -25,12 +28,8 @@ export class AuthServicesSSSDSwitchable extends AuthServices {
[Constants.WEB_LOGIN_ROLE_NAME]: Constants.SWITCHABLE_AUTH_SERVICE_NAME,
};
- static {
- GObject.registerClass(this);
- }
-
- constructor(params) {
- super(params);
+ _init(params) {
+ super._init(params);
this._mechanismsStatus = MechanismsStatus.WAITING;
}
@@ -440,4 +439,4 @@ export class AuthServicesSSSDSwitchable extends AuthServices {
GLib.source_remove(this._webLoginTimeoutId);
this._webLoginTimeoutId = 0;
}
-}
+});
diff --git a/js/gdm/constants.js b/js/gdm/constants.js
index 7c48599e64..cfbbe32426 100644
--- a/js/gdm/constants.js
+++ b/js/gdm/constants.js
@@ -1,12 +1,16 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/* exported PASSWORD_ROLE_NAME, SMARTCARD_ROLE_NAME, FINGERPRINT_ROLE_NAME,
+ PASSKEY_ROLE_NAME, WEB_LOGIN_ROLE_NAME, PASSWORD_SERVICE_NAME,
+ SMARTCARD_SERVICE_NAME, FINGERPRINT_SERVICE_NAME,
+ SWITCHABLE_AUTH_SERVICE_NAME */
-export const PASSWORD_ROLE_NAME = 'password';
-export const SMARTCARD_ROLE_NAME = 'smartcard';
-export const FINGERPRINT_ROLE_NAME = 'fingerprint';
-export const PASSKEY_ROLE_NAME = 'passkey';
-export const WEB_LOGIN_ROLE_NAME = 'eidp';
+var PASSWORD_ROLE_NAME = 'password';
+var SMARTCARD_ROLE_NAME = 'smartcard';
+var FINGERPRINT_ROLE_NAME = 'fingerprint';
+var PASSKEY_ROLE_NAME = 'passkey';
+var WEB_LOGIN_ROLE_NAME = 'eidp';
-export const PASSWORD_SERVICE_NAME = 'gdm-password';
-export const SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
-export const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
-export const SWITCHABLE_AUTH_SERVICE_NAME = 'gdm-switchable-auth';
+var PASSWORD_SERVICE_NAME = 'gdm-password';
+var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
+var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
+var SWITCHABLE_AUTH_SERVICE_NAME = 'gdm-switchable-auth';
diff --git a/js/gdm/util.js b/js/gdm/util.js
index 743fce11b7..f1709edea3 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY,
- DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */
+ DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor,
+ InitError, isSelectable, getIconName */
const { Clutter, Gio, GLib } = imports.gi;
const Signals = imports.signals;
@@ -125,7 +126,7 @@ function cloneAndFadeOutActor(actor) {
* a service via beginVerification fails. It wraps the underlying error
* and provides context about which service failed.
*/
-export class InitError extends Error {
+var InitError = class extends Error {
constructor(error, message, serviceName) {
super(message, {cause: error});
this.serviceName = serviceName;
@@ -136,7 +137,7 @@ export class InitError extends Error {
* @param {object} mechanism
* @returns {boolean}
*/
-export function isSelectable(mechanism) {
+function isSelectable(mechanism) {
switch (mechanism.role) {
case Constants.PASSWORD_ROLE_NAME:
case Constants.SMARTCARD_ROLE_NAME:
@@ -154,7 +155,7 @@ export function isSelectable(mechanism) {
* @param {object} mechanism
* @returns {string}
*/
-export function getNonSelectableIconName(mechanism) {
+function getNonSelectableIconName(mechanism) {
// This is only used for non selectable mechanisms.
// Currently only fingerprint is non selectable
if (isSelectable(mechanism))
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index ef4f28b592..9c858f7269 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
//
// A widget showing a URL for web login
-/* exported WebLoginPrompt */
+/* exported QrCode, WebLoginPrompt, WebLoginDialog, WebLoginIntro */
const { Clutter, Gio, GnomeQR, GObject, Pango, St } = imports.gi;
@@ -15,9 +15,9 @@ const QR_CODE_SIZE = 150;
const WEB_LOGIN_SPINNER_SIZE = 35;
const URL_LABEL_LONG_THRESHOLD = 45;
-export const WebLoginPrompt = GObject.registerClass(
+var WebLoginPrompt = GObject.registerClass(
class WebLoginPrompt extends St.BoxLayout {
- constructor(params) {
+ _init(params) {
const {qrSize: qrCodeSize, message, url, code} = Params.parse(params, {
qrSize: QR_CODE_SIZE,
message: null,
@@ -25,7 +25,7 @@ class WebLoginPrompt extends St.BoxLayout {
code: null,
});
- super({
+ super._init({
styleClass: 'web-login-prompt',
vertical: true,
y_align: Clutter.ActorAlign.CENTER,
@@ -124,13 +124,13 @@ class WebLoginPrompt extends St.BoxLayout {
}
});
-export const WebLoginDialog = GObject.registerClass({
+var WebLoginDialog = GObject.registerClass({
Signals: {
'cancel': {},
'loading': {},
},
}, class WebLoginDialog extends St.Widget {
- constructor(params) {
+ _init(params) {
const {message, url, code, buttons} = Params.parse(params, {
message: null,
url: null,
@@ -138,7 +138,7 @@ export const WebLoginDialog = GObject.registerClass({
buttons: [],
});
- super({
+ super._init({
layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true,
@@ -279,9 +279,9 @@ export const WebLoginDialog = GObject.registerClass({
}
});
-export var WebLoginIntro = GObject.registerClass(
+var WebLoginIntro = GObject.registerClass(
class WebLoginIntro extends St.Button {
- constructor(params) {
+ _init(params) {
const {message} = Params.parse(params, {
message: null,
});
@@ -291,7 +291,7 @@ class WebLoginIntro extends St.Button {
style_class: 'web-login-button-label',
});
- super({
+ super._init({
style_class: 'web-login-intro-button',
accessible_name: message,
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
diff --git a/js/misc/fingerprintManager.js b/js/misc/fingerprintManager.js
index cdeb3579d1..151e787e0b 100644
--- a/js/misc/fingerprintManager.js
+++ b/js/misc/fingerprintManager.js
@@ -1,4 +1,5 @@
const { Gio, GLib, GObject } = imports.gi;
+/* exported FingerprintReaderType, FingerprintManager */
const FileUtils = imports.misc.fileUtils;
@@ -7,7 +8,7 @@ const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(
const FprintDeviceInfo = Gio.DBusInterfaceInfo.new_for_xml(
FileUtils.loadInterfaceXML('net.reactivated.Fprint.Device'));
-export const FingerprintReaderType = {
+var FingerprintReaderType = {
NONE: 0,
PRESS: 1,
SWIPE: 2,
@@ -18,32 +19,27 @@ let _fingerprintManager = null;
/**
* @returns {FingerprintManager}
*/
-export function getFingerprintManager() {
+function getFingerprintManager() {
if (_fingerprintManager == null)
_fingerprintManager = new FingerprintManager();
return _fingerprintManager;
}
-class FingerprintManager extends GObject.Object {
- static [GObject.properties] = {
+var FingerprintManager = GObject.registerClass({
+ Properties: {
'reader-type': GObject.ParamSpec.uint(
- 'reader-type', null, null,
+ 'reader-type', 'reader-type', 'reader-type',
GObject.ParamFlags.READWRITE,
FingerprintReaderType.NONE, FingerprintReaderType.SWIPE,
FingerprintReaderType.NONE),
- };
-
- static [GObject.signals] = {
+ },
+ Signals: {
'reader-type-changed': {},
- };
-
- static {
- GObject.registerClass(this);
- }
-
- constructor() {
- super();
+ },
+}, class FingerprintManager extends GObject.Object {
+ _init() {
+ super._init();
this._fingerprintManagerProxy = new Gio.DBusProxy({
g_connection: Gio.DBus.system,
@@ -133,4 +129,4 @@ class FingerprintManager extends GObject.Object {
logError(e, 'Failed to interact with fprintd service');
}
-}
+});
diff --git a/js/misc/passkeyDeviceManager.js b/js/misc/passkeyDeviceManager.js
index 2aa81d2ce6..747ee93fc8 100644
--- a/js/misc/passkeyDeviceManager.js
+++ b/js/misc/passkeyDeviceManager.js
@@ -1,30 +1,27 @@
const { GObject, GUdev } = imports.gi;
+/* exported getPasskeyDeviceManager */
+
let _passkeyDeviceManager = null;
/**
* @returns {PasskeyDeviceManager}
*/
-export function getPasskeyDeviceManager() {
+function getPasskeyDeviceManager() {
if (_passkeyDeviceManager == null)
_passkeyDeviceManager = new PasskeyDeviceManager();
return _passkeyDeviceManager;
}
-class PasskeyDeviceManager extends GObject.Object {
- static [GObject.signals] = {
+var PasskeyDeviceManager = GObject.registerClass({
+ Signals: {
'passkey-inserted': {param_types: [GObject.TYPE_JSOBJECT]},
'passkey-removed': {param_types: [GObject.TYPE_JSOBJECT]},
- };
-
- static {
- GObject.registerClass(this);
- }
-
- constructor() {
- super();
-
+ },
+}, class PasskeyDeviceManager extends GObject.Object {
+ _init() {
+ super._init();
this._insertedPasskeys = new Map();
this._udevClient = new GUdev.Client({subsystems: ['hidraw']});
@@ -65,4 +62,4 @@ class PasskeyDeviceManager extends GObject.Object {
this._insertedPasskeys.delete(sysfsPath);
this.emit('passkey-removed', device);
}
-}
+});
diff --git a/js/ui/qrCode.js b/js/ui/qrCode.js
index d1fac46847..5920e45e5a 100644
--- a/js/ui/qrCode.js
+++ b/js/ui/qrCode.js
@@ -7,43 +7,39 @@ Gio._promisify(GnomeQR, 'generate_qr_code_async');
const QR_CODE_DEFAULT_SIZE = 150;
const QR_CODE_TRANSPARENT_COLOR = new GnomeQR.Color({alpha: 0});
-export class QrCode extends St.Bin {
- static [GObject.properties] = {
+var QrCode = GObject.registerClass({
+ Properties: {
'url': GObject.ParamSpec.string(
- 'url', null, null,
+ 'url', 'url', 'url',
GObject.ParamFlags.READWRITE,
null),
- };
-
- static {
- GObject.registerClass(this);
- }
-
- constructor(params) {
+ },
+}, class QrCode extends St.Bin {
+ _init(params) {
const qrSize = Math.max(params.width ?? 0, params.height ?? 0) ||
QR_CODE_DEFAULT_SIZE;
- super({
- styleClass: 'qr-code',
+ super._init({
+ style_class: 'qr-code',
width: qrSize,
height: qrSize,
...params,
});
this.set_child(new Clutter.Actor({
- xExpand: true,
- yExpand: true,
- xAlign: Clutter.ActorAlign.FILL,
- yAlign: Clutter.ActorAlign.FILL,
- minificationFilter: Clutter.ScalingFilter.NEAREST,
- magnificationFilter: Clutter.ScalingFilter.NEAREST,
+ x_expand: true,
+ y_expand: true,
+ x_align: Clutter.ActorAlign.FILL,
+ y_align: Clutter.ActorAlign.FILL,
+ minification_filter: Clutter.ScalingFilter.NEAREST,
+ magnification_filter: Clutter.ScalingFilter.NEAREST,
}));
this._fgColor = null;
this.connect('notify::url', () =>
this._update().catch(logErrorUnlessCancelled));
- };
+ }
vfunc_allocate(box) {
const width = box.get_width();
@@ -69,7 +65,7 @@ export class QrCode extends St.Bin {
}
async _update() {
- const fgColor = QrCode.#getGnomeQRColor(this._fgColor);
+ const fgColor = QrCode._getGnomeQRColor(this._fgColor);
this._cancellable?.cancel();
const cancellable = new Gio.Cancellable();
@@ -100,7 +96,7 @@ export class QrCode extends St.Bin {
this.child.set_content(content);
}
- static #getGnomeQRColor(color) {
+ static _getGnomeQRColor(color) {
if (!color)
return null;
@@ -111,4 +107,4 @@ export class QrCode extends St.Bin {
alpha: color.alpha,
});
}
-};
+});
--
2.51.0
From 8d635a7b5f8da824025ae9e206cd2cdf92bc83ff Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 15:01:19 +0100
Subject: [PATCH 04/30] gdm: Fix using logErrorUnless cancelled
This function doesn't exist in this version.
---
js/gdm/authServices.js | 3 ++-
js/gdm/authServicesLegacy.js | 12 +++++++++---
js/gdm/authServicesSSSDSwitchable.js | 12 +++++++++---
js/gdm/util.js | 5 ++++-
js/ui/qrCode.js | 13 ++++++++++---
5 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index ce4f0729b3..fea7ba0634 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -373,7 +373,8 @@ var AuthServices = GObject.registerClass({
await this._waitPendingMessages();
this.emit('reset', {softReset: !doneTrying});
} catch (e) {
- logErrorUnlessCancelled(e);
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
}
}
diff --git a/js/gdm/authServicesLegacy.js b/js/gdm/authServicesLegacy.js
index 8922546474..0fd0e10d81 100644
--- a/js/gdm/authServicesLegacy.js
+++ b/js/gdm/authServicesLegacy.js
@@ -1,6 +1,6 @@
/* exported AuthServicesLegacy */
-const { GLib, GObject } = imports.gi;
+const { Gio, GLib, GObject } = imports.gi;
const {AuthServices} = imports.gdm.authServices;
const Constants = imports.gdm.constants;
@@ -61,7 +61,10 @@ var AuthServicesLegacy = GObject.registerClass({
return;
this._userVerifierChoiceList.call_select_choice(
- serviceName, key, this._cancellable).catch(logErrorUnlessCancelled);
+ serviceName, key, this._cancellable).catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
}
_handleAnswerQuery(serviceName, answer) {
@@ -72,7 +75,10 @@ var AuthServicesLegacy = GObject.registerClass({
this._smartcardInProgress = true;
this._userVerifier.call_answer_query(
- serviceName, answer, this._cancellable).catch(logErrorUnlessCancelled);
+ serviceName, answer, this._cancellable).catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
}
_handleBeginVerification() {
diff --git a/js/gdm/authServicesSSSDSwitchable.js b/js/gdm/authServicesSSSDSwitchable.js
index 4b4761d105..601f4cd295 100644
--- a/js/gdm/authServicesSSSDSwitchable.js
+++ b/js/gdm/authServicesSSSDSwitchable.js
@@ -1,6 +1,6 @@
/* exported AuthServicesSwitchable */
-const { GLib, GObject } = imports.gi;
+const { Gio, GLib, GObject } = imports.gi;
const {AuthServices} = imports.gdm.authServices;
const Constants = imports.gdm.constants;
@@ -54,7 +54,10 @@ var AuthServicesSSSDSwitchable = GObject.registerClass({
this._resettingPassword) {
this._userVerifier.call_answer_query(serviceName,
answer,
- this._cancellable).catch(logErrorUnlessCancelled);
+ this._cancellable).catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
return;
}
@@ -316,7 +319,10 @@ var AuthServicesSSSDSwitchable = GObject.registerClass({
const {serviceName} = this._selectedMechanism;
this._userVerifierCustomJSON.call_reply(
- serviceName, JSON.stringify(response), this._cancellable).catch(logErrorUnlessCancelled);
+ serviceName, JSON.stringify(response), this._cancellable).catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
}
_eventExpected() {
diff --git a/js/gdm/util.js b/js/gdm/util.js
index f1709edea3..17892c75e8 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -282,7 +282,10 @@ var ShellUserVerifier = class {
async answerQuery(serviceName, answer) {
// Wait for pending messages to be displayed before answering to
// ensure no messages get lost
- await this._handlePendingMessages().catch(logErrorUnlessCancelled);
+ await this._handlePendingMessages().catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
this._authServicesSSSDSwitchable?.answerQuery(serviceName, answer);
this._authServicesLegacy?.answerQuery(serviceName, answer);
diff --git a/js/ui/qrCode.js b/js/ui/qrCode.js
index 5920e45e5a..b53508c2dd 100644
--- a/js/ui/qrCode.js
+++ b/js/ui/qrCode.js
@@ -37,8 +37,12 @@ var QrCode = GObject.registerClass({
this._fgColor = null;
- this.connect('notify::url', () =>
- this._update().catch(logErrorUnlessCancelled));
+ this.connect('notify::url', () => {
+ this._update().catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
+ });
}
vfunc_allocate(box) {
@@ -60,7 +64,10 @@ var QrCode = GObject.registerClass({
if (!this._fgColor?.equal(fgColor)) {
this._fgColor = fgColor;
- this._update().catch(logErrorUnlessCancelled);
+ this._update().catch(e => {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ logError(e);
+ });
}
}
--
2.51.0
From 147ad05d7d926478da5d35ea14bcec81bf0795ee Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 12:58:59 +0100
Subject: [PATCH 05/30] gdm: Change connectObject to connect
connectObject is a helper that isn't available in this older version.
---
js/gdm/authPrompt.js | 24 +++---
js/gdm/authServices.js | 138 +++++++++++++++++++++++++----------
js/gdm/authServicesLegacy.js | 26 ++++++-
js/gdm/util.js | 61 +++++++++++-----
js/gdm/webLogin.js | 11 ++-
5 files changed, 186 insertions(+), 74 deletions(-)
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
index 8c5c8a1fab..6996dac18b 100644
--- a/js/gdm/authPrompt.js
+++ b/js/gdm/authPrompt.js
@@ -81,16 +81,16 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly });
- this._userVerifier.connectObject(
- 'ask-question', this._onAskQuestion.bind(this),
- 'show-message', this._onShowMessage.bind(this),
- 'show-choice-list', this._onShowChoiceList.bind(this),
- 'mechanisms-changed', (_, ...args) => this.emit('mechanisms-changed', ...args),
- 'web-login', this._onWebLogin.bind(this),
- 'verification-failed', this._onVerificationFailed.bind(this),
- 'verification-complete', this._onVerificationComplete.bind(this),
- 'reset', this._onReset.bind(this),
- this);
+ this._userVerifierSignalIds = [
+ this._userVerifier.connect('ask-question', this._onAskQuestion.bind(this)),
+ this._userVerifier.connect('show-message', this._onShowMessage.bind(this)),
+ this._userVerifier.connect('show-choice-list', this._onShowChoiceList.bind(this)),
+ this._userVerifier.connect('mechanisms-changed', (_, ...args) => this.emit('mechanisms-changed', ...args)),
+ this._userVerifier.connect('web-login', this._onWebLogin.bind(this)),
+ this._userVerifier.connect('verification-failed', this._onVerificationFailed.bind(this)),
+ this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this)),
+ this._userVerifier.connect('reset', this._onReset.bind(this)),
+ ];
this.connect('destroy', this._onDestroy.bind(this));
@@ -134,7 +134,9 @@ var AuthPrompt = GObject.registerClass({
this._preemptiveAnswerWatchId = 0;
}
- this._userVerifier.disconnectObject(this);
+ this._userVerifierSignalIds.forEach(id =>
+ this._userVerifier.disconnect(id));
+ this._userVerifierSignalIds = [];
this._userVerifier.destroy();
this._userVerifier = null;
this._entry = null;
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index fea7ba0634..88462cf17e 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -165,6 +165,8 @@ var AuthServices = GObject.registerClass({
destroy() {
this.reset();
this.clear();
+ this._disconnectManagers();
+ this._handleDestroy();
this.emit('destroy');
}
@@ -202,10 +204,35 @@ var AuthServices = GObject.registerClass({
}
_disconnectUserVerifierSignals() {
- this._userVerifier?.get_connection().disconnectObject(this);
- this._userVerifier?.disconnectObject(this);
- this._userVerifierChoiceList?.disconnectObject(this);
- this._userVerifierCustomJSON?.disconnectObject(this);
+ this._userVerifierConnectionSignalIds?.forEach(id =>
+ this._userVerifier?.get_connection().disconnect(id));
+ this._userVerifierConnectionSignalIds = [];
+
+ this._userVerifierSignalIds?.forEach(id =>
+ this._userVerifier?.disconnect(id));
+ this._userVerifierSignalIds = [];
+
+ this._userVerifierChoiceListSignalIds?.forEach(id =>
+ this._userVerifierChoiceList?.disconnect(id));
+ this._userVerifierChoiceListSignalIds = [];
+
+ this._userVerifierCustomJSONSignalIds?.forEach(id =>
+ this._userVerifierCustomJSON?.disconnect(id));
+ this._userVerifierCustomJSONSignalIds = [];
+ }
+
+ _disconnectManagers() {
+ this._smartcardManagerSignalIds?.forEach(id =>
+ this._smartcardManager?.disconnect(id));
+ this._smartcardManagerSignalIds = [];
+
+ this._passkeyDeviceManagerSignalIds?.forEach(id =>
+ this._passkeyDeviceManager?.disconnect(id));
+ this._passkeyDeviceManagerSignalIds = [];
+
+ this._fingerprintManagerSignalIds?.forEach(id =>
+ this._fingerprintManager?.disconnect(id));
+ this._fingerprintManagerSignalIds = [];
}
_updateEnabledMechanisms() {
@@ -218,18 +245,24 @@ var AuthServices = GObject.registerClass({
_connectSmartcardManager() {
this._smartcardManager = SmartcardManager.getSmartcardManager();
- this._smartcardManager.connectObject(
- 'smartcard-inserted', () => this._handleSmartcardChanged(),
- 'smartcard-removed', () => this._handleSmartcardChanged(),
- this);
+ this._smartcardManagerSignalIds = [];
+ let id = this._smartcardManager.connect('smartcard-inserted',
+ () => this._handleSmartcardChanged());
+ this._smartcardManagerSignalIds.push(id);
+ id = this._smartcardManager.connect('smartcard-removed',
+ () => this._handleSmartcardChanged());
+ this._smartcardManagerSignalIds.push(id);
}
_connectPasskeyDeviceManager() {
this._passkeyDeviceManager = PasskeyDeviceManager.getPasskeyDeviceManager();
- this._passkeyDeviceManager.connectObject(
- 'passkey-inserted', () => this._handlePasskeyChanged(),
- 'passkey-removed', () => this._handlePasskeyChanged(),
- this);
+ this._passkeyDeviceManagerSignalIds = [];
+ let id = this._passkeyDeviceManager.connect('passkey-inserted',
+ () => this._handlePasskeyChanged());
+ this._passkeyDeviceManagerSignalIds.push(id);
+ id = this._passkeyDeviceManager.connect('passkey-removed',
+ () => this._handlePasskeyChanged());
+ this._passkeyDeviceManagerSignalIds.push(id);
}
_connectFingerprintManager() {
@@ -237,10 +270,11 @@ var AuthServices = GObject.registerClass({
if (!this._reauthOnly)
return;
- this._fingerprintManager = FingerprintManager.getFingerprintManager();
- this._fingerprintManager.connectObject(
- 'reader-type-changed', () => this._handleFingerprintChanged(),
- this);
+ this._fingerprintManager = new FingerprintManager.FingerprintManager();
+ this._fingerprintManagerSignalIds = [];
+ let id = this._fingerprintManager.connect('reader-type-changed',
+ () => this._handleFingerprintChanged());
+ this._fingerprintManagerSignalIds.push(id);
}
_waitPendingMessages() {
@@ -276,29 +310,53 @@ var AuthServices = GObject.registerClass({
}
_connectUserVerifierSignals() {
- this._userVerifier.get_connection().connectObject(
- 'closed', () => this._clearUserVerifier(),
- this);
-
- this._userVerifier.connectObject(
- 'info', (_, ...args) => this._onInfo(...args),
- 'problem', (_, ...args) => this._onProblem(...args),
- 'info-query', (_, ...args) => this._onInfoQuery(...args),
- 'secret-info-query', (_, ...args) => this._onSecretInfoQuery(...args),
- 'conversation-started', (_, ...args) => this._onConversationStarted(...args),
- 'conversation-stopped', (_, ...args) => this._onConversationStopped(...args),
- 'service-unavailable', (_, ...args) => this._onServiceUnavailable(...args),
- 'reset', () => this.emit('reset', {}),
- 'verification-complete', (_, ...args) => this._onVerificationComplete(...args),
- this);
-
- this._userVerifierChoiceList?.connectObject(
- 'choice-query', (_, ...args) => this._onChoiceListQuery(...args),
- this);
-
- this._userVerifierCustomJSON?.connectObject(
- 'request', (_, ...args) => this._onCustomJSONRequest(...args),
- this);
+ this._userVerifierConnectionSignalIds = [];
+ let id = this._userVerifier.get_connection().connect('closed',
+ () => this._clearUserVerifier());
+ this._userVerifierConnectionSignalIds.push(id);
+
+ this._userVerifierSignalIds = [];
+ id = this._userVerifier.connect('info',
+ (_, ...args) => this._onInfo(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('problem',
+ (_, ...args) => this._onProblem(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('info-query',
+ (_, ...args) => this._onInfoQuery(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('secret-info-query',
+ (_, ...args) => this._onSecretInfoQuery(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('conversation-started',
+ (_, ...args) => this._onConversationStarted(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('conversation-stopped',
+ (_, ...args) => this._onConversationStopped(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('service-unavailable',
+ (_, ...args) => this._onServiceUnavailable(...args));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('reset',
+ () => this.emit('reset', {}));
+ this._userVerifierSignalIds.push(id);
+ id = this._userVerifier.connect('verification-complete',
+ (_, ...args) => this._onVerificationComplete(...args));
+ this._userVerifierSignalIds.push(id);
+
+ this._userVerifierChoiceListSignalIds = [];
+ if (this._userVerifierChoiceList) {
+ id = this._userVerifierChoiceList.connect('choice-query',
+ (_, ...args) => this._onChoiceListQuery(...args));
+ this._userVerifierChoiceListSignalIds.push(id);
+ }
+
+ this._userVerifierCustomJSONSignalIds = [];
+ if (this._userVerifierCustomJSON) {
+ id = this._userVerifierCustomJSON.connect('request',
+ (_, ...args) => this._onCustomJSONRequest(...args));
+ this._userVerifierCustomJSONSignalIds.push(id);
+ }
}
_onInfo(serviceName, info) {
@@ -456,6 +514,8 @@ var AuthServices = GObject.registerClass({
_handleClear() {}
+ _handleDestroy() {}
+
_handleUpdateEnabledRoles() {}
_handleUpdateEnabledMechanisms() {
diff --git a/js/gdm/authServicesLegacy.js b/js/gdm/authServicesLegacy.js
index 0fd0e10d81..5955aeadff 100644
--- a/js/gdm/authServicesLegacy.js
+++ b/js/gdm/authServicesLegacy.js
@@ -50,6 +50,7 @@ var AuthServicesLegacy = GObject.registerClass({
this._updateEnabledMechanisms();
this._credentialManagers = {};
+ this._credentialManagerSignalIds = {};
this.addCredentialManager(OVirt.SERVICE_NAME, OVirt.getOVirtCredentialsManager());
this.addCredentialManager(Vmware.SERVICE_NAME, Vmware.getVmwareCredentialsManager());
@@ -104,6 +105,20 @@ var AuthServicesLegacy = GObject.registerClass({
this._selectedMechanism = null;
}
+ _handleDestroy() {
+ this._disconnectCredentialManagers();
+ }
+
+ _disconnectCredentialManagers() {
+ Object.keys(this._credentialManagerSignalIds).forEach(serviceName => {
+ const signalId = this._credentialManagerSignalIds[serviceName];
+ const credentialManager = this._credentialManagers[serviceName];
+ if (signalId)
+ credentialManager?.disconnect(signalId);
+ });
+ this._credentialManagerSignalIds = {};
+ }
+
_handleClear() {
this._smartcardInProgress = false;
this._clearFingerprintReadyTimeout();
@@ -359,9 +374,9 @@ var AuthServicesLegacy = GObject.registerClass({
if (credentialManager.token)
this._onCredentialManagerAuthenticated(credentialManager);
- credentialManager.connectObject(
- 'user-authenticated', () => this._onCredentialManagerAuthenticated(credentialManager),
- this);
+ const id = credentialManager.connect('user-authenticated',
+ () => this._onCredentialManagerAuthenticated(credentialManager));
+ this._credentialManagerSignalIds[serviceName] = id;
}
removeCredentialManager(serviceName) {
@@ -369,7 +384,10 @@ var AuthServicesLegacy = GObject.registerClass({
if (!credentialManager)
return;
- credentialManager.disconnectObject(this);
+ const signalId = this._credentialManagerSignalIds[serviceName];
+ if (signalId)
+ credentialManager.disconnect(signalId);
+ delete this._credentialManagerSignalIds[serviceName];
delete this._credentialManagers[serviceName];
if (this._selectedMechanism?.serviceName === serviceName)
diff --git a/js/gdm/util.js b/js/gdm/util.js
index 17892c75e8..85de597d33 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -270,6 +270,8 @@ var ShellUserVerifier = class {
this.cancel();
+ this._clearAuthServices();
+
this._settings.run_dispose();
this._settings = null;
}
@@ -498,31 +500,54 @@ var ShellUserVerifier = class {
}
_clearAuthServices() {
+ this._authServicesSSSDSwitchableSignalIds?.forEach(id =>
+ this._authServicesSSSDSwitchable?.disconnect(id));
+ this._authServicesSSSDSwitchableSignalIds = [];
this._authServicesSSSDSwitchable?.destroy();
this._authServicesSSSDSwitchable = null;
+
+ this._authServicesLegacySignalIds?.forEach(id =>
+ this._authServicesLegacy?.disconnect(id));
+ this._authServicesLegacySignalIds = [];
this._authServicesLegacy?.destroy();
this._authServicesLegacy = null;
}
_connectAuthServices() {
- [
- this._authServicesSSSDSwitchable,
- this._authServicesLegacy,
- ].forEach(authServices => {
- authServices?.connectObject(
- 'ask-question', (_, ...args) => this.emit('ask-question', ...args),
- 'queue-message', (_, ...args) => this._queueMessage(...args),
- 'queue-priority-message', (_, ...args) => this._queuePriorityMessage(...args),
- 'wait-pending-messages', (_, ...args) => this._waitPendingMessages(...args),
- 'filter-messages', (_, ...args) => this._filterServiceMessages(...args),
- 'verification-failed', (_, ...args) => this._verificationFailed(...args),
- 'verification-complete', (_, ...args) => this.emit('verification-complete', ...args),
- 'reset', (_, ...args) => this.emit('reset', ...args),
- 'show-choice-list', (_, ...args) => this.emit('show-choice-list', ...args),
- 'mechanisms-changed', (_, ...args) => this._onMechanismsChanged(...args),
- 'web-login', (_, ...args) => this.emit('web-login', ...args),
- this);
- });
+ const connectSignals = authServices => {
+ if (!authServices)
+ return [];
+
+ return [
+ authServices.connect('ask-question',
+ (_, ...args) => this.emit('ask-question', ...args)),
+ authServices.connect('queue-message',
+ (_, ...args) => this._queueMessage(...args)),
+ authServices.connect('queue-priority-message',
+ (_, ...args) => this._queuePriorityMessage(...args)),
+ authServices.connect('wait-pending-messages',
+ (_, ...args) => this._waitPendingMessages(...args)),
+ authServices.connect('filter-messages',
+ (_, ...args) => this._filterServiceMessages(...args)),
+ authServices.connect('verification-failed',
+ (_, ...args) => this._verificationFailed(...args)),
+ authServices.connect('verification-complete',
+ (_, ...args) => this.emit('verification-complete', ...args)),
+ authServices.connect('reset',
+ (_, ...args) => this.emit('reset', ...args)),
+ authServices.connect('show-choice-list',
+ (_, ...args) => this.emit('show-choice-list', ...args)),
+ authServices.connect('mechanisms-changed',
+ (_, ...args) => this._onMechanismsChanged(...args)),
+ authServices.connect('web-login',
+ (_, ...args) => this.emit('web-login', ...args)),
+ ];
+ };
+
+ this._authServicesSSSDSwitchableSignalIds =
+ connectSignals(this._authServicesSSSDSwitchable);
+ this._authServicesLegacySignalIds =
+ connectSignals(this._authServicesLegacy);
}
_verificationFailed(serviceName, canRetry) {
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index 9c858f7269..26da94b624 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -182,7 +182,14 @@ var WebLoginDialog = GObject.registerClass({
}
_updateButtons(buttons) {
+ this._buttonBox.get_children().forEach(b => {
+ if (b._clickedSignalId) {
+ b.disconnect(b._clickedSignalId);
+ b._clickedSignalId = 0;
+ }
+ });
this._buttonBox.destroy_all_children();
+
this._cancelButton = this._addButton({
label: _('Cancel'),
action: () => this.emit('cancel'),
@@ -202,11 +209,11 @@ var WebLoginDialog = GObject.registerClass({
}),
});
- button.connectObject('clicked', () => {
+ button._clickedSignalId = button.connect('clicked', () => {
if (b.needsLoading)
this._startLoading();
b.action();
- }, this);
+ });
button.default = b.default;
--
2.51.0
From bcf392cbdac51d1bb1fb2e161c674bc4bd3286a6 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 15:12:16 +0100
Subject: [PATCH 06/30] gdm: Use promisify adding two params
This is how it works in this old version
---
js/gdm/authServices.js | 12 +++++-------
js/gdm/util.js | 7 ++++++-
js/gdm/webLogin.js | 2 +-
js/ui/qrCode.js | 2 +-
4 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index 88462cf17e..3cb1985817 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -9,13 +9,11 @@ const PasskeyDeviceManager = imports.misc.passkeyDeviceManager;
const SmartcardManager = imports.misc.smartcardManager;
const Util = imports.gdm.util;
-Gio._promisify(Gdm.Client.prototype, 'open_reauthentication_channel');
-Gio._promisify(Gdm.Client.prototype, 'get_user_verifier');
-Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_begin_verification_for_user');
-Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_begin_verification');
-Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_answer_query');
-Gio._promisify(Gdm.UserVerifierChoiceListProxy.prototype, 'call_select_choice');
-Gio._promisify(Gdm.UserVerifierCustomJSONProxy.prototype, 'call_reply');
+Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_begin_verification_for_user', 'call_begin_verification_for_user_finish');
+Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_begin_verification', 'call_begin_verification_finish');
+Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_answer_query', 'call_answer_query_finish');
+Gio._promisify(Gdm.UserVerifierChoiceListProxy.prototype, 'call_select_choice', 'call_select_choice_finish');
+Gio._promisify(Gdm.UserVerifierCustomJSONProxy.prototype, 'call_reply', 'call_reply_finish');
var AuthServices = GObject.registerClass({
Signals: {
diff --git a/js/gdm/util.js b/js/gdm/util.js
index 85de597d33..4aeec5b02a 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -3,7 +3,7 @@
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor,
InitError, isSelectable, getIconName */
-const { Clutter, Gio, GLib } = imports.gi;
+const { Clutter, Gdm, Gio, GLib } = imports.gi;
const Signals = imports.signals;
const Batch = imports.gdm.batch;
@@ -13,6 +13,11 @@ const Params = imports.misc.params;
const { AuthServicesLegacy } = imports.gdm.authServicesLegacy;
const { AuthServicesSSSDSwitchable } = imports.gdm.authServicesSSSDSwitchable;
+Gio._promisify(Gdm.Client.prototype, 'open_reauthentication_channel', 'open_reauthentication_channel_finish');
+Gio._promisify(Gdm.Client.prototype, 'get_user_verifier', 'get_user_verifier_finish');
+Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_begin_verification_for_user', 'call_begin_verification_for_user_finish');
+Gio._promisify(Gdm.UserVerifierProxy.prototype, 'call_begin_verification', 'call_begin_verification_finish');
+
var FADE_ANIMATION_TIME = 160;
var CLONE_FADE_ANIMATION_TIME = 250;
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index 26da94b624..f4972144fa 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -9,7 +9,7 @@ const Params = imports.misc.params;
const { Spinner } = imports.ui.animation;
const { QrCode } = imports.ui.qrCode;
-Gio._promisify(GnomeQR, 'generate_qr_code_async');
+Gio._promisify(GnomeQR, 'generate_qr_code_async', 'generate_qr_code_finish');
const QR_CODE_SIZE = 150;
const WEB_LOGIN_SPINNER_SIZE = 35;
diff --git a/js/ui/qrCode.js b/js/ui/qrCode.js
index b53508c2dd..547ad7d153 100644
--- a/js/ui/qrCode.js
+++ b/js/ui/qrCode.js
@@ -2,7 +2,7 @@
const { Clutter, Cogl, Gio, GnomeQR, GObject, St } = imports.gi;
-Gio._promisify(GnomeQR, 'generate_qr_code_async');
+Gio._promisify(GnomeQR, 'generate_qr_code_async', 'generate_qr_code_finish');
const QR_CODE_DEFAULT_SIZE = 150;
const QR_CODE_TRANSPARENT_COLOR = new GnomeQR.Color({alpha: 0});
--
2.51.0
From 74a94cb0c34413d45ef2e1d599822c25c434e1b8 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 13:52:50 +0100
Subject: [PATCH 07/30] gdm: Use timeout_add_seconds instead of once
_once type doesn't exist in this old glib version
---
js/gdm/authServices.js | 7 +++++--
js/gdm/authServicesSSSDSwitchable.js | 3 ++-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index 3cb1985817..003b4836a6 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -277,8 +277,11 @@ var AuthServices = GObject.registerClass({
_waitPendingMessages() {
const cancellable = this._cancellable;
- const timeoutId = GLib.timeout_add_seconds_once(GLib.PRIORITY_DEFAULT, 10,
- () => cancellable.cancel());
+ const timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 10,
+ () => {
+ cancellable.cancel();
+ return GLib.SOURCE_REMOVE;
+ });
const {promise, resolve, reject} = Promise.withResolvers();
const task = Gio.Task.new(this, cancellable, () => {
diff --git a/js/gdm/authServicesSSSDSwitchable.js b/js/gdm/authServicesSSSDSwitchable.js
index 601f4cd295..48c1c020fb 100644
--- a/js/gdm/authServicesSSSDSwitchable.js
+++ b/js/gdm/authServicesSSSDSwitchable.js
@@ -195,7 +195,7 @@ var AuthServicesSSSDSwitchable = GObject.registerClass({
if (!timeout)
return;
- this._webLoginTimeoutId = GLib.timeout_add_seconds_once(GLib.PRIORITY_DEFAULT,
+ this._webLoginTimeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT,
timeout, () => {
if (this._selectedMechanism?.role !== Constants.WEB_LOGIN_ROLE_NAME)
webLoginMechanism.needsRefresh = true;
@@ -203,6 +203,7 @@ var AuthServicesSSSDSwitchable = GObject.registerClass({
this.emit('reset', {softReset: true});
this._webLoginTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
});
}
--
2.51.0
From aff9353c2f80c15111f9b7f772b5fa45277251fd Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 13:56:56 +0100
Subject: [PATCH 08/30] gdm: fix Promise.withResolvers
Use manual new Promise to extract them.
---
js/gdm/authServices.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/js/gdm/authServices.js b/js/gdm/authServices.js
index 003b4836a6..00d19004f3 100644
--- a/js/gdm/authServices.js
+++ b/js/gdm/authServices.js
@@ -283,7 +283,11 @@ var AuthServices = GObject.registerClass({
return GLib.SOURCE_REMOVE;
});
- const {promise, resolve, reject} = Promise.withResolvers();
+ let resolve, reject;
+ const promise = new Promise((_resolve, _reject) => {
+ resolve = _resolve;
+ reject = _reject;
+ });
const task = Gio.Task.new(this, cancellable, () => {
try {
const res = task.propagate_boolean();
--
2.51.0
From fdad9ac3e5bb6699d835d23a50033244fefc6907 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 19:33:38 +0100
Subject: [PATCH 09/30] data/theme: Add new icons to theme gresource
They were in a different icons gresource that doesn't exist in 40 vesion
---
data/gnome-shell-theme.gresource.xml | 2 ++
data/icons/meson.build | 1 +
2 files changed, 3 insertions(+)
diff --git a/data/gnome-shell-theme.gresource.xml b/data/gnome-shell-theme.gresource.xml
index 7857f4407b..4f697f88df 100644
--- a/data/gnome-shell-theme.gresource.xml
+++ b/data/gnome-shell-theme.gresource.xml
@@ -4,6 +4,8 @@
<file>calendar-today.svg</file>
<file alias="icons/scalable/status/carousel-arrow-next-24-symbolic.svg">carousel-arrow-next-24-symbolic.svg</file>
<file alias="icons/scalable/status/carousel-arrow-back-24-symbolic.svg">carousel-arrow-back-24-symbolic.svg</file>
+ <file alias="icons/scalable/status/fingerprint-auth-symbolic.svg">../icons/scalable/status/fingerprint-auth-symbolic.svg</file>
+ <file alias="icons/scalable/status/vcard-symbolic.svg">../icons/scalable/status/vcard-symbolic.svg</file>
<file>checkbox-focused.svg</file>
<file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file>
diff --git a/data/icons/meson.build b/data/icons/meson.build
index eff6e4b530..44e2b164a3 100644
--- a/data/icons/meson.build
+++ b/data/icons/meson.build
@@ -1 +1,2 @@
install_subdir('hicolor', install_dir: icondir)
+install_subdir('scalable', install_dir: icondir)
--
2.51.0
From e0b648ce306e29ecb754711700d0b95aa4ed8769 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Mon, 15 Dec 2025 13:34:27 +0100
Subject: [PATCH 10/30] gdm/authmenuButton: Use None ornament
NOT_DOT doesn't exist.
---
js/gdm/authMenuButton.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index e58c331b45..9a02b0cb05 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -236,7 +236,7 @@ var AuthMenuButton = GObject.registerClass({
_updateOrnament() {
for (const menuItem of this._items.values())
- menuItem.setOrnament(PopupMenu.Ornament.NO_DOT);
+ menuItem.setOrnament(PopupMenu.Ornament.NONE);
for (const itemKey of this._activeItems) {
const menuItem = this._getMenuItem(JSON.parse(itemKey));
--
2.51.0
From 6a246865fb5a2da8724aafea34995d5aab81c263 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 20:33:15 +0100
Subject: [PATCH 11/30] gdm/authMenuButton: Add proper style classes to button
---
js/gdm/authMenuButton.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index 9a02b0cb05..64dcf1a3f4 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -146,7 +146,7 @@ var AuthMenuButton = GObject.registerClass({
params.sectionOrder ??= [];
super._init({
...params,
- style_class: 'login-dialog-button login-dialog-auth-menu-button',
+ style_class: 'modal-dialog-button button login-dialog-auth-menu-button',
reactive: true,
track_hover: true,
can_focus: true,
--
2.51.0
From 11ad6201e3c032674d4e58f44d9fea9820fb4234 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 2 Jan 2026 14:48:42 +0100
Subject: [PATCH 12/30] gdm/authMenuButton: Add style to indicator description
This is needed to set its color in the lockscreen.
---
data/theme/gnome-shell-sass/widgets/_login-dialog.scss | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss
index f3aeed4bf3..29c6803082 100644
--- a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss
+++ b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss
@@ -123,6 +123,10 @@ $_gdm_fg: $osd_fg_color;
}
}
+.login-dialog-auth-menu-button-indicator-description {
+ color: $osd_fg_color;
+}
+
.login-dialog-bottom-button-group {
padding: 32px;
spacing: 16px;
--
2.51.0
From d7c9b074f8cb0bf2295daa3a518776cae023a039 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 17:57:03 +0100
Subject: [PATCH 13/30] gdm/authMenuButton: Add no-op () instead of null
---
js/gdm/authMenuButton.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index 64dcf1a3f4..a211ebe0d8 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -475,7 +475,7 @@ class AuthMenuButtonIndicator extends AuthMenuButton {
this._descriptionLabel, 'visible',
GObject.BindingFlags.SYNC_CREATE,
(bind, source) => [true, !!source],
- null);
+ () => {});
container.add_child(this._descriptionLabel);
return container;
--
2.51.0
From 5fb0f23fda55d433a08db68920ed896cdf9e3d08 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Thu, 2 Apr 2026 19:38:34 +0200
Subject: [PATCH 14/30] gdm/authMenuButton: Ensure visible of description is
properly binded to
its text
---
js/gdm/authMenuButton.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index a211ebe0d8..3dafd87630 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -510,6 +510,7 @@ class AuthMenuButtonIndicator extends AuthMenuButton {
updateDescriptionLabel() {
const [item] = this._items.size === 1 ? this.getItems() : [];
this._descriptionLabel.text = item?.description ?? '';
+ this._descriptionLabel.visible = !!this._descriptionLabel.text;
}
// Override to force visibility even when there's only one item
--
2.51.0
From e9abaf90b24df1f98108ab48c5d00ec87a6d5c9e Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 13:38:06 +0100
Subject: [PATCH 15/30] Fix foreach in wrong type
Map.keys() returns an iterator which doesn't have .forEach() in older
SpiderMonkey. Wrapped it with [...] to convert to an array first.
---
js/gdm/authMenuButton.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index 3dafd87630..393dc5da4b 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -307,7 +307,7 @@ var AuthMenuButton = GObject.registerClass({
this._items.delete(itemKey);
});
- this._sections.keys().forEach(sectionName => {
+ [...this._sections.keys()].forEach(sectionName => {
const itemsInSection = this._findItems({sectionName});
if (itemsInSection.length === 0) {
const section = this._sections.get(sectionName);
--
2.51.0
From 2e28cf05ef0033c42c6bb54839184701718bf48a Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 12:56:24 +0100
Subject: [PATCH 16/30] Change ??= by if statement
This old js version doesn't support it.
---
js/gdm/authMenuButton.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/js/gdm/authMenuButton.js b/js/gdm/authMenuButton.js
index 393dc5da4b..c5e864c686 100644
--- a/js/gdm/authMenuButton.js
+++ b/js/gdm/authMenuButton.js
@@ -143,7 +143,8 @@ var AuthMenuButton = GObject.registerClass({
},
}, class AuthMenuButton extends St.Button {
_init(params) {
- params.sectionOrder ??= [];
+ if (params.sectionOrder === undefined || params.sectionOrder === null)
+ params.sectionOrder = [];
super._init({
...params,
style_class: 'modal-dialog-button button login-dialog-auth-menu-button',
@@ -449,7 +450,8 @@ var AuthMenuButton = GObject.registerClass({
var AuthMenuButtonIndicator = GObject.registerClass(
class AuthMenuButtonIndicator extends AuthMenuButton {
_init(params = {}) {
- params.readOnly ??= true;
+ if (params.readOnly === undefined || params.readOnly === null)
+ params.readOnly = true;
super._init(params);
this.add_style_class_name('login-dialog-auth-menu-button-indicator');
--
2.51.0
From f55cd19afd2028dda3af2bb1490c13ca06caf759 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 18:26:49 +0100
Subject: [PATCH 17/30] gdm/util: Don't return a promise in
wait-pending-messages
The callback of wait-pending-messages was returning a Promise.
That was causing the error "Could not guess unspecified GValue type".
Avoid it embracing the callback with {} so the return isn't passed.
---
js/gdm/util.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/util.js b/js/gdm/util.js
index 4aeec5b02a..629ba1b629 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -531,7 +531,7 @@ var ShellUserVerifier = class {
authServices.connect('queue-priority-message',
(_, ...args) => this._queuePriorityMessage(...args)),
authServices.connect('wait-pending-messages',
- (_, ...args) => this._waitPendingMessages(...args)),
+ (_, ...args) => {this._waitPendingMessages(...args);}),
authServices.connect('filter-messages',
(_, ...args) => this._filterServiceMessages(...args)),
authServices.connect('verification-failed',
--
2.51.0
From 179858faf126b93d734452ebb522383b07bf0a1d Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 16:26:57 +0100
Subject: [PATCH 18/30] gdm/authPrompt: Fixes
1. Don't set directly icon_name in StButton
2. Guard setting text on entries on clear
3. Use Const instead of GdmUtil to get standard service_names
4. Inputwell was an extra container, in old version directly store in
this.
5. On setChoiceList, don't hide _message. This keeps the same layout
avoiding height increase of mainBox
6. On vfunc_key_press_event, handle event more explicitly instead of
just calling event.
---
js/gdm/authPrompt.js | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
index 6996dac18b..7f683b2ba0 100644
--- a/js/gdm/authPrompt.js
+++ b/js/gdm/authPrompt.js
@@ -146,8 +146,17 @@ var AuthPrompt = GObject.registerClass({
if (keyPressEvent.keyval == Clutter.KEY_Escape)
this.cancel();
- if (this._preemptiveInput && !this._pendingActivate)
- return this._entry.clutter_text.event(keyPressEvent, false);
+ if (this._preemptiveInput && !this._pendingActivate) {
+ const unichar = keyPressEvent.unicode_value;
+ if (keyPressEvent.keyval === Clutter.KEY_Return &&
+ this._entry.clutter_text.text) {
+ this._pendingActivate = true;
+ } else if (GLib.unichar_isprint(unichar)) {
+ this._entry.clutter_text.insert_text(unichar,
+ this._entry.clutter_text.cursor_position);
+ }
+ return Clutter.EVENT_STOP;
+ }
return super.vfunc_key_press_event(keyPressEvent);
}
@@ -200,7 +209,7 @@ var AuthPrompt = GObject.registerClass({
},
});
});
- this._inputWell.add_child(this._authList);
+ this.add_child(this._authList);
// Use an insensitive button for the auth list title
// to get the same style as the auth list buttons
@@ -291,7 +300,7 @@ var AuthPrompt = GObject.registerClass({
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: false,
- icon_name: 'go-next-symbolic',
+ child: new St.Icon({icon_name: 'go-next-symbolic'}),
});
this._nextButton.connect('clicked', () => this._activateNext());
this._nextButton.add_style_pseudo_class('default');
@@ -322,7 +331,7 @@ var AuthPrompt = GObject.registerClass({
}
});
this._webLoginDialog.connect('loading', () => this.emit('loading', this._webLoginDialog.isLoading));
- this._inputWell.add_child(this._webLoginDialog);
+ this.add_child(this._webLoginDialog);
}
_updateShowPasswordIcon() {
@@ -638,8 +647,10 @@ var AuthPrompt = GObject.registerClass({
});
if (!reuseEntryText) {
- this._entry.text = '';
- this._inactiveEntry.text = '';
+ if (this._entry)
+ this._entry.text = '';
+ if (this._inactiveEntry)
+ this._inactiveEntry.text = '';
}
this._entryArea.hide();
@@ -712,8 +723,6 @@ var AuthPrompt = GObject.registerClass({
}
this._entryArea.hide();
- if (this._message.text === '')
- this._message.hide();
this._fadeInElement(this._authList);
}
--
2.51.0
From bf8ecd9f1dec3a58c9734ae0b6bfb5ab6f7e0e0d Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 18:48:48 +0100
Subject: [PATCH 19/30] gdm/authList: Use vertical instead of orientation
orientation isn't a valid property for St.BoxLayout
---
js/gdm/authList.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/js/gdm/authList.js b/js/gdm/authList.js
index 6eb34f6d97..b5072fe945 100644
--- a/js/gdm/authList.js
+++ b/js/gdm/authList.js
@@ -32,7 +32,7 @@ const ItemIconPopup = class extends PopupMenu.PopupMenu {
this.actor.add_style_class_name('login-dialog-item-icon-popup');
const labels = new St.BoxLayout({
- orientation: Clutter.Orientation.VERTICAL,
+ vertical: true,
style_class: 'login-dialog-item-icon-popup-labels',
});
labels.add_child(new St.Label({text: title}));
@@ -95,7 +95,7 @@ const AuthListItem = GObject.registerClass({
x_expand: true,
});
this._labelBox = new St.BoxLayout({
- orientation: Clutter.Orientation.VERTICAL,
+ vertical: true,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true,
});
@@ -171,7 +171,7 @@ var AuthList = GObject.registerClass({
}, class AuthList extends St.BoxLayout {
_init() {
super._init({
- orientation: Clutter.Orientation.VERTICAL,
+ vertical: true,
style_class: 'login-dialog-auth-list-layout',
y_align: Clutter.ActorAlign.CENTER,
x_expand: true,
--
2.51.0
From 2c10304549a203ea1e5fca2ad6e08e0ee5b0f701 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 17:47:17 +0100
Subject: [PATCH 20/30] gdm/authList: Use St.Icon instead of iconName as
property
---
js/gdm/authList.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/authList.js b/js/gdm/authList.js
index b5072fe945..0c8ef1f18d 100644
--- a/js/gdm/authList.js
+++ b/js/gdm/authList.js
@@ -62,7 +62,7 @@ class ItemIcon extends St.Button {
_init(iconName, iconTitle, iconSubtitle) {
super._init({
style_class: 'login-dialog-item-icon',
- iconName,
+ child: new St.Icon({icon_name: iconName}),
});
this._popup = new ItemIconPopup(this, iconTitle, iconSubtitle);
--
2.51.0
From 480c3f08428161c3f5ef2e85d7ddc7e9a0c42737 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 19:02:04 +0100
Subject: [PATCH 21/30] gdm/loginDialog: Use propper icon name for
authMenuButton
---
js/gdm/loginDialog.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
index f59663401b..ab5b9c3d77 100644
--- a/js/gdm/loginDialog.js
+++ b/js/gdm/loginDialog.js
@@ -445,7 +445,7 @@ var LoginDialog = GObject.registerClass({
_createAuthMenuButton() {
this._authMenuButton = new AuthMenuButton.AuthMenuButton({
title: _('Login Options'),
- iconName: 'cog-wheel-symbolic',
+ iconName: 'emblem-system-symbolic',
sectionOrder: [_PRIMARY_LOGIN_METHOD_SECTION_NAME, _SESSION_TYPE_SECTION_NAME],
});
this._authMenuButton.updateSensitivity(false);
--
2.51.0
From 56de4883ea483307607d148e2880da220cf782c5 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Wed, 1 Apr 2026 13:05:30 +0200
Subject: [PATCH 22/30] gdm/LoginDialog: Reduce min height of authprompt
authprompt is smaller so min height has to be smaller
---
js/gdm/loginDialog.js | 2 +-
js/ui/unlockDialog.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
index ab5b9c3d77..cdf6f23e2d 100644
--- a/js/gdm/loginDialog.js
+++ b/js/gdm/loginDialog.js
@@ -34,7 +34,7 @@ const UserWidget = imports.ui.userWidget;
const _FADE_ANIMATION_TIME = 250;
const _SCROLL_ANIMATION_TIME = 500;
-const _FIXED_TOP_ACTOR_HEIGHT = 400;
+const _FIXED_TOP_ACTOR_HEIGHT = 300;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _PRIMARY_LOGIN_METHOD_SECTION_NAME = _('Login Options');
const _SESSION_TYPE_SECTION_NAME = _('Session Type');
diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js
index 654959190e..477edbe8fd 100644
--- a/js/ui/unlockDialog.js
+++ b/js/ui/unlockDialog.js
@@ -32,7 +32,7 @@ const BLUR_SIGMA = 60;
const SUMMARY_ICON_SIZE = 32;
-const FIXED_PROMPT_HEIGHT = 400;
+const FIXED_PROMPT_HEIGHT = 300;
var NotificationsBox = GObject.registerClass({
Signals: { 'wake-up-screen': {} },
--
2.51.0
From 074089190aad31dc52f4da9748a2bda7cb04f239 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 12 Dec 2025 16:21:02 +0100
Subject: [PATCH 23/30] gdm/webLogin: Some fixes for backport
1. Use connect with notify::reactive because bind_property_full is not available
2. Use vertical property because orientation isn't available
3. Set '' as the default value for message
---
js/gdm/webLogin.js | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index f4972144fa..d2e947f646 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -144,14 +144,13 @@ var WebLoginDialog = GObject.registerClass({
y_expand: true,
visible: false,
});
- this.bind_property_full('reactive',
- this, 'opacity',
- GObject.BindingFlags.SYNC_CREATE,
- (_bind, source) => [true, source ? 255 : 128],
- null);
+ this.connect('notify::reactive', () => {
+ this.opacity = this.reactive ? 255 : 128;
+ });
+ this.opacity = this.reactive ? 255 : 128;
this._contentBox = new St.BoxLayout({
- orientation: Clutter.Orientation.VERTICAL,
+ vertical: true,
x_expand: true,
y_expand: true,
});
@@ -161,7 +160,7 @@ var WebLoginDialog = GObject.registerClass({
this._contentBox.add_child(this._webLoginPrompt);
this._buttonBox = new St.BoxLayout({
- orientation: Clutter.Orientation.HORIZONTAL,
+ vertical: false,
x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
});
@@ -290,7 +289,7 @@ var WebLoginIntro = GObject.registerClass(
class WebLoginIntro extends St.Button {
_init(params) {
const {message} = Params.parse(params, {
- message: null,
+ message: '',
});
const label = new St.Label({
--
2.51.0
From 908cce536d7933bb09138e4022af46813fe82092 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Mon, 15 Dec 2025 13:36:31 +0100
Subject: [PATCH 24/30] gdm/webLogin: Vertically center align labels of buttons
---
js/gdm/webLogin.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index d2e947f646..062ad5f309 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -205,6 +205,7 @@ var WebLoginDialog = GObject.registerClass({
child: new St.Label({
text: b.label,
style_class: 'web-login-button-label',
+ y_align: Clutter.ActorAlign.CENTER,
}),
});
@@ -295,6 +296,7 @@ class WebLoginIntro extends St.Button {
const label = new St.Label({
text: message,
style_class: 'web-login-button-label',
+ y_align: Clutter.ActorAlign.CENTER,
});
super._init({
@@ -304,6 +306,7 @@ class WebLoginIntro extends St.Button {
reactive: true,
can_focus: true,
child: label,
+ y_align: Clutter.ActorAlign.CENTER,
});
}
--
2.51.0
From 0e08e9a99057f24e3f8e57d66115d8368d00f2d0 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Mon, 15 Dec 2025 13:53:08 +0100
Subject: [PATCH 25/30] gdm/webLogin: Set data to qr texture with the right
args
This old version has a different signature for setting text data.
---
js/ui/qrCode.js | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/js/ui/qrCode.js b/js/ui/qrCode.js
index 547ad7d153..adf6e40051 100644
--- a/js/ui/qrCode.js
+++ b/js/ui/qrCode.js
@@ -87,14 +87,12 @@ var QrCode = GObject.registerClass({
GnomeQR.EccLevel.LOW,
cancellable);
- const coglContext = global.stage.context.get_backend().get_cogl_context();
const bpp = Cogl.pixel_format_get_bytes_per_pixel(Cogl.PixelFormat.RGBA_8888, 0);
const rowStride = qrSize * bpp;
const content = St.ImageContent.new_with_preferred_size(qrSize, qrSize);
- content.set_bytes(
- coglContext,
- pixelData,
+ content.set_data(
+ pixelData.get_data(),
Cogl.PixelFormat.RGBA_8888,
qrSize,
qrSize,
--
2.51.0
From 97ac6d29ff531f15dcadd907164ae5c4609bb016 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 12:30:43 +0100
Subject: [PATCH 26/30] gdm/webLogin: Make spinner size 16
In old versions spinner icon would be duplicated to fill the space
instead of scaled.
---
js/gdm/webLogin.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/gdm/webLogin.js b/js/gdm/webLogin.js
index 062ad5f309..ac79816699 100644
--- a/js/gdm/webLogin.js
+++ b/js/gdm/webLogin.js
@@ -12,7 +12,7 @@ const { QrCode } = imports.ui.qrCode;
Gio._promisify(GnomeQR, 'generate_qr_code_async', 'generate_qr_code_finish');
const QR_CODE_SIZE = 150;
-const WEB_LOGIN_SPINNER_SIZE = 35;
+const WEB_LOGIN_SPINNER_SIZE = 16;
const URL_LABEL_LONG_THRESHOLD = 45;
var WebLoginPrompt = GObject.registerClass(
--
2.51.0
From 36e72660620d28929d250ee958df0eb0834a163d Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 12:31:48 +0100
Subject: [PATCH 27/30] gdm/unlockDialog: Use proper icon for gear
In old versions the icon name is called 'emblem-system-symbolic'
---
js/ui/unlockDialog.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js
index 477edbe8fd..85b512aa85 100644
--- a/js/ui/unlockDialog.js
+++ b/js/ui/unlockDialog.js
@@ -646,7 +646,7 @@ var UnlockDialog = GObject.registerClass({
// Login Options button
this._authMenuButton = new AuthMenuButton.AuthMenuButton({
title: _('Login Options'),
- iconName: 'cog-wheel-symbolic',
+ iconName: 'emblem-system-symbolic',
});
this._authMenuButton.connect('active-item-changed', () => {
const authMechanism = this._authMenuButton.getActiveItem();
--
2.51.0
From 39d93c9d86f99e3ed46544d052ceae188e2adc25 Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 27 Mar 2026 17:53:33 +0100
Subject: [PATCH 28/30] gdm/unlockDialog: Use vertical boolean instead
orientation
---
js/ui/unlockDialog.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js
index 85b512aa85..ab4141e2c3 100644
--- a/js/ui/unlockDialog.js
+++ b/js/ui/unlockDialog.js
@@ -335,7 +335,7 @@ class UnlockDialogClock extends St.BoxLayout {
_init() {
super._init({
style_class: 'unlock-dialog-clock',
- orientation: Clutter.Orientation.VERTICAL,
+ vertical: true,
y_align: Clutter.ActorAlign.CENTER,
});
--
2.51.0
From 0b4f7dcb4ec6821e38888898a8298a1e8a5e88bf Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Thu, 2 Apr 2026 18:55:31 +0200
Subject: [PATCH 29/30] gdm/unlockDialog: Don't use timeout_add_once
---
js/gdm/authServicesLegacy.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/js/gdm/authServicesLegacy.js b/js/gdm/authServicesLegacy.js
index 5955aeadff..4c5a49effa 100644
--- a/js/gdm/authServicesLegacy.js
+++ b/js/gdm/authServicesLegacy.js
@@ -136,12 +136,13 @@ var AuthServicesLegacy = GObject.registerClass({
this._fingerprintReadyTimeoutId !== 0)
return;
- this._fingerprintReadyTimeoutId = GLib.timeout_add_once(
+ this._fingerprintReadyTimeoutId = GLib.timeout_add(
GLib.PRIORITY_DEFAULT,
FINGERPRINT_READY_TIMEOUT_MS,
() => {
this._fingerprintReadyTimeoutId = 0;
this._setFingerprintReady(true);
+ return GLib.SOURCE_REMOVE;
});
}
--
2.51.0
From 17a21d8e27fddb369977c50e9e62de177222120b Mon Sep 17 00:00:00 2001
From: Joan Torres Lopez <joantolo@redhat.com>
Date: Fri, 26 Dec 2025 12:34:11 +0100
Subject: [PATCH 30/30] fingerprintManager: Update getDefaultService using
remote
This is how async methods are called in this version.
---
js/misc/fingerprintManager.js | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/js/misc/fingerprintManager.js b/js/misc/fingerprintManager.js
index 151e787e0b..4467e0bfa9 100644
--- a/js/misc/fingerprintManager.js
+++ b/js/misc/fingerprintManager.js
@@ -64,23 +64,23 @@ var FingerprintManager = GObject.registerClass({
}
async checkReaderType(cancellable = null) {
- try {
- // Wrappers don't support null cancellable, so let's ignore it in case
- const args = cancellable ? [cancellable] : [];
- const [devicePath] =
- await this._fingerprintManagerProxy.GetDefaultDeviceAsync(...args);
-
- const fprintDeviceProxy = this._getFprintDeviceProxy(devicePath);
- await fprintDeviceProxy.init_async(GLib.PRIORITY_DEFAULT, cancellable ?? null);
-
- const fingerprintReaderKey = fprintDeviceProxy['scan-type'].toUpperCase();
- const fingerprintReaderType = FingerprintReaderType[fingerprintReaderKey];
- this._setFingerprintReaderType(fingerprintReaderType);
- } catch (e) {
- if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+ this._fingerprintManagerProxy.GetDefaultDeviceRemote((result, error) => {
+ if (error) {
+ this._handleFingerprintError(error);
return;
- this._handleFingerprintError(e);
- }
+ }
+
+ try {
+ const [devicePath] = result;
+ const fprintDeviceProxy = this._getFprintDeviceProxy(devicePath);
+ fprintDeviceProxy.init(cancellable ?? null);
+ const fingerprintReaderKey = fprintDeviceProxy['scan-type'].toUpperCase();
+ const fingerprintReaderType = FingerprintReaderType[fingerprintReaderKey];
+ this._setFingerprintReaderType(fingerprintReaderType);
+ } catch (e) {
+ this._handleFingerprintError(e);
+ }
+ });
}
async _initFingerprintManagerProxy() {
--
2.51.0