commit 892530c007a92fc58b273843df68da3ac12d0d10 Author: CentOS Sources Date: Tue Nov 15 01:27:16 2022 -0500 import gnome-shell-40.10-3.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d85369 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/gnome-shell-40.10.tar.xz diff --git a/.gnome-shell.metadata b/.gnome-shell.metadata new file mode 100644 index 0000000..780dfaf --- /dev/null +++ b/.gnome-shell.metadata @@ -0,0 +1 @@ +c955a004fb650a83863d1151e3adbbd6758b1c2e SOURCES/gnome-shell-40.10.tar.xz diff --git a/SOURCES/0001-Revert-dash-Subtract-vertical-margins-from-availHeig.patch b/SOURCES/0001-Revert-dash-Subtract-vertical-margins-from-availHeig.patch new file mode 100644 index 0000000..a62d76e --- /dev/null +++ b/SOURCES/0001-Revert-dash-Subtract-vertical-margins-from-availHeig.patch @@ -0,0 +1,25 @@ +From a8c8b7ef31f7219157b94148b771f6f663928dea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 19 Apr 2022 19:17:48 +0200 +Subject: [PATCH] Revert "dash: Subtract vertical margins from availHeight" + +This reverts commit 0de0a1f5940784eb4a7ca9ecf5e92f5277ceb0d8. +--- + js/ui/dash.js | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/js/ui/dash.js b/js/ui/dash.js +index f35cc2e25..0f1ca2c4c 100644 +--- a/js/ui/dash.js ++++ b/js/ui/dash.js +@@ -610,7 +610,6 @@ var Dash = GObject.registerClass({ + (iconChildren.length - 1) * spacing; + + let availHeight = this._maxHeight; +- availHeight -= this.margin_top + this.margin_bottom; + availHeight -= this._background.get_theme_node().get_vertical_padding(); + availHeight -= themeNode.get_vertical_padding(); + availHeight -= buttonHeight - iconHeight; +-- +2.35.1 + diff --git a/SOURCES/0001-Update-generated-stylesheets.patch b/SOURCES/0001-Update-generated-stylesheets.patch new file mode 100644 index 0000000..4133dd6 --- /dev/null +++ b/SOURCES/0001-Update-generated-stylesheets.patch @@ -0,0 +1,364 @@ +From 678cdd9e0da851da78527fa827d71a80273510b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 8 Feb 2022 14:18:04 -0500 + +--- + data/theme/gnome-shell-high-contrast.css | 36 ++++++++++++++++++++++++ + data/theme/gnome-shell.css | 36 ++++++++++++++++++++++++ + 2 files changed, 72 insertions(+) + +diff --git a/data/theme/gnome-shell-high-contrast.css b/data/theme/gnome-shell-high-contrast.css +index b73f407..90f363c 100644 +--- a/data/theme/gnome-shell-high-contrast.css ++++ b/data/theme/gnome-shell-high-contrast.css +@@ -1223,60 +1223,63 @@ StScrollBar { + -panel-corner-border-color: transparent; + -panel-corner-opacity: 1; + transition-duration: 250ms; } + #panel .panel-button { + font-weight: bold; + color: #ddd; + -natural-hpadding: 12px; + -minimum-hpadding: 6px; + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 99px; } + #panel .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 99px; } + #panel .panel-button:hover, #panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.2); } + #panel .panel-button.clock-display:hover, #panel .panel-button.clock-display:active, #panel .panel-button.clock-display:overview, #panel .panel-button.clock-display:focus, #panel .panel-button.clock-display:checked { + box-shadow: none; } + #panel .panel-button.clock-display:hover .clock, #panel .panel-button.clock-display:active .clock, #panel .panel-button.clock-display:overview .clock, #panel .panel-button.clock-display:focus .clock, #panel .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.2); } + #panel .panel-button .system-status-icon { + icon-size: 1.09em; + padding: 5px; + margin: 0 4px; } + #panel .panel-button .panel-status-indicators-box .system-status-icon, + #panel .panel-button .panel-status-menu-box .system-status-icon { + margin: 0; } + #panel .panel-button .app-menu-icon { + -st-icon-style: symbolic; } ++ #panel .panel-button .panel-logo-icon { ++ padding-right: .4em; ++ icon-size: 1em; } + #panel #panelActivities.panel-button { + -natural-hpadding: 18px; } + #panel.unlock-screen .panel-button:hover, #panel.unlock-screen .panel-button:active, #panel.unlock-screen .panel-button:overview, #panel.unlock-screen .panel-button:focus, #panel.unlock-screen .panel-button:checked, #panel.login-screen .panel-button:hover, #panel.login-screen .panel-button:active, #panel.login-screen .panel-button:overview, #panel.login-screen .panel-button:focus, #panel.login-screen .panel-button:checked, #panel:overview .panel-button:hover, #panel:overview .panel-button:active, #panel:overview .panel-button:overview, #panel:overview .panel-button:focus, #panel:overview .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15); } + #panel.unlock-screen .panel-button.clock-display:hover, #panel.unlock-screen .panel-button.clock-display:active, #panel.unlock-screen .panel-button.clock-display:overview, #panel.unlock-screen .panel-button.clock-display:focus, #panel.unlock-screen .panel-button.clock-display:checked, #panel.login-screen .panel-button.clock-display:hover, #panel.login-screen .panel-button.clock-display:active, #panel.login-screen .panel-button.clock-display:overview, #panel.login-screen .panel-button.clock-display:focus, #panel.login-screen .panel-button.clock-display:checked, #panel:overview .panel-button.clock-display:hover, #panel:overview .panel-button.clock-display:active, #panel:overview .panel-button.clock-display:overview, #panel:overview .panel-button.clock-display:focus, #panel:overview .panel-button.clock-display:checked { + box-shadow: none; } + #panel.unlock-screen .panel-button.clock-display:hover .clock, #panel.unlock-screen .panel-button.clock-display:active .clock, #panel.unlock-screen .panel-button.clock-display:overview .clock, #panel.unlock-screen .panel-button.clock-display:focus .clock, #panel.unlock-screen .panel-button.clock-display:checked .clock, #panel.login-screen .panel-button.clock-display:hover .clock, #panel.login-screen .panel-button.clock-display:active .clock, #panel.login-screen .panel-button.clock-display:overview .clock, #panel.login-screen .panel-button.clock-display:focus .clock, #panel.login-screen .panel-button.clock-display:checked .clock, #panel:overview .panel-button.clock-display:hover .clock, #panel:overview .panel-button.clock-display:active .clock, #panel:overview .panel-button.clock-display:overview .clock, #panel:overview .panel-button.clock-display:focus .clock, #panel:overview .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15); } + #panel .panel-status-indicators-box, + #panel .panel-status-menu-box { + spacing: 2px; } + #panel .power-status.panel-status-indicators-box { + spacing: 0; } + #panel .screencast-indicator, + #panel .remote-access-indicator { + color: #f57900; } + + #appMenu { + spacing: 6px; } + #appMenu .label-shadow { + color: transparent; } + + #appMenu .panel-status-menu-box { + padding: 0 6px; + spacing: 6px; } + + /* Activities Ripple */ + .ripple-box { + background-color: rgba(158, 196, 235, 0.3); + box-shadow: 0 0 2px 2px #4a90d9; +@@ -2039,74 +2042,107 @@ StScrollBar { + width: 2.18em; + height: 2.18em; + border-color: #202020; + background-color: #202020; } + .login-dialog .cancel-button StIcon, + .login-dialog .switch-user-button StIcon, + .login-dialog .login-dialog-session-list-button StIcon, + .unlock-dialog .cancel-button StIcon, + .unlock-dialog .switch-user-button StIcon, + .unlock-dialog .login-dialog-session-list-button StIcon { + icon-size: 1.09em; } + .login-dialog .caps-lock-warning-label, + .login-dialog .login-dialog-message-warning, + .unlock-dialog .caps-lock-warning-label, + .unlock-dialog .login-dialog-message-warning { + color: #eeeeec; } + + .login-dialog-logo-bin { + padding: 24px 0px; } + + .login-dialog-banner { + color: #d6d6d1; } + + .login-dialog-button-box { + width: 23em; + spacing: 5px; } + + .login-dialog-message { + text-align: center; } + ++.login-dialog-message-hint, .login-dialog-message { ++ color: #bebeb6; ++ min-height: 2.75em; } ++ + .login-dialog-user-selection-box { + padding: 100px 0px; } + + .login-dialog-not-listed-label { + padding-left: 2px; } + .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { + color: #eeeeec; } + + .login-dialog-not-listed-label { + font-size: 10pt; + font-weight: bold; + color: #a6a69b; + padding-top: 1em; } + ++.login-dialog-auth-list-view { ++ -st-vfade-offset: 1em; } ++ ++.login-dialog-auth-list { ++ spacing: 6px; ++ margin-left: 2em; } ++ ++.login-dialog-auth-list-title { ++ margin-left: 2em; } ++ ++.login-dialog-auth-list-item { ++ border-radius: 12px; ++ padding: 6px; ++ color: #a6a69b; } ++ .login-dialog-auth-list-item:focus, .login-dialog-auth-list-item:selected { ++ background-color: #215d9c; ++ color: #ffffff; } ++ ++.login-dialog-auth-list-label { ++ font-size: 13pt; ++ font-weight: bold; ++ padding-left: 15px; } ++ .login-dialog-auth-list-label:ltr { ++ padding-left: 14px; ++ text-align: left; } ++ .login-dialog-auth-list-label:rtl { ++ padding-right: 14px; ++ text-align: right; } ++ + .login-dialog-user-list-view { + -st-vfade-offset: 1em; } + + .login-dialog-user-list { + spacing: 12px; + width: 23em; } + .login-dialog-user-list:expanded .login-dialog-user-list-item:selected { + background-color: #215d9c; + color: #ffffff; } + .login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in { + border-right: 2px solid #215d9c; } + + .login-dialog-user-list-item { + border-radius: 12px; + padding: 6px; + color: #a6a69b; } + .login-dialog-user-list-item:ltr .user-widget { + padding-right: 1em; } + .login-dialog-user-list-item:rtl .user-widget { + padding-left: 1em; } + .login-dialog-user-list-item .login-dialog-timed-login-indicator { + height: 2px; + margin-top: 6px; + background-color: #eeeeec; } + .login-dialog-user-list-item:focus .login-dialog-timed-login-indicator { + background-color: #ffffff; } + + .user-widget-label { + color: #eeeeec; } + +diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css +index f93819b..d3d7fc8 100644 +--- a/data/theme/gnome-shell.css ++++ b/data/theme/gnome-shell.css +@@ -1223,60 +1223,63 @@ StScrollBar { + -panel-corner-border-color: transparent; + -panel-corner-opacity: 1; + transition-duration: 250ms; } + #panel .panel-button { + font-weight: bold; + color: #ddd; + -natural-hpadding: 12px; + -minimum-hpadding: 6px; + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 99px; } + #panel .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 99px; } + #panel .panel-button:hover, #panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.2); } + #panel .panel-button.clock-display:hover, #panel .panel-button.clock-display:active, #panel .panel-button.clock-display:overview, #panel .panel-button.clock-display:focus, #panel .panel-button.clock-display:checked { + box-shadow: none; } + #panel .panel-button.clock-display:hover .clock, #panel .panel-button.clock-display:active .clock, #panel .panel-button.clock-display:overview .clock, #panel .panel-button.clock-display:focus .clock, #panel .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.2); } + #panel .panel-button .system-status-icon { + icon-size: 1.09em; + padding: 5px; + margin: 0 4px; } + #panel .panel-button .panel-status-indicators-box .system-status-icon, + #panel .panel-button .panel-status-menu-box .system-status-icon { + margin: 0; } + #panel .panel-button .app-menu-icon { + -st-icon-style: symbolic; } ++ #panel .panel-button .panel-logo-icon { ++ padding-right: .4em; ++ icon-size: 1em; } + #panel #panelActivities.panel-button { + -natural-hpadding: 18px; } + #panel.unlock-screen .panel-button:hover, #panel.unlock-screen .panel-button:active, #panel.unlock-screen .panel-button:overview, #panel.unlock-screen .panel-button:focus, #panel.unlock-screen .panel-button:checked, #panel.login-screen .panel-button:hover, #panel.login-screen .panel-button:active, #panel.login-screen .panel-button:overview, #panel.login-screen .panel-button:focus, #panel.login-screen .panel-button:checked, #panel:overview .panel-button:hover, #panel:overview .panel-button:active, #panel:overview .panel-button:overview, #panel:overview .panel-button:focus, #panel:overview .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15); } + #panel.unlock-screen .panel-button.clock-display:hover, #panel.unlock-screen .panel-button.clock-display:active, #panel.unlock-screen .panel-button.clock-display:overview, #panel.unlock-screen .panel-button.clock-display:focus, #panel.unlock-screen .panel-button.clock-display:checked, #panel.login-screen .panel-button.clock-display:hover, #panel.login-screen .panel-button.clock-display:active, #panel.login-screen .panel-button.clock-display:overview, #panel.login-screen .panel-button.clock-display:focus, #panel.login-screen .panel-button.clock-display:checked, #panel:overview .panel-button.clock-display:hover, #panel:overview .panel-button.clock-display:active, #panel:overview .panel-button.clock-display:overview, #panel:overview .panel-button.clock-display:focus, #panel:overview .panel-button.clock-display:checked { + box-shadow: none; } + #panel.unlock-screen .panel-button.clock-display:hover .clock, #panel.unlock-screen .panel-button.clock-display:active .clock, #panel.unlock-screen .panel-button.clock-display:overview .clock, #panel.unlock-screen .panel-button.clock-display:focus .clock, #panel.unlock-screen .panel-button.clock-display:checked .clock, #panel.login-screen .panel-button.clock-display:hover .clock, #panel.login-screen .panel-button.clock-display:active .clock, #panel.login-screen .panel-button.clock-display:overview .clock, #panel.login-screen .panel-button.clock-display:focus .clock, #panel.login-screen .panel-button.clock-display:checked .clock, #panel:overview .panel-button.clock-display:hover .clock, #panel:overview .panel-button.clock-display:active .clock, #panel:overview .panel-button.clock-display:overview .clock, #panel:overview .panel-button.clock-display:focus .clock, #panel:overview .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15); } + #panel .panel-status-indicators-box, + #panel .panel-status-menu-box { + spacing: 2px; } + #panel .power-status.panel-status-indicators-box { + spacing: 0; } + #panel .screencast-indicator, + #panel .remote-access-indicator { + color: #f57900; } + + #appMenu { + spacing: 6px; } + #appMenu .label-shadow { + color: transparent; } + + #appMenu .panel-status-menu-box { + padding: 0 6px; + spacing: 6px; } + + /* Activities Ripple */ + .ripple-box { + background-color: rgba(188, 214, 246, 0.3); + box-shadow: 0 0 2px 2px #629fea; +@@ -2039,74 +2042,107 @@ StScrollBar { + width: 2.18em; + height: 2.18em; + border-color: #202020; + background-color: #202020; } + .login-dialog .cancel-button StIcon, + .login-dialog .switch-user-button StIcon, + .login-dialog .login-dialog-session-list-button StIcon, + .unlock-dialog .cancel-button StIcon, + .unlock-dialog .switch-user-button StIcon, + .unlock-dialog .login-dialog-session-list-button StIcon { + icon-size: 1.09em; } + .login-dialog .caps-lock-warning-label, + .login-dialog .login-dialog-message-warning, + .unlock-dialog .caps-lock-warning-label, + .unlock-dialog .login-dialog-message-warning { + color: #eeeeec; } + + .login-dialog-logo-bin { + padding: 24px 0px; } + + .login-dialog-banner { + color: #d6d6d1; } + + .login-dialog-button-box { + width: 23em; + spacing: 5px; } + + .login-dialog-message { + text-align: center; } + ++.login-dialog-message-hint, .login-dialog-message { ++ color: #bebeb6; ++ min-height: 2.75em; } ++ + .login-dialog-user-selection-box { + padding: 100px 0px; } + + .login-dialog-not-listed-label { + padding-left: 2px; } + .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { + color: #eeeeec; } + + .login-dialog-not-listed-label { + font-size: 10pt; + font-weight: bold; + color: #a6a69b; + padding-top: 1em; } + ++.login-dialog-auth-list-view { ++ -st-vfade-offset: 1em; } ++ ++.login-dialog-auth-list { ++ spacing: 6px; ++ margin-left: 2em; } ++ ++.login-dialog-auth-list-title { ++ margin-left: 2em; } ++ ++.login-dialog-auth-list-item { ++ border-radius: 12px; ++ padding: 6px; ++ color: #a6a69b; } ++ .login-dialog-auth-list-item:focus, .login-dialog-auth-list-item:selected { ++ background-color: #1b6acb; ++ color: #fff; } ++ ++.login-dialog-auth-list-label { ++ font-size: 13pt; ++ font-weight: bold; ++ padding-left: 15px; } ++ .login-dialog-auth-list-label:ltr { ++ padding-left: 14px; ++ text-align: left; } ++ .login-dialog-auth-list-label:rtl { ++ padding-right: 14px; ++ text-align: right; } ++ + .login-dialog-user-list-view { + -st-vfade-offset: 1em; } + + .login-dialog-user-list { + spacing: 12px; + width: 23em; } + .login-dialog-user-list:expanded .login-dialog-user-list-item:selected { + background-color: #1b6acb; + color: #fff; } + .login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in { + border-right: 2px solid #1b6acb; } + + .login-dialog-user-list-item { + border-radius: 12px; + padding: 6px; + color: #a6a69b; } + .login-dialog-user-list-item:ltr .user-widget { + padding-right: 1em; } + .login-dialog-user-list-item:rtl .user-widget { + padding-left: 1em; } + .login-dialog-user-list-item .login-dialog-timed-login-indicator { + height: 2px; + margin-top: 6px; + background-color: #eeeeec; } + .login-dialog-user-list-item:focus .login-dialog-timed-login-indicator { + background-color: #fff; } + + .user-widget-label { + color: #eeeeec; } + +-- +2.34.1 + diff --git a/SOURCES/0001-app-Fall-back-to-window-title-instead-of-WM_CLASS.patch b/SOURCES/0001-app-Fall-back-to-window-title-instead-of-WM_CLASS.patch new file mode 100644 index 0000000..001e896 --- /dev/null +++ b/SOURCES/0001-app-Fall-back-to-window-title-instead-of-WM_CLASS.patch @@ -0,0 +1,28 @@ +From afa3fc7be62cf70c9f6c6954e9cf5b49581269fb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 20 May 2015 16:44:00 +0200 +Subject: [PATCH] app: Fall back to window title instead of WM_CLASS + +It's a bad fallback as it's clearly window-specific (rather than +app-specific), but it likely looks prettier when we fail to associate +a .desktop file ... +--- + src/shell-app.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shell-app.c b/src/shell-app.c +index 62ba2ec73..dc0e1c732 100644 +--- a/src/shell-app.c ++++ b/src/shell-app.c +@@ -293,7 +293,7 @@ shell_app_get_name (ShellApp *app) + const char *name = NULL; + + if (window) +- name = meta_window_get_wm_class (window); ++ name = meta_window_get_title (window); + if (!name) + name = C_("program", "Unknown"); + return name; +-- +2.31.1 + diff --git a/SOURCES/0001-extensionDownloader-Refuse-to-override-system-extens.patch b/SOURCES/0001-extensionDownloader-Refuse-to-override-system-extens.patch new file mode 100644 index 0000000..58a3ee8 --- /dev/null +++ b/SOURCES/0001-extensionDownloader-Refuse-to-override-system-extens.patch @@ -0,0 +1,36 @@ +From c18b7b7819f17f5d14be1ba2760653f3d93b81b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 1 Feb 2021 18:26:00 +0100 +Subject: [PATCH] extensionDownloader: Refuse to override system extensions + +The website allows to "update" system extensions by installing the +upstream version into the user's home directory. + +Prevent that by refusing to download and install extensions that are +already installed system-wide. +--- + js/ui/extensionDownloader.js | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js +index 6a3b2b488..471ddab14 100644 +--- a/js/ui/extensionDownloader.js ++++ b/js/ui/extensionDownloader.js +@@ -17,6 +17,14 @@ var REPOSITORY_URL_UPDATE = 'https://extensions.gnome.org/update-info/'; + let _httpSession; + + function installExtension(uuid, invocation) { ++ const oldExt = Main.extensionManager.lookup(uuid); ++ if (oldExt && oldExt.type === ExtensionUtils.ExtensionType.SYSTEM) { ++ log('extensionDownloader: Trying to replace system extension %s'.format(uuid)); ++ invocation.return_dbus_error('org.gnome.Shell.InstallError', ++ 'System extensions cannot be replaced'); ++ return; ++ } ++ + let params = { uuid, + shell_version: Config.PACKAGE_VERSION }; + +-- +2.31.1 + diff --git a/SOURCES/0001-kbdA11yDialog-Use-MetaKeyboardA11yFlags.patch b/SOURCES/0001-kbdA11yDialog-Use-MetaKeyboardA11yFlags.patch new file mode 100644 index 0000000..2ff43aa --- /dev/null +++ b/SOURCES/0001-kbdA11yDialog-Use-MetaKeyboardA11yFlags.patch @@ -0,0 +1,51 @@ +From bd4fef8354ff0730c1e96a47d77adbb4a4d7beaa Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 14 Jun 2022 16:38:27 +0200 +Subject: [PATCH] kbdA11yDialog: Use MetaKeyboardA11yFlags + +The change in mutter to move keyboard accessibility into backends needs +to be applied in gnome-shell as well, otherwise the keyboard +accessibility dialog cannot work. + +Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2306 +Part-of: +--- + js/ui/kbdA11yDialog.js | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/js/ui/kbdA11yDialog.js b/js/ui/kbdA11yDialog.js +index a45e02443..60ec161a6 100644 +--- a/js/ui/kbdA11yDialog.js ++++ b/js/ui/kbdA11yDialog.js +@@ -1,5 +1,5 @@ + /* exported KbdA11yDialog */ +-const { Clutter, Gio, GObject } = imports.gi; ++const { Clutter, Gio, GObject, Meta } = imports.gi; + + const Dialog = imports.ui.dialog; + const ModalDialog = imports.ui.modalDialog; +@@ -25,17 +25,17 @@ class KbdA11yDialog extends GObject.Object { + let title, description; + let key, enabled; + +- if (whatChanged & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) { ++ if (whatChanged & Meta.KeyboardA11yFlags.SLOW_KEYS_ENABLED) { + key = KEY_SLOW_KEYS_ENABLED; +- enabled = (newFlags & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) > 0; ++ enabled = (newFlags & Meta.KeyboardA11yFlags.SLOW_KEYS_ENABLED) > 0; + title = enabled + ? _("Slow Keys Turned On") + : _("Slow Keys Turned Off"); + description = _('You just held down the Shift key for 8 seconds. This is the shortcut ' + + 'for the Slow Keys feature, which affects the way your keyboard works.'); +- } else if (whatChanged & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) { ++ } else if (whatChanged & Meta.KeyboardA11yFlags.STICKY_KEYS_ENABLED) { + key = KEY_STICKY_KEYS_ENABLED; +- enabled = (newFlags & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) > 0; ++ enabled = (newFlags & Meta.KeyboardA11yFlags.STICKY_KEYS_ENABLED) > 0; + title = enabled + ? _("Sticky Keys Turned On") + : _("Sticky Keys Turned Off"); +-- +2.36.1 + diff --git a/SOURCES/0001-loginDialog-make-info-messages-themed.patch b/SOURCES/0001-loginDialog-make-info-messages-themed.patch new file mode 100644 index 0000000..761f06a --- /dev/null +++ b/SOURCES/0001-loginDialog-make-info-messages-themed.patch @@ -0,0 +1,83 @@ +From 4ad30b5c506ab043c2091441021b6cf334e2412f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 26 Jun 2017 14:35:05 -0400 +Subject: [PATCH] loginDialog: make info messages themed + +They were lacking a definition before leading them to +show up invisible. +--- + 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 1789beca9..84539342d 100644 +--- a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss ++++ b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss +@@ -66,60 +66,64 @@ + border-color: darken($selected_bg_color, 10%); + background-color: darken($selected_bg_color, 10%); + color: transparentize($selected_fg_color, 0.3); + } + } + } + + .cancel-button, + .switch-user-button, + .login-dialog-session-list-button { + padding: 0; + border-radius: 99px; + width: $base_icon_size * 2; + height: $base_icon_size * 2; + border-color: darken($system_bg_color, 3%); + background-color: darken($system_bg_color, 3%); + + StIcon { icon-size: $base_icon_size; } + } + + .caps-lock-warning-label, + .login-dialog-message-warning { + color: $osd_fg_color; + } + } + + .login-dialog-logo-bin { padding: 24px 0px; } + .login-dialog-banner { color: darken($osd_fg_color,10%); } + .login-dialog-button-box { width: 23em; spacing: 5px; } + .login-dialog-message { text-align: center; } ++.login-dialog-message-hint, .login-dialog-message { ++ color: darken($osd_fg_color, 20%); ++ min-height: 2.75em; ++} + .login-dialog-user-selection-box { padding: 100px 0px; } + .login-dialog-not-listed-label { + padding-left: 2px; + .login-dialog-not-listed-button:focus &, + .login-dialog-not-listed-button:hover & { + color: $osd_fg_color; + } + } + + .login-dialog-not-listed-label { + @include fontsize($base_font_size - 1); + font-weight: bold; + color: darken($osd_fg_color,30%); + padding-top: 1em; + } + + .login-dialog-user-list-view { -st-vfade-offset: 1em; } + .login-dialog-user-list { + spacing: 12px; + width: 23em; + &:expanded .login-dialog-user-list-item:selected { background-color: $selected_bg_color; color: $selected_fg_color; } + &:expanded .login-dialog-user-list-item:logged-in { border-right: 2px solid $selected_bg_color; } + } + + .login-dialog-user-list-item { + border-radius: $base_border_radius + 4px; + padding: 6px; + color: darken($osd_fg_color,30%); + &:ltr .user-widget { padding-right: 1em; } + &:rtl .user-widget { padding-left: 1em; } +-- +2.34.1 + diff --git a/SOURCES/0001-main-Dump-stack-on-segfaults-by-default.patch b/SOURCES/0001-main-Dump-stack-on-segfaults-by-default.patch new file mode 100644 index 0000000..57dc9f0 --- /dev/null +++ b/SOURCES/0001-main-Dump-stack-on-segfaults-by-default.patch @@ -0,0 +1,38 @@ +From f54c3f9f66001c210e10fda6aa17b9218fb67dc1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 29 Oct 2020 18:21:06 +0100 +Subject: [PATCH] main: Dump stack on segfaults by default + +--- + src/main.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 5d07a4301..ed0b78dcc 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -38,6 +38,7 @@ static int caught_signal = 0; + #define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 + #define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 + ++#define DEFAULT_SHELL_DEBUG SHELL_DEBUG_BACKTRACE_SEGFAULTS + enum { + SHELL_DEBUG_BACKTRACE_WARNINGS = 1, + SHELL_DEBUG_BACKTRACE_SEGFAULTS = 2, +@@ -279,8 +280,11 @@ shell_init_debug (const char *debug_env) + { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS }, + }; + +- _shell_debug = g_parse_debug_string (debug_env, keys, +- G_N_ELEMENTS (keys)); ++ if (debug_env) ++ _shell_debug = g_parse_debug_string (debug_env, keys, ++ G_N_ELEMENTS (keys)); ++ else ++ _shell_debug = DEFAULT_SHELL_DEBUG; + } + + static void +-- +2.31.1 + diff --git a/SOURCES/0001-main-Leak-the-GJS-context-and-ShellGlobal.patch b/SOURCES/0001-main-Leak-the-GJS-context-and-ShellGlobal.patch new file mode 100644 index 0000000..250416d --- /dev/null +++ b/SOURCES/0001-main-Leak-the-GJS-context-and-ShellGlobal.patch @@ -0,0 +1,31 @@ +From a9e79b1657dc7c1b702d7acc4d322539d2b8b6aa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 6 Oct 2021 10:00:43 +0200 +Subject: [PATCH] main: Leak the GJS context and ShellGlobal + +There are many crash-on-exit happening as a side effect of destroying +the GJS context. Work around these until we have a better solution by +leaking them. +--- + src/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 91e5493fd1..d62dda9627 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -508,9 +508,11 @@ main (int argc, char **argv) + ecode = meta_run (); + shell_profiler_shutdown (); + ++#if 0 + g_debug ("Doing final cleanup"); + _shell_global_destroy_gjs_context (shell_global_get ()); + g_object_unref (shell_global_get ()); ++#endif + + return ecode; + } +-- +2.31.1 + diff --git a/SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch b/SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch new file mode 100644 index 0000000..8ebfc46 --- /dev/null +++ b/SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch @@ -0,0 +1,56 @@ +From b5db4d318546654f4e9c1e4999fa00456441f105 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 15 Jan 2014 16:45:34 -0500 +Subject: [PATCH] panel: add an icon to the ActivitiesButton + +Requested by brand +--- + data/theme/gnome-shell-sass/widgets/_panel.scss | 5 +++++ + js/ui/panel.js | 11 ++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/data/theme/gnome-shell-sass/widgets/_panel.scss b/data/theme/gnome-shell-sass/widgets/_panel.scss +index 1f4650773..5f323cbc8 100644 +--- a/data/theme/gnome-shell-sass/widgets/_panel.scss ++++ b/data/theme/gnome-shell-sass/widgets/_panel.scss +@@ -85,6 +85,11 @@ $panel_transition_duration: 250ms; // same as the overview transition duration + // dimensions of the icon are hardcoded + } + ++ .panel-logo-icon { ++ padding-right: .4em; ++ icon-size: 1em; ++ } ++ + &#panelActivities { + -natural-hpadding: $base_padding * 3; + } +diff --git a/js/ui/panel.js b/js/ui/panel.js +index 1474886ef..ad11f4ba2 100644 +--- a/js/ui/panel.js ++++ b/js/ui/panel.js +@@ -390,11 +390,20 @@ class ActivitiesButton extends PanelMenu.Button { + + this.name = 'panelActivities'; + ++ const box = new St.BoxLayout(); ++ this.add_child(box); ++ const iconFile = Gio.File.new_for_path('/usr/share/icons/hicolor/scalable/apps/start-here.svg'); ++ this._icon = new St.Icon({ ++ gicon: new Gio.FileIcon({ file: iconFile }), ++ style_class: 'panel-logo-icon', ++ }); ++ box.add_child(this._icon); ++ + /* Translators: If there is no suitable word for "Activities" + in your language, you can use the word for "Overview". */ + this._label = new St.Label({ text: _("Activities"), + y_align: Clutter.ActorAlign.CENTER }); +- this.add_actor(this._label); ++ box.add_child(this._label); + + this.label_actor = this._label; + +-- +2.31.1 + diff --git a/SOURCES/0001-screenShield-unblank-when-inserting-smartcard.patch b/SOURCES/0001-screenShield-unblank-when-inserting-smartcard.patch new file mode 100644 index 0000000..3a1ac18 --- /dev/null +++ b/SOURCES/0001-screenShield-unblank-when-inserting-smartcard.patch @@ -0,0 +1,33 @@ +From 1e4e9248ef6bcdd95ec3b91c8c8e94c4587a876b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 3 Jul 2015 13:54:36 -0400 +Subject: [PATCH] screenShield: unblank when inserting smartcard + +If a user inserts the smartcard when the screen is locked/blanked +we should ask them their pin right away. + +At the moment they have to wiggle the mouse or do some other +action to get the screen to unblank. +--- + js/ui/screenShield.js | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js +index 9a64fc32c..bc1a0fba7 100644 +--- a/js/ui/screenShield.js ++++ b/js/ui/screenShield.js +@@ -85,8 +85,10 @@ var ScreenShield = class { + this._smartcardManager = SmartcardManager.getSmartcardManager(); + this._smartcardManager.connect('smartcard-inserted', + (manager, token) => { +- if (this._isLocked && token.UsedToLogin) ++ if (this._isLocked && token.UsedToLogin) { ++ this._wakeUpScreen(); + this._activateDialog(); ++ } + }); + + this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager(); +-- +2.31.1 + diff --git a/SOURCES/0001-st-texture-cache-purge-on-resume.patch b/SOURCES/0001-st-texture-cache-purge-on-resume.patch new file mode 100644 index 0000000..1a32fc7 --- /dev/null +++ b/SOURCES/0001-st-texture-cache-purge-on-resume.patch @@ -0,0 +1,66 @@ +From 483f0340bb64767bd8d6d95788058270dfdb5def Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 15 Jan 2019 12:54:32 -0500 +Subject: [PATCH] st-texture-cache: purge on resume + +With the proprietary nvidia driver, textures get garbled on suspend, +so the texture cache needs to evict all textures in that situation. +--- + js/ui/main.js | 6 +++++- + src/st/st-texture-cache.c | 10 ++++++++++ + src/st/st-texture-cache.h | 1 + + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/js/ui/main.js b/js/ui/main.js +index 979fcefa5..dbf3a32d3 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -249,7 +249,11 @@ function _initializeUI() { + return true; + }); + +- global.display.connect('gl-video-memory-purged', loadTheme); ++ global.display.connect('gl-video-memory-purged', () => { ++ let cache = St.TextureCache.get_default(); ++ cache.clear(); ++ loadTheme(); ++ }); + + // Provide the bus object for gnome-session to + // initiate logouts. +diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c +index b7b547a78..583c3f7d2 100644 +--- a/src/st/st-texture-cache.c ++++ b/src/st/st-texture-cache.c +@@ -130,6 +130,16 @@ st_texture_cache_class_init (StTextureCacheClass *klass) + G_TYPE_NONE, 1, G_TYPE_FILE); + } + ++/* Evicts all cached textures */ ++void ++st_texture_cache_clear (StTextureCache *cache) ++{ ++ g_return_if_fail (ST_IS_TEXTURE_CACHE (cache)); ++ ++ g_hash_table_remove_all (cache->priv->keyed_cache); ++ g_signal_emit (cache, signals[ICON_THEME_CHANGED], 0); ++} ++ + /* Evicts all cached textures for named icons */ + static void + st_texture_cache_evict_icons (StTextureCache *cache) +diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h +index 55d84952d..948915c30 100644 +--- a/src/st/st-texture-cache.h ++++ b/src/st/st-texture-cache.h +@@ -53,6 +53,7 @@ typedef enum { + } StTextureCachePolicy; + + StTextureCache* st_texture_cache_get_default (void); ++void st_texture_cache_clear (StTextureCache *cache); + + ClutterActor * + st_texture_cache_load_sliced_image (StTextureCache *cache, +-- +2.31.1 + diff --git a/SOURCES/0001-status-network-Use-wwan-settings-panel-for-GSM-LTE-M.patch b/SOURCES/0001-status-network-Use-wwan-settings-panel-for-GSM-LTE-M.patch new file mode 100644 index 0000000..b910c43 --- /dev/null +++ b/SOURCES/0001-status-network-Use-wwan-settings-panel-for-GSM-LTE-M.patch @@ -0,0 +1,58 @@ +From 7e94d682985ac4ff422da73b5878f4f005eff67b Mon Sep 17 00:00:00 2001 +From: Mohammed Sadiq +Date: Tue, 10 Aug 2021 15:22:30 +0530 +Subject: [PATCH] status/network: Use wwan settings panel for GSM/LTE Modems + +GSM/UMTS/LTE modems now have better support with wwan panel in GNOME +Settings. So, if the modem supports, open wwan panel, otherwise +fallback to opening network panel when "Mobile Broadband Settings" +item is clicked. + +See https://gitlab.gnome.org/GNOME/gnome-control-center/-/merge_requests/583 + +Part-of: +--- + js/ui/status/network.js | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/js/ui/status/network.js b/js/ui/status/network.js +index f510f90ae..fe82fcb08 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -543,7 +543,11 @@ var NMDeviceModem = class extends NMConnectionDevice { + constructor(client, device) { + super(client, device); + +- this.item.menu.addSettingsAction(_("Mobile Broadband Settings"), 'gnome-network-panel.desktop'); ++ const settingsPanel = this._useWwanPanel() ++ ? 'gnome-wwan-panel.desktop' ++ : 'gnome-network-panel.desktop'; ++ ++ this.item.menu.addSettingsAction(_('Mobile Broadband Settings'), settingsPanel); + + this._mobileDevice = null; + +@@ -573,8 +577,19 @@ var NMDeviceModem = class extends NMConnectionDevice { + return NMConnectionCategory.WWAN; + } + ++ _useWwanPanel() { ++ // Currently, wwan panel doesn't support CDMA_EVDO modems ++ const supportedCaps = ++ NM.DeviceModemCapabilities.GSM_UMTS | ++ NM.DeviceModemCapabilities.LTE; ++ return this._device.current_capabilities & supportedCaps; ++ } ++ + _autoConnect() { +- launchSettingsPanel('network', 'connect-3g', this._device.get_path()); ++ if (this._useWwanPanel()) ++ launchSettingsPanel('wwan', 'show-device', this._device.udi); ++ else ++ launchSettingsPanel('network', 'connect-3g', this._device.get_path()); + } + + _sessionUpdated() { +-- +2.31.1 + diff --git a/SOURCES/0001-status-volume-Hide-sliders-initially.patch b/SOURCES/0001-status-volume-Hide-sliders-initially.patch new file mode 100644 index 0000000..1600ab9 --- /dev/null +++ b/SOURCES/0001-status-volume-Hide-sliders-initially.patch @@ -0,0 +1,30 @@ +From b212b973175be1cbefa1da2c5ed4f58fae032c73 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 11 May 2022 02:34:21 +0200 +Subject: [PATCH] status/volume: Hide sliders initially + +We update the visibility on state or stream changes, but those +changes may never happen if pipewire-pulse/pulseaudio isn't +available (for example when running as root). + +Hiding the sliders is preferable in that case to showing non-working +controls. +--- + js/ui/status/volume.js | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/js/ui/status/volume.js b/js/ui/status/volume.js +index 7164e1054..f623ee680 100644 +--- a/js/ui/status/volume.js ++++ b/js/ui/status/volume.js +@@ -34,6 +34,7 @@ var StreamSlider = class { + this._control = control; + + this.item = new PopupMenu.PopupBaseMenuItem({ activate: false }); ++ this.item.hide(); + + this._inDrag = false; + this._notifyVolumeChangeId = 0; +-- +2.35.1 + diff --git a/SOURCES/0001-welcomeDialog-Adapt-dialog-title.patch b/SOURCES/0001-welcomeDialog-Adapt-dialog-title.patch new file mode 100644 index 0000000..dd812c7 --- /dev/null +++ b/SOURCES/0001-welcomeDialog-Adapt-dialog-title.patch @@ -0,0 +1,38 @@ +From 79049292451b9bb23ad92c572a438585ca37246b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 27 Oct 2021 15:18:20 +0200 +Subject: [PATCH] welcomeDialog: Adapt dialog title + +Use RHEL branding instead of the upstream GNOME XX one. +--- + js/ui/welcomeDialog.js | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/js/ui/welcomeDialog.js b/js/ui/welcomeDialog.js +index 9d99f0035..783fd1108 100644 +--- a/js/ui/welcomeDialog.js ++++ b/js/ui/welcomeDialog.js +@@ -1,9 +1,8 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + /* exported WelcomeDialog */ + +-const { Clutter, GObject, Shell, St } = imports.gi; ++const { Clutter, GLib, GObject, Shell, St } = imports.gi; + +-const Config = imports.misc.config; + const Dialog = imports.ui.dialog; + const Main = imports.ui.main; + const ModalDialog = imports.ui.modalDialog; +@@ -32,8 +31,7 @@ class WelcomeDialog extends ModalDialog.ModalDialog { + } + + _buildLayout() { +- const [majorVersion] = Config.PACKAGE_VERSION.split('.'); +- const title = _('Welcome to GNOME %s').format(majorVersion); ++ const title = _('Welcome to %s').format(GLib.get_os_info('NAME')); + const description = _('If you want to learn your way around, check out the tour.'); + const content = new Dialog.MessageDialogContent({ title, description }); + +-- +2.33.1 + diff --git a/SOURCES/0001-windowMenu-Bring-back-workspaces-submenu-for-static-.patch b/SOURCES/0001-windowMenu-Bring-back-workspaces-submenu-for-static-.patch new file mode 100644 index 0000000..980f607 --- /dev/null +++ b/SOURCES/0001-windowMenu-Bring-back-workspaces-submenu-for-static-.patch @@ -0,0 +1,45 @@ +From 34a7bfdade939e39c2a01cc1b0737a7bdccddd5b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 14 Mar 2017 17:04:36 +0100 +Subject: [PATCH] windowMenu: Bring back workspaces submenu for static + workspaces + +When the titlebar context menu was moved to the shell, the submenu for +moving to a specific workspace was intentionally left out; some people +are quite attached to it though, so bring it back when static workspaces +are used. +--- + js/ui/windowMenu.js | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/js/ui/windowMenu.js b/js/ui/windowMenu.js +index bb6a8df7b..3449f759d 100644 +--- a/js/ui/windowMenu.js ++++ b/js/ui/windowMenu.js +@@ -116,6 +116,23 @@ var WindowMenu = class extends PopupMenu.PopupMenu { + window.change_workspace(workspace.get_neighbor(dir)); + }); + } ++ ++ let { workspaceManager } = global; ++ let nWorkspaces = workspaceManager.n_workspaces; ++ if (nWorkspaces > 1 && !Meta.prefs_get_dynamic_workspaces()) { ++ item = new PopupMenu.PopupSubMenuMenuItem(_("Move to another workspace")); ++ this.addMenuItem(item); ++ ++ let currentIndex = workspaceManager.get_active_workspace_index(); ++ for (let i = 0; i < nWorkspaces; i++) { ++ let index = i; ++ let name = Meta.prefs_get_workspace_name(i); ++ let subitem = item.menu.addAction(name, () => { ++ window.change_workspace_by_index(index, false); ++ }); ++ subitem.setSensitive(currentIndex != i); ++ } ++ } + } + } + +-- +2.31.1 + diff --git a/SOURCES/add-power-profiles-menu.patch b/SOURCES/add-power-profiles-menu.patch new file mode 100644 index 0000000..289a80b --- /dev/null +++ b/SOURCES/add-power-profiles-menu.patch @@ -0,0 +1,333 @@ +From 2103c5fcf994bb6aebd978553b338436e85fa7ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 7 Jul 2021 22:05:25 +0200 +Subject: [PATCH 1/2] status/powerProfiles: Add power mode selection + +Settings' power panel gained support for switchable power profiles +in GNOME 40. It's useful to have that functionality more readily +available, so expose it in the system status menu as well. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3944 + +Part-of: +--- + .../net.hadess.PowerProfiles.xml | 76 ++++++++++++ + .../gnome-shell-dbus-interfaces.gresource.xml | 1 + + js/js-resources.gresource.xml | 1 + + js/ui/panel.js | 4 + + js/ui/status/powerProfiles.js | 111 ++++++++++++++++++ + po/POTFILES.in | 1 + + 6 files changed, 194 insertions(+) + create mode 100644 data/dbus-interfaces/net.hadess.PowerProfiles.xml + create mode 100644 js/ui/status/powerProfiles.js + +diff --git a/data/dbus-interfaces/net.hadess.PowerProfiles.xml b/data/dbus-interfaces/net.hadess.PowerProfiles.xml +new file mode 100644 +index 000000000..fce04a86d +--- /dev/null ++++ b/data/dbus-interfaces/net.hadess.PowerProfiles.xml +@@ -0,0 +1,76 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml +index e7972f6cb..6682c462d 100644 +--- a/data/gnome-shell-dbus-interfaces.gresource.xml ++++ b/data/gnome-shell-dbus-interfaces.gresource.xml +@@ -1,6 +1,7 @@ + + + ++ net.hadess.PowerProfiles.xml + net.hadess.SensorProxy.xml + net.reactivated.Fprint.Device.xml + net.reactivated.Fprint.Manager.xml +diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml +index b2c603a55..7a94e2ff1 100644 +--- a/js/js-resources.gresource.xml ++++ b/js/js-resources.gresource.xml +@@ -134,6 +134,7 @@ + ui/status/nightLight.js + ui/status/network.js + ui/status/power.js ++ ui/status/powerProfiles.js + ui/status/rfkill.js + ui/status/volume.js + ui/status/bluetooth.js +diff --git a/js/ui/panel.js b/js/ui/panel.js +index ad11f4ba2..84668e96e 100644 +--- a/js/ui/panel.js ++++ b/js/ui/panel.js +@@ -693,6 +693,7 @@ class AggregateMenu extends PanelMenu.Button { + + this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet(); + this._power = new imports.ui.status.power.Indicator(); ++ this._powerProfiles = new imports.ui.status.powerProfiles.Indicator(); + this._rfkill = new imports.ui.status.rfkill.Indicator(); + this._volume = new imports.ui.status.volume.Indicator(); + this._brightness = new imports.ui.status.brightness.Indicator(); +@@ -712,6 +713,7 @@ class AggregateMenu extends PanelMenu.Button { + this._indicators.add_child(this._rfkill); + this._indicators.add_child(this._volume); + this._indicators.add_child(this._power); ++ this._indicators.add_child(this._powerProfiles); + + this.menu.addMenuItem(this._volume.menu); + this.menu.addMenuItem(this._brightness.menu); +@@ -726,6 +728,7 @@ class AggregateMenu extends PanelMenu.Button { + this.menu.addMenuItem(this._location.menu); + this.menu.addMenuItem(this._rfkill.menu); + this.menu.addMenuItem(this._power.menu); ++ this.menu.addMenuItem(this._powerProfiles.menu); + this.menu.addMenuItem(this._nightLight.menu); + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addMenuItem(this._system.menu); +@@ -733,6 +736,7 @@ class AggregateMenu extends PanelMenu.Button { + menuLayout.addSizeChild(this._location.menu.actor); + menuLayout.addSizeChild(this._rfkill.menu.actor); + menuLayout.addSizeChild(this._power.menu.actor); ++ menuLayout.addSizeChild(this._powerProfiles.menu.actor); + menuLayout.addSizeChild(this._system.menu.actor); + } + }); +diff --git a/js/ui/status/powerProfiles.js b/js/ui/status/powerProfiles.js +new file mode 100644 +index 000000000..f6bc5835b +--- /dev/null ++++ b/js/ui/status/powerProfiles.js +@@ -0,0 +1,111 @@ ++// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- ++/* exported Indicator */ ++ ++const { Gio, GObject } = imports.gi; ++ ++const Main = imports.ui.main; ++const PanelMenu = imports.ui.panelMenu; ++const PopupMenu = imports.ui.popupMenu; ++ ++const { loadInterfaceXML } = imports.misc.fileUtils; ++ ++const BUS_NAME = 'net.hadess.PowerProfiles'; ++const OBJECT_PATH = '/net/hadess/PowerProfiles'; ++ ++const PowerProfilesIface = loadInterfaceXML('net.hadess.PowerProfiles'); ++const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesIface); ++ ++const PROFILE_LABELS = { ++ 'performance': _('Performance Mode'), ++ 'balanced': _('Balanced Power'), ++ 'power-saver': _('Power Saver'), ++}; ++const PROFILE_ICONS = { ++ 'performance': 'power-profile-performance-symbolic', ++ 'balanced': 'power-profile-balanced-symbolic', ++ 'power-saver': 'power-profile-power-saver-symbolic', ++}; ++ ++var Indicator = GObject.registerClass( ++class Indicator extends PanelMenu.SystemIndicator { ++ _init() { ++ super._init(); ++ ++ this._profileItems = new Map(); ++ this._updateProfiles = true; ++ ++ this._proxy = new PowerProfilesProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH, ++ (proxy, error) => { ++ if (error) { ++ log(error.message); ++ } else { ++ this._proxy.connect('g-properties-changed', ++ (p, properties) => { ++ const propertyNames = properties.deep_unpack(); ++ this._updateProfiles = 'Profiles' in propertyNames; ++ this._sync(); ++ }); ++ } ++ this._sync(); ++ }); ++ ++ this._item = new PopupMenu.PopupSubMenuMenuItem('', true); ++ ++ this._profileSection = new PopupMenu.PopupMenuSection(); ++ this._item.menu.addMenuItem(this._profileSection); ++ this._item.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); ++ this._item.menu.addSettingsAction(_('Power Settings'), ++ 'gnome-power-panel.desktop'); ++ this.menu.addMenuItem(this._item); ++ ++ Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); ++ this._sessionUpdated(); ++ this._sync(); ++ } ++ ++ _sessionUpdated() { ++ const sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; ++ this.menu.setSensitive(sensitive); ++ } ++ ++ _sync() { ++ this._item.visible = this._proxy.g_name_owner !== null; ++ ++ if (!this._item.visible) ++ return; ++ ++ if (this._updateProfiles) { ++ this._profileSection.removeAll(); ++ this._profileItems.clear(); ++ ++ const profiles = this._proxy.Profiles ++ .map(p => p.Profile.unpack()) ++ .reverse(); ++ for (const profile of profiles) { ++ const label = PROFILE_LABELS[profile]; ++ if (!label) ++ continue; ++ ++ const item = new PopupMenu.PopupMenuItem(label); ++ item.connect('activate', ++ () => (this._proxy.ActiveProfile = profile)); ++ this._profileItems.set(profile, item); ++ this._profileSection.addMenuItem(item); ++ } ++ this._updateProfiles = false; ++ } ++ ++ for (const [profile, item] of this._profileItems) { ++ item.setOrnament(profile === this._proxy.ActiveProfile ++ ? PopupMenu.Ornament.DOT ++ : PopupMenu.Ornament.NONE); ++ } ++ ++ const perfItem = this._profileItems.get('performance'); ++ if (perfItem) ++ perfItem.sensitive = this._proxy.PerformanceInhibited === ''; ++ ++ this._item.label.text = PROFILE_LABELS[this._proxy.ActiveProfile]; ++ this._item.icon.icon_name = PROFILE_ICONS[this._proxy.ActiveProfile]; ++ } ++}); +diff --git a/po/POTFILES.in b/po/POTFILES.in +index cb279c1ee..727cb01a8 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -61,6 +61,7 @@ js/ui/status/location.js + js/ui/status/network.js + js/ui/status/nightLight.js + js/ui/status/power.js ++js/ui/status/powerProfiles.js + js/ui/status/remoteAccess.js + js/ui/status/rfkill.js + js/ui/status/system.js +-- +2.31.1 + + +From 0f8a2e2c6c3119492670efce5aff1224f2c3c47f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 6 Aug 2021 21:04:24 +0200 +Subject: [PATCH 2/2] powerProfiles: Tweak profile names + +After some more discussion, we settled on slightly different +profile names. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4530 + +Part-of: +--- + js/ui/status/powerProfiles.js | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/js/ui/status/powerProfiles.js b/js/ui/status/powerProfiles.js +index f6bc5835b..61205bbc6 100644 +--- a/js/ui/status/powerProfiles.js ++++ b/js/ui/status/powerProfiles.js +@@ -16,9 +16,9 @@ const PowerProfilesIface = loadInterfaceXML('net.hadess.PowerProfiles'); + const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesIface); + + const PROFILE_LABELS = { +- 'performance': _('Performance Mode'), +- 'balanced': _('Balanced Power'), +- 'power-saver': _('Power Saver'), ++ 'performance': C_('Power profile', 'Performance'), ++ 'balanced': C_('Power profile', 'Balanced'), ++ 'power-saver': C_('Power profile', 'Power Saver'), + }; + const PROFILE_ICONS = { + 'performance': 'power-profile-performance-symbolic', +-- +2.31.1 + diff --git a/SOURCES/disable-unlock-entry-until-question.patch b/SOURCES/disable-unlock-entry-until-question.patch new file mode 100644 index 0000000..20980c5 --- /dev/null +++ b/SOURCES/disable-unlock-entry-until-question.patch @@ -0,0 +1,176 @@ +From 6739f213965c2b6a41c21b446095f393f9d86e43 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 30 Sep 2015 12:51:24 -0400 +Subject: [PATCH 1/3] authPrompt: don't fade out auth messages if user types + password up front + +Right now we fade out any stale auth messages as soon as the user starts +typing. This behavior doesn't really make sense if the user is typing up +front, before a password is asked. +--- + js/gdm/authPrompt.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js +index 4844b9ee0..149e5ad4a 100644 +--- a/js/gdm/authPrompt.js ++++ b/js/gdm/authPrompt.js +@@ -179,7 +179,7 @@ var AuthPrompt = GObject.registerClass({ + + [this._textEntry, this._passwordEntry].forEach(entry => { + entry.clutter_text.connect('text-changed', () => { +- if (!this._userVerifier.hasPendingMessages) ++ if (!this._userVerifier.hasPendingMessages && this._queryingService && !this._preemptiveAnswer) + this._fadeOutMessage(); + }); + +-- +2.31.1 + + +From 2b84c3d611120ae2f60386d5c637b84d1958398d Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 30 Sep 2015 14:36:33 -0400 +Subject: [PATCH 2/3] authPrompt: don't spin unless answering question + +--- + js/gdm/authPrompt.js | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js +index 149e5ad4a..c5643d046 100644 +--- a/js/gdm/authPrompt.js ++++ b/js/gdm/authPrompt.js +@@ -243,13 +243,14 @@ var AuthPrompt = GObject.registerClass({ + this.verificationStatus = AuthPromptStatus.VERIFICATION_IN_PROGRESS; + this.updateSensitivity(false); + +- if (shouldSpin) +- this.startSpinning(); ++ if (this._queryingService) { ++ if (shouldSpin) ++ this.startSpinning(); + +- if (this._queryingService) + this._userVerifier.answerQuery(this._queryingService, this._entry.text); +- else ++ } else { + this._preemptiveAnswer = this._entry.text; ++ } + + this.emit('next'); + } +-- +2.31.1 + + +From 56360c872e01b0554b4d8b53dddba5407d4e889b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 5 Oct 2015 15:26:18 -0400 +Subject: [PATCH 3/3] authPrompt: stop accepting preemptive answer if user + stops typing + +We only want to allow the user to type the preemptive password in +one smooth motion. If they start to type, and then stop typing, +we should discard their preemptive password as expired. + +Typing ahead the password is just a convenience for users who don't +want to manually lift the shift before typing their passwords, after +all. +--- + js/gdm/authPrompt.js | 37 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js +index c5643d046..84c608b2f 100644 +--- a/js/gdm/authPrompt.js ++++ b/js/gdm/authPrompt.js +@@ -1,7 +1,7 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + /* exported AuthPrompt */ + +-const { Clutter, GLib, GObject, Pango, Shell, St } = imports.gi; ++const { Clutter, GLib, GObject, Meta, Pango, Shell, St } = imports.gi; + + const Animation = imports.ui.animation; + const Batch = imports.gdm.batch; +@@ -63,6 +63,8 @@ var AuthPrompt = GObject.registerClass({ + this._defaultButtonWellActor = null; + this._cancelledRetries = 0; + ++ this._idleMonitor = Meta.IdleMonitor.get_core(); ++ + let reauthenticationOnly; + if (this._mode == AuthPromptMode.UNLOCK_ONLY) + reauthenticationOnly = true; +@@ -119,6 +121,11 @@ var AuthPrompt = GObject.registerClass({ + } + + _onDestroy() { ++ if (this._preemptiveAnswerWatchId) { ++ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); ++ this._preemptiveAnswerWatchId = 0; ++ } ++ + this._userVerifier.destroy(); + this._userVerifier = null; + } +@@ -250,6 +257,11 @@ var AuthPrompt = GObject.registerClass({ + this._userVerifier.answerQuery(this._queryingService, this._entry.text); + } else { + this._preemptiveAnswer = this._entry.text; ++ ++ if (this._preemptiveAnswerWatchId) { ++ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); ++ this._preemptiveAnswerWatchId = 0; ++ } + } + + this.emit('next'); +@@ -429,6 +441,11 @@ var AuthPrompt = GObject.registerClass({ + } + + setQuestion(question) { ++ if (this._preemptiveAnswerWatchId) { ++ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); ++ this._preemptiveAnswerWatchId = 0; ++ } ++ + this._entry.hint_text = question; + + this._entry.show(); +@@ -530,6 +547,19 @@ var AuthPrompt = GObject.registerClass({ + this._updateEntry(false); + } + ++ _onUserStoppedTypePreemptiveAnswer() { ++ if (!this._preemptiveAnswerWatchId || ++ this._preemptiveAnswer || ++ this._queryingService) ++ return; ++ ++ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); ++ this._preemptiveAnswerWatchId = 0; ++ ++ this._entry.text = ''; ++ this.updateSensitivity(false); ++ } ++ + reset() { + let oldStatus = this.verificationStatus; + this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; +@@ -537,6 +567,11 @@ var AuthPrompt = GObject.registerClass({ + this.cancelButton.can_focus = this._hasCancelButton; + this._preemptiveAnswer = null; + ++ if (this._preemptiveAnswerWatchId) ++ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); ++ this._preemptiveAnswerWatchId = this._idleMonitor.add_idle_watch(500, ++ this._onUserStoppedTypePreemptiveAnswer.bind(this)); ++ + if (this._userVerifier) + this._userVerifier.cancel(); + +-- +2.31.1 + diff --git a/SOURCES/enforce-smartcard-at-unlock.patch b/SOURCES/enforce-smartcard-at-unlock.patch new file mode 100644 index 0000000..ffe2316 --- /dev/null +++ b/SOURCES/enforce-smartcard-at-unlock.patch @@ -0,0 +1,114 @@ +From d2c12a372ea0ccbe6ba682c553d8b83b3253169f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 28 Sep 2015 10:57:02 -0400 +Subject: [PATCH 1/3] smartcardManager: add way to detect if user logged using + (any) token + +If a user uses a token at login time, we need to make sure they continue +to use the token at unlock time. + +As a prerequisite for addressing that problem we need to know up front +if a user logged in with a token at all. + +This commit adds the necessary api to detect that case. +--- + js/misc/smartcardManager.js | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/js/misc/smartcardManager.js b/js/misc/smartcardManager.js +index d9b6ff474..26f9f5aaa 100644 +--- a/js/misc/smartcardManager.js ++++ b/js/misc/smartcardManager.js +@@ -111,5 +111,12 @@ var SmartcardManager = class { + + return true; + } ++ ++ loggedInWithToken() { ++ if (this._loginToken) ++ return true; ++ ++ return false; ++ } + }; + Signals.addSignalMethods(SmartcardManager.prototype); +-- +2.31.1 + + +From 98393eef884edc9e685b712c71356751acdd552f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 28 Sep 2015 19:56:53 -0400 +Subject: [PATCH 2/3] gdm: only unlock with smartcard, if smartcard used for + login + +If a smartcard is used for login, we need to make sure the smartcard +gets used for unlock, too. +--- + js/gdm/util.js | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/js/gdm/util.js b/js/gdm/util.js +index 72561daab..6b92e3564 100644 +--- a/js/gdm/util.js ++++ b/js/gdm/util.js +@@ -149,7 +149,6 @@ var ShellUserVerifier = class { + this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); + this._settings.connect('changed', + this._updateDefaultService.bind(this)); +- this._updateDefaultService(); + + this._fprintManager = new FprintManagerProxy(Gio.DBus.system, + 'net.reactivated.Fprint', +@@ -166,6 +165,8 @@ var ShellUserVerifier = class { + this.smartcardDetected = false; + this._checkForSmartcard(); + ++ this._updateDefaultService(); ++ + this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted', + this._checkForSmartcard.bind(this)); + this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed', +@@ -527,7 +528,9 @@ var ShellUserVerifier = class { + } + + _updateDefaultService() { +- if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY)) ++ if (this._smartcardManager.loggedInWithToken()) ++ this._defaultService = SMARTCARD_SERVICE_NAME; ++ else if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY)) + this._defaultService = PASSWORD_SERVICE_NAME; + else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY)) + this._defaultService = SMARTCARD_SERVICE_NAME; +-- +2.31.1 + + +From 57ca969a0af6f65e71dc1158163b9c826bdb7079 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 28 Sep 2015 19:57:36 -0400 +Subject: [PATCH 3/3] gdm: update default service when smartcard inserted + +Early on at start up we may not know if a smartcard is +available. Make sure we reupdate the default service +after we get a smartcard insertion event. +--- + js/gdm/util.js | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/js/gdm/util.js b/js/gdm/util.js +index 6b92e3564..e62114cb1 100644 +--- a/js/gdm/util.js ++++ b/js/gdm/util.js +@@ -420,6 +420,8 @@ var ShellUserVerifier = class { + else if (this._preemptingService == SMARTCARD_SERVICE_NAME) + this._preemptingService = null; + ++ this._updateDefaultService(); ++ + this.emit('smartcard-status-changed'); + } + } +-- +2.31.1 + diff --git a/SOURCES/fix-markup-in-highlighter.patch b/SOURCES/fix-markup-in-highlighter.patch new file mode 100644 index 0000000..b7509f6 --- /dev/null +++ b/SOURCES/fix-markup-in-highlighter.patch @@ -0,0 +1,334 @@ +From 49a950b9e0dc262fd20c28e21ee4815ea8efe758 Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +Date: Tue, 16 Nov 2021 18:57:26 +0100 +Subject: [PATCH 1/3] search: Split out the description highlighter into its + own class + +No functional change yet, only preparation to allow adding a unit test +later on. + +Part-of: +--- + js/misc/util.js | 38 +++++++++++++++++++++++++++++++++++++- + js/ui/search.js | 12 +++++------- + 2 files changed, 42 insertions(+), 8 deletions(-) + +diff --git a/js/misc/util.js b/js/misc/util.js +index 8139d3f47..d1a702960 100644 +--- a/js/misc/util.js ++++ b/js/misc/util.js +@@ -1,7 +1,8 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + /* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine, + formatTime, formatTimeSpan, createTimeLabel, insertSorted, +- ensureActorVisibleInScrollView, wiggle, lerp, GNOMEversionCompare */ ++ ensureActorVisibleInScrollView, wiggle, lerp, GNOMEversionCompare, ++ Highlighter */ + + const { Clutter, Gio, GLib, Shell, St, GnomeDesktop } = imports.gi; + const Gettext = imports.gettext; +@@ -477,3 +478,38 @@ function GNOMEversionCompare(version1, version2) { + + return 0; + } ++ ++/* @class Highlighter Highlight given terms in text using markup. */ ++var Highlighter = class { ++ /** ++ * @param {?string[]} terms - list of terms to highlight ++ */ ++ constructor(terms) { ++ if (!terms) ++ return; ++ ++ const escapedTerms = terms ++ .map(term => Shell.util_regex_escape(term)) ++ .filter(term => term.length > 0); ++ ++ if (escapedTerms.length === 0) ++ return; ++ ++ this._highlightRegex = new RegExp('(%s)'.format( ++ escapedTerms.join('|')), 'gi'); ++ } ++ ++ /** ++ * Highlight all occurences of the terms defined for this ++ * highlighter in the provided text using markup. ++ * ++ * @param {string} text - text to highlight the defined terms in ++ * @returns {string} ++ */ ++ highlight(text) { ++ if (!this._highlightRegex) ++ return text; ++ ++ return text.replace(this._highlightRegex, '$1'); ++ } ++}; +diff --git a/js/ui/search.js b/js/ui/search.js +index 7300b053e..b1e76c46d 100644 +--- a/js/ui/search.js ++++ b/js/ui/search.js +@@ -10,6 +10,8 @@ const ParentalControlsManager = imports.misc.parentalControlsManager; + const RemoteSearch = imports.ui.remoteSearch; + const Util = imports.misc.util; + ++const { Highlighter } = imports.misc.util; ++ + const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers'; + + var MAX_LIST_SEARCH_RESULTS_ROWS = 5; +@@ -596,7 +598,7 @@ var SearchResultsView = GObject.registerClass({ + + this._providers = []; + +- this._highlightRegex = null; ++ this._highlighter = new Highlighter(); + + this._searchSettings = new Gio.Settings({ schema_id: SEARCH_PROVIDERS_SCHEMA }); + this._searchSettings.connect('changed::disabled', this._reloadRemoteProviders.bind(this)); +@@ -739,8 +741,7 @@ var SearchResultsView = GObject.registerClass({ + if (this._searchTimeoutId == 0) + this._searchTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 150, this._onSearchTimeout.bind(this)); + +- let escapedTerms = this._terms.map(term => Shell.util_regex_escape(term)); +- this._highlightRegex = new RegExp('(%s)'.format(escapedTerms.join('|')), 'gi'); ++ this._highlighter = new Highlighter(this._terms); + + this.emit('terms-changed'); + } +@@ -894,10 +895,7 @@ var SearchResultsView = GObject.registerClass({ + if (!description) + return ''; + +- if (!this._highlightRegex) +- return description; +- +- return description.replace(this._highlightRegex, '$1'); ++ return this._highlighter.highlight(description); + } + }); + +-- +2.35.1 + + +From 7c1abe1bd91ecf274d81e122035cbeeef6fd58d4 Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +Date: Wed, 17 Nov 2021 02:50:39 +0100 +Subject: [PATCH 2/3] util: Properly handle markup in highlighter + +The code to highlight matches did not properly escape the passed in text +as for markup before adding its highlighting markup. This lead to some +search result descriptions not showing up, because their descriptions +contained characters, such as "<", that would have to be escaped when +used in markup or otherwise lead to invalid markup. + +To work around this some search providers wrongly started escaping the +description on their end before sending them to gnome-shell. This lead +to another issue. Now if the highlighter was trying to highlight the +term "a", and the escaped description contained "'", the "a" in +that would be considered a match and surrounded by "". This +however would also generate invalid markup, again leading to an error +and the description not being shown. + +Fix this by always escaping the passed in string before applying the +highlights in such a way that there are no matches within entities. + +This also means that search providers that escaped their description +strings will now show up with the markup syntax. This will have to be +fixed separately in the affected search providers. + +Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4791 +Part-of: +--- + js/misc/util.js | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/js/misc/util.js b/js/misc/util.js +index d1a702960..802398d18 100644 +--- a/js/misc/util.js ++++ b/js/misc/util.js +@@ -508,8 +508,25 @@ var Highlighter = class { + */ + highlight(text) { + if (!this._highlightRegex) +- return text; ++ return GLib.markup_escape_text(text, -1); ++ ++ let escaped = []; ++ let lastMatchEnd = 0; ++ let match; ++ while ((match = this._highlightRegex.exec(text))) { ++ if (match.index > lastMatchEnd) { ++ let unmatched = GLib.markup_escape_text( ++ text.slice(lastMatchEnd, match.index), -1); ++ escaped.push(unmatched); ++ } ++ let matched = GLib.markup_escape_text(match[0], -1); ++ escaped.push('%s'.format(matched)); ++ lastMatchEnd = match.index + match[0].length; ++ } ++ let unmatched = GLib.markup_escape_text( ++ text.slice(lastMatchEnd), -1); ++ escaped.push(unmatched); + +- return text.replace(this._highlightRegex, '$1'); ++ return escaped.join(''); + } + }; +-- +2.35.1 + + +From 82e2a6dcfabc2f82efbf468175d16c303f0c73da Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +Date: Wed, 17 Nov 2021 03:05:05 +0100 +Subject: [PATCH 3/3] tests: Add unit test for highlighter + +Part-of: +--- + tests/meson.build | 12 ++++- + tests/unit/highlighter.js | 106 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 117 insertions(+), 1 deletion(-) + create mode 100644 tests/unit/highlighter.js + +diff --git a/tests/meson.build b/tests/meson.build +index c0431631f..50fb601e9 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -10,7 +10,17 @@ run_test = configure_file( + testenv = environment() + testenv.set('GSETTINGS_SCHEMA_DIR', join_paths(meson.build_root(), 'data')) + +-foreach test : ['insertSorted', 'jsParse', 'markup', 'params', 'url', 'versionCompare'] ++tests = [ ++ 'highlighter', ++ 'insertSorted', ++ 'jsParse', ++ 'markup', ++ 'params', ++ 'url', ++ 'versionCompare', ++] ++ ++foreach test : tests + test(test, run_test, + args: 'unit/@0@.js'.format(test), + env: testenv, +diff --git a/tests/unit/highlighter.js b/tests/unit/highlighter.js +new file mode 100644 +index 000000000..d582d38e3 +--- /dev/null ++++ b/tests/unit/highlighter.js +@@ -0,0 +1,106 @@ ++// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- ++ ++// Test cases for SearchResult description match highlighter ++ ++const JsUnit = imports.jsUnit; ++const Pango = imports.gi.Pango; ++ ++const Environment = imports.ui.environment; ++Environment.init(); ++ ++const Util = imports.misc.util; ++ ++const tests = [ ++ { input: 'abc cba', ++ terms: null, ++ output: 'abc cba' }, ++ { input: 'abc cba', ++ terms: [], ++ output: 'abc cba' }, ++ { input: 'abc cba', ++ terms: [''], ++ output: 'abc cba' }, ++ { input: 'abc cba', ++ terms: ['a'], ++ output: 'abc cba' }, ++ { input: 'abc cba', ++ terms: ['a', 'a'], ++ output: 'abc cba' }, ++ { input: 'CaSe InSenSiTiVe', ++ terms: ['cas', 'sens'], ++ output: 'CaSe InSenSiTiVe' }, ++ { input: 'This contains the < character', ++ terms: null, ++ output: 'This contains the < character' }, ++ { input: 'Don\'t', ++ terms: ['t'], ++ output: 'Don't' }, ++ { input: 'Don\'t', ++ terms: ['n\'t'], ++ output: 'Don't' }, ++ { input: 'Don\'t', ++ terms: ['o', 't'], ++ output: 'Don't' }, ++ { input: 'salt&pepper', ++ terms: ['salt'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['salt', 'alt'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['pepper'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['salt', 'pepper'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['t', 'p'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['t', '&', 'p'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['e'], ++ output: 'salt&pepper' }, ++ { input: 'salt&pepper', ++ terms: ['&a', '&am', '&', '&'], ++ output: 'salt&pepper' }, ++ { input: '&&&&&', ++ terms: ['a'], ++ output: '&&&&&' }, ++ { input: '&;&;&;&;&;', ++ terms: ['a'], ++ output: '&;&;&;&;&;' }, ++ { input: '&;&;&;&;&;', ++ terms: [';'], ++ output: '&;&;&;&;&;' }, ++ { input: '&', ++ terms: ['a'], ++ output: '&amp;' } ++]; ++ ++try { ++ for (let i = 0; i < tests.length; i++) { ++ let highlighter = new Util.Highlighter(tests[i].terms); ++ let output = highlighter.highlight(tests[i].input); ++ ++ JsUnit.assertEquals(`Test ${i + 1} highlight ` + ++ `"${tests[i].terms}" in "${tests[i].input}"`, ++ output, tests[i].output); ++ ++ let parsed = false; ++ try { ++ Pango.parse_markup(output, -1, ''); ++ parsed = true; ++ } catch (e) {} ++ JsUnit.assertEquals(`Test ${i + 1} is valid markup`, true, parsed); ++ } ++} catch (e) { ++ if (typeof(e.isJsUnitException) != 'undefined' ++ && e.isJsUnitException) ++ { ++ if (e.comment) ++ log(`Error in: ${e.comment}`); ++ } ++ throw e; ++} +-- +2.35.1 + diff --git a/SOURCES/fix-some-js-warnings.patch b/SOURCES/fix-some-js-warnings.patch new file mode 100644 index 0000000..67adf0d --- /dev/null +++ b/SOURCES/fix-some-js-warnings.patch @@ -0,0 +1,184 @@ +From 05a5f4641c8ad6337ccb46e63abcaf27dd7eb852 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 9 Jun 2020 19:42:21 +0200 +Subject: [PATCH 1/4] popupMenu: Guard against non-menu-item children + +This avoid a harmless but annoying warning. +--- + js/ui/popupMenu.js | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js +index 11528560d..144c600d7 100644 +--- a/js/ui/popupMenu.js ++++ b/js/ui/popupMenu.js +@@ -773,7 +773,8 @@ var PopupMenuBase = class { + } + + _getMenuItems() { +- return this.box.get_children().map(a => a._delegate).filter(item => { ++ const children = this.box.get_children().filter(a => a._delegate !== undefined); ++ return children.map(a => a._delegate).filter(item => { + return item instanceof PopupBaseMenuItem || item instanceof PopupMenuSection; + }); + } +-- +2.31.1 + + +From e5b2c2b3cfd0443fa83fd1f6f56f65fefa5186c3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 9 Jun 2020 19:48:06 +0200 +Subject: [PATCH 2/4] st/shadow: Check pipeline when painting + +We shouldn't simply assume that st_shadow_helper_update() has been +called before paint() or that the pipeline was created successfully. +--- + src/st/st-shadow.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/st/st-shadow.c b/src/st/st-shadow.c +index ab3eaa856..d53808698 100644 +--- a/src/st/st-shadow.c ++++ b/src/st/st-shadow.c +@@ -296,9 +296,10 @@ st_shadow_helper_paint (StShadowHelper *helper, + ClutterActorBox *actor_box, + guint8 paint_opacity) + { +- _st_paint_shadow_with_opacity (helper->shadow, +- framebuffer, +- helper->pipeline, +- actor_box, +- paint_opacity); ++ if (helper->pipeline != NULL) ++ _st_paint_shadow_with_opacity (helper->shadow, ++ framebuffer, ++ helper->pipeline, ++ actor_box, ++ paint_opacity); + } +-- +2.31.1 + + +From 0f7656d85af51339d14217b9a673442a18df3de8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 8 Jul 2021 19:10:05 +0200 +Subject: [PATCH 3/4] messageTray: Always remove destroyed banners + +Currently we only mark the banner as removed if it is destroyed +while in SHOWN or SHOWING state, but not if we're already HIDING +(for example in response to `NotificationBanner::done-displaying`). + +If this happens, we'll try to destroy the notification again at +the end of the transition, which leads to (harmless but annoying) +log spam since Notifications were turned into GObjects (that are +disposed when destroyed). + +Address this by always marking destroyed banners as removed, while +still only triggering a state update while shown (or in the process +of being shown). + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4457 +--- + js/ui/messageTray.js | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js +index 1dab00a70..ccf56fc5b 100644 +--- a/js/ui/messageTray.js ++++ b/js/ui/messageTray.js +@@ -1022,17 +1022,20 @@ var MessageTray = GObject.registerClass({ + } + + _onNotificationDestroy(notification) { +- if (this._notification == notification && (this._notificationState == State.SHOWN || this._notificationState == State.SHOWING)) { +- this._updateNotificationTimeout(0); +- this._notificationRemoved = true; +- this._updateState(); +- return; +- } ++ this._notificationRemoved = this._notification === notification; + +- let index = this._notificationQueue.indexOf(notification); +- if (index != -1) { +- this._notificationQueue.splice(index, 1); +- this.emit('queue-changed'); ++ if (this._notificationRemoved) { ++ if (this._notificationState === State.SHOWN || ++ this._notificationState === State.SHOWING) { ++ this._updateNotificationTimeout(0); ++ this._updateState(); ++ } ++ } else { ++ const index = this._notificationQueue.indexOf(notification); ++ if (index !== -1) { ++ this._notificationQueue.splice(index, 1); ++ this.emit('queue-changed'); ++ } + } + } + +-- +2.31.1 + + +From 8652836521d0729ce230268c7b448cdb393d5b47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 8 Jul 2021 19:23:38 +0200 +Subject: [PATCH 4/4] shellInfo: Don't destroy source on undo + +Destroying the source from an action callback will result in the +notification being destroyed twice: + + - source.destroy() destroys all its notifications + + - a notification destroys itself after an action + was activated + +This results in unwanted log spam when attempting to dispose the +notification for a second time. + +There is actually no good reason for destroying the source explicitly, +as sources already self-destruct with their last notification. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4457 +--- + js/ui/overview.js | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +diff --git a/js/ui/overview.js b/js/ui/overview.js +index 529779ea8..c71b11389 100644 +--- a/js/ui/overview.js ++++ b/js/ui/overview.js +@@ -25,16 +25,6 @@ var OVERVIEW_ACTIVATION_TIMEOUT = 0.5; + var ShellInfo = class { + constructor() { + this._source = null; +- this._undoCallback = null; +- } +- +- _onUndoClicked() { +- if (this._undoCallback) +- this._undoCallback(); +- this._undoCallback = null; +- +- if (this._source) +- this._source.destroy(); + } + + setMessage(text, options) { +@@ -64,9 +54,8 @@ var ShellInfo = class { + notification.update(text, null, { clear: true }); + } + +- this._undoCallback = undoCallback; + if (undoCallback) +- notification.addAction(_("Undo"), this._onUndoClicked.bind(this)); ++ notification.addAction(_('Undo'), () => undoCallback()); + + this._source.showNotification(notification); + } +-- +2.31.1 + diff --git a/SOURCES/gdm-networking.patch b/SOURCES/gdm-networking.patch new file mode 100644 index 0000000..6bb33d7 --- /dev/null +++ b/SOURCES/gdm-networking.patch @@ -0,0 +1,244 @@ +From 1eb9fef5e18d56bbe7a6422303ff8e31fe677759 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 7 Jun 2021 17:49:57 +0200 +Subject: [PATCH 1/5] status/network: Disable modem connection when windows + aren't allowed + +The item launches the corresponding Settings panel when activated, which +doesn't work when windows are disabled by the session mode. Rather than +failing silently, turn the item insensitive. +--- + js/ui/status/network.js | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/js/ui/status/network.js b/js/ui/status/network.js +index 5487fde40..6e7878d20 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -563,6 +563,10 @@ var NMDeviceModem = class extends NMConnectionDevice { + this._iconChanged(); + }); + } ++ ++ this._sessionUpdatedId = ++ Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); ++ this._sessionUpdated(); + } + + get category() { +@@ -573,6 +577,10 @@ var NMDeviceModem = class extends NMConnectionDevice { + launchSettingsPanel('network', 'connect-3g', this._device.get_path()); + } + ++ _sessionUpdated() { ++ this._autoConnectItem.sensitive = Main.sessionMode.hasWindows; ++ } ++ + destroy() { + if (this._operatorNameId) { + this._mobileDevice.disconnect(this._operatorNameId); +@@ -582,6 +590,10 @@ var NMDeviceModem = class extends NMConnectionDevice { + this._mobileDevice.disconnect(this._signalQualityId); + this._signalQualityId = 0; + } ++ if (this._sessionUpdatedId) { ++ Main.sessionMode.disconnect(this._sessionUpdatedId); ++ this._sessionUpdatedId = 0; ++ } + + super.destroy(); + } +-- +2.31.1 + + +From 0288558940c0090dca0873daeaa33e8d20cdbb0f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 7 Jun 2021 18:28:32 +0200 +Subject: [PATCH 2/5] status/network: Only list wifi networks that can be + activated + +Setting up a connection for an Enterprise WPA(2) encrypted wireless +network requires Settings. That's not available when windows are +disabled via the session mode, so filter out affected entries. +--- + js/ui/status/network.js | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +diff --git a/js/ui/status/network.js b/js/ui/status/network.js +index 6e7878d20..36915dbc1 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -1,6 +1,6 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + /* exported NMApplet */ +-const { Clutter, Gio, GLib, GObject, NM, St } = imports.gi; ++const { Clutter, Gio, GLib, GObject, Meta, NM, St } = imports.gi; + const Signals = imports.signals; + + const Animation = imports.ui.animation; +@@ -816,6 +816,11 @@ class NMWirelessDialog extends ModalDialog.ModalDialog { + GLib.source_remove(this._scanTimeoutId); + this._scanTimeoutId = 0; + } ++ ++ if (this._syncVisibilityId) { ++ Meta.later_remove(this._syncVisibilityId); ++ this._syncVisibilityId = 0; ++ } + } + + _onScanTimeout() { +@@ -1149,9 +1154,32 @@ class NMWirelessDialog extends ModalDialog.ModalDialog { + this._itemBox.insert_child_at_index(network.item, newPos); + } + ++ this._queueSyncItemVisibility(); + this._syncView(); + } + ++ _queueSyncItemVisibility() { ++ if (this._syncVisibilityId) ++ return; ++ ++ this._syncVisibilityId = Meta.later_add( ++ Meta.LaterType.BEFORE_REDRAW, ++ () => { ++ const { hasWindows } = Main.sessionMode; ++ const { WPA2_ENT, WPA_ENT } = NMAccessPointSecurity; ++ ++ for (const network of this._networks) { ++ const [firstAp] = network.accessPoints; ++ network.item.visible = ++ hasWindows || ++ network.connections.length > 0 || ++ (firstAp._secType !== WPA2_ENT && firstAp._secType !== WPA_ENT); ++ } ++ this._syncVisibilityId = 0; ++ return GLib.SOURCE_REMOVE; ++ }); ++ } ++ + _accessPointRemoved(device, accessPoint) { + let res = this._findExistingNetwork(accessPoint); + +-- +2.31.1 + + +From eb9620bc134ef8e7732f5e64b93ac9ea5bba2092 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 8 Jun 2021 00:17:48 +0200 +Subject: [PATCH 3/5] status/network: Consider network-control action + +NetworkManager installs a `network-control` polkit action that can +be used to disallow network configuration, except that we happily +ignore it. Add it to the conditions that turn a network section +insensitive. +--- + js/ui/status/network.js | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/js/ui/status/network.js b/js/ui/status/network.js +index 36915dbc1..e238fdfe7 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -1,6 +1,6 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + /* exported NMApplet */ +-const { Clutter, Gio, GLib, GObject, Meta, NM, St } = imports.gi; ++const { Clutter, Gio, GLib, GObject, Meta, NM, Polkit, St } = imports.gi; + const Signals = imports.signals; + + const Animation = imports.ui.animation; +@@ -1750,11 +1750,21 @@ class Indicator extends PanelMenu.SystemIndicator { + this._client.connect('connection-removed', this._connectionRemoved.bind(this)); + + Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); ++ try { ++ this._configPermission = await Polkit.Permission.new( ++ 'org.freedesktop.NetworkManager.network-control', null, null); ++ } catch (e) { ++ log('No permission to control network connections: %s'.format(e.toString())); ++ this._configPermission = null; ++ } + this._sessionUpdated(); + } + + _sessionUpdated() { +- let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; ++ const sensitive = ++ !Main.sessionMode.isLocked && ++ !Main.sessionMode.isGreeter && ++ this._configPermission && this._configPermission.allowed; + this.menu.setSensitive(sensitive); + } + +-- +2.31.1 + + +From 2392810bb7e3d48fb33c4d6de39f5be2eca58988 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 10 Jun 2021 23:12:27 +0200 +Subject: [PATCH 4/5] sessionMode: Enable networkAgent on login screen + +We will soon enable the network sections in the status menu on the +login screen, so enable the network agent to handle authentication +requests (like wifi/VPN passwords). +--- + js/ui/sessionMode.js | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index aa69fd115..4d4fb2444 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -47,7 +47,9 @@ const _modes = { + isGreeter: true, + isPrimary: true, + unlockDialog: imports.gdm.loginDialog.LoginDialog, +- components: ['polkitAgent'], ++ components: Config.HAVE_NETWORKMANAGER ++ ? ['networkAgent', 'polkitAgent'] ++ : ['polkitAgent'], + panel: { + left: [], + center: ['dateMenu'], +-- +2.31.1 + + +From b5fedfd846f271bf28be02ce5cd8517af7a3bc0a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 8 Jun 2021 00:19:26 +0200 +Subject: [PATCH 5/5] status/network: Do not disable on login screen + +We currently disable all network items on both the lock- and login +screen. While it makes sense to be very restrictive on the lock screen, +there are some (fringe) use cases for being more permissive on the +login screen (like remote home directories only accessible via VPN). + +There's precedence with the power-off/restart actions to be less +restrictive on the login screen, and since we started respecting +the `network-control` polkit action, it's possible to restore the +old behavior if desired. +--- + js/ui/status/network.js | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/js/ui/status/network.js b/js/ui/status/network.js +index e238fdfe7..f510f90ae 100644 +--- a/js/ui/status/network.js ++++ b/js/ui/status/network.js +@@ -1763,7 +1763,6 @@ class Indicator extends PanelMenu.SystemIndicator { + _sessionUpdated() { + const sensitive = + !Main.sessionMode.isLocked && +- !Main.sessionMode.isGreeter && + this._configPermission && this._configPermission.allowed; + this.menu.setSensitive(sensitive); + } +-- +2.31.1 + diff --git a/SOURCES/gnome-shell-enabled-extensions-background-logos.patch b/SOURCES/gnome-shell-enabled-extensions-background-logos.patch new file mode 100644 index 0000000..c511c66 --- /dev/null +++ b/SOURCES/gnome-shell-enabled-extensions-background-logos.patch @@ -0,0 +1,67 @@ +From 1f8252470ce43dc8a0680871013e2f4492764302 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 28 Feb 2022 10:27:09 -0500 +Subject: [PATCH] data: Enable logo extension out of the box + +Our brand team would like the logo extension to be used on new +installs. + +This commit makes sure it gets enabled out of the box. +--- + data/org.gnome.shell.gschema.xml.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in +index d5ea1e3..e3f440c 100644 +--- a/data/org.gnome.shell.gschema.xml.in ++++ b/data/org.gnome.shell.gschema.xml.in +@@ -1,45 +1,45 @@ + + + + true + + Enable internal tools useful for developers and testers from Alt-F2 + + + Allows access to internal debugging and monitoring tools + using the Alt-F2 dialog. + + + +- [] ++ ['background-logo@fedorahosted.org'] + UUIDs of extensions to enable + + GNOME Shell extensions have a UUID property; this key lists extensions + which should be loaded. Any extension that wants to be loaded needs + to be in this list. You can also manipulate this list with the + EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell. + + + + [] + UUIDs of extensions to force disabling + + GNOME Shell extensions have a UUID property; this key lists extensions + which should be disabled, even if loaded as part of the current mode. + You can also manipulate this list with the EnableExtension and + DisableExtension D-Bus methods on org.gnome.Shell. + This key takes precedence over the “enabled-extensions” setting. + + + + false + Disable user extensions + + Disable all extensions the user has enabled without affecting + the “enabled-extension” setting. + + + + false + Disables the validation of extension version compatibility +-- +2.35.1 + diff --git a/SOURCES/gnome-shell-favourite-apps-firefox.patch b/SOURCES/gnome-shell-favourite-apps-firefox.patch new file mode 100644 index 0000000..fba63ae --- /dev/null +++ b/SOURCES/gnome-shell-favourite-apps-firefox.patch @@ -0,0 +1,38 @@ +From a2e62e671260576d23f18c22c10a48ac4a8504af Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 17 Sep 2014 07:11:12 +0200 +Subject: [PATCH] Replace Web with Firefox in default favorites + +--- + data/org.gnome.shell.gschema.xml.in | 2 +- + js/ui/appFavorites.js | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in +index cd6a2356d..b8a13a9cc 100644 +--- a/data/org.gnome.shell.gschema.xml.in ++++ b/data/org.gnome.shell.gschema.xml.in +@@ -50,7 +50,7 @@ + + + +- [ 'org.gnome.Epiphany.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ] ++ [ 'firefox.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ] + List of desktop file IDs for favorite applications + + The applications corresponding to these identifiers +diff --git a/js/ui/appFavorites.js b/js/ui/appFavorites.js +index a876727ed..24ce16f81 100644 +--- a/js/ui/appFavorites.js ++++ b/js/ui/appFavorites.js +@@ -52,6 +52,7 @@ const RENAMED_DESKTOP_IDS = { + 'gnotski.desktop': 'org.gnome.Klotski.desktop', + 'gtali.desktop': 'org.gnome.Tali.desktop', + 'iagno.desktop': 'org.gnome.Reversi.desktop', ++ 'mozilla-firefox.desktop': 'firefox.desktop', + 'nautilus.desktop': 'org.gnome.Nautilus.desktop', + 'org.gnome.gnome-2048.desktop': 'org.gnome.TwentyFortyEight.desktop', + 'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop', +-- +2.30.1 + diff --git a/SOURCES/gnome-shell-favourite-apps-terminal.patch b/SOURCES/gnome-shell-favourite-apps-terminal.patch new file mode 100644 index 0000000..5f7207a --- /dev/null +++ b/SOURCES/gnome-shell-favourite-apps-terminal.patch @@ -0,0 +1,25 @@ +From 1e699b55f3dc84b2ddbc5acd03424240eddbe06c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 9 Mar 2017 14:44:32 +0100 +Subject: [PATCH 3/3] appFavorites: Add terminal + +--- + data/org.gnome.shell.gschema.xml.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in +index 35ddaf4a9..d5ea1e35f 100644 +--- a/data/org.gnome.shell.gschema.xml.in ++++ b/data/org.gnome.shell.gschema.xml.in +@@ -50,7 +50,7 @@ + + + +- [ 'firefox.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop' ] ++ [ 'firefox.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop', 'org.gnome.Terminal.desktop' ] + List of desktop file IDs for favorite applications + + The applications corresponding to these identifiers +-- +2.31.1 + diff --git a/SOURCES/gnome-shell-favourite-apps-yelp.patch b/SOURCES/gnome-shell-favourite-apps-yelp.patch new file mode 100644 index 0000000..f47dab8 --- /dev/null +++ b/SOURCES/gnome-shell-favourite-apps-yelp.patch @@ -0,0 +1,26 @@ +From 4e21aed64d48ddd22e40a3605084379b2fa7f1cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 9 Mar 2017 14:44:03 +0100 +Subject: [PATCH 2/3] Add 'yelp' to default favorites + +Help should be easily available, so add it to the default favorites. +--- + data/org.gnome.shell.gschema.xml.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in +index b8a13a9cc..35ddaf4a9 100644 +--- a/data/org.gnome.shell.gschema.xml.in ++++ b/data/org.gnome.shell.gschema.xml.in +@@ -50,7 +50,7 @@ + + + +- [ 'firefox.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ] ++ [ 'firefox.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop' ] + List of desktop file IDs for favorite applications + + The applications corresponding to these identifiers +-- +2.31.1 + diff --git a/SOURCES/login-screen-extensions.patch b/SOURCES/login-screen-extensions.patch new file mode 100644 index 0000000..bdfb9a1 --- /dev/null +++ b/SOURCES/login-screen-extensions.patch @@ -0,0 +1,227 @@ +From 4024d59871d0c8990ef5e4243c9fc485971755e7 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 10 Aug 2021 13:25:57 -0400 +Subject: [PATCH 1/3] extensionSystem: Get rid of _enabled boolean optimization + +At the moment a session mode either allows extensions or it doesn't. +If it allows extensions, then the entire available list of +configured extensions get enabled as soon as the session mode is +entered. + +Since enabling or disabling extensions is an all or nothing situation, +the code tracks whether extensions are already enabled when entering +the session mode, and if so, avoids iterating through the extension list +needlessly. It does this using a boolean named _enabled. + +In the future, the extensions themselves will be given some say on +whether or not they should be enabled in a given session mode. This +means, the configured extension list may contain extensions that +shouldn't be enabled for a given session mode, and the _enabled boolean +will no longer be appropriated. + +This commit drops the _enabled boolean optimization. +--- + js/ui/extensionSystem.js | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js +index 9f4eb757b..2aae44b53 100644 +--- a/js/ui/extensionSystem.js ++++ b/js/ui/extensionSystem.js +@@ -23,7 +23,6 @@ const UPDATE_CHECK_TIMEOUT = 24 * 60 * 60; // 1 day in seconds + var ExtensionManager = class { + constructor() { + this._initialized = false; +- this._enabled = false; + this._updateNotified = false; + + this._extensions = new Map(); +@@ -597,9 +596,6 @@ var ExtensionManager = class { + } + + _enableAllExtensions() { +- if (this._enabled) +- return; +- + if (!this._initialized) { + this._loadExtensions(); + this._initialized = true; +@@ -608,20 +604,14 @@ var ExtensionManager = class { + this._callExtensionEnable(uuid); + }); + } +- this._enabled = true; + } + + _disableAllExtensions() { +- if (!this._enabled) +- return; +- + if (this._initialized) { + this._extensionOrder.slice().reverse().forEach(uuid => { + this._callExtensionDisable(uuid); + }); + } +- +- this._enabled = false; + } + + _sessionUpdated() { +-- +2.33.1 + + +From f883c3f87f9778a0c2ed34db648aad73668949e3 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sat, 28 Aug 2021 13:54:39 -0400 +Subject: [PATCH 2/3] extensionSystem: Allow extensions to run on the login + screen + +At the moment it's not realy possible to extend the login screen to do +things it doesn't have built-in support for. This means in order +to support niche use cases, those cases have to change the main +code base. For instance, oVirt and Vmware deployments want to be able +to automaticaly log in guest VMs when a user pre-authenticates through a +console on a management host. To support those use cases, we added +code to the login screen directly, even though most machines will never +be associated with oVirt or Vmware management hosts. + +We also get requests from e.g. government users that need certain features +at the login screen that wouldn't get used much outside of government +deployments. For instance, we've gotten requests that a machine contains +prominently displays that it has "Top Secret" information. + +All of these use cases seem like they would better handled via +extensions that could be installed in the specific deployments. The +problem is extensions only run in the user session, and get +disabled at the login screen automatically. + +This commit changes that. Now extensions can specify in their metadata +via a new sessionModes property, which modes that want to run in. For +backward compatibility, if an extension doesn't specify which session +modes it works in, its assumed the extension only works in the user +session. +--- + js/ui/extensionSystem.js | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js +index 2aae44b53..937f86199 100644 +--- a/js/ui/extensionSystem.js ++++ b/js/ui/extensionSystem.js +@@ -75,6 +75,28 @@ var ExtensionManager = class { + return [...this._extensions.keys()]; + } + ++ _extensionSupportsSessionMode(uuid) { ++ const extension = this.lookup(uuid); ++ if (!extension) ++ return false; ++ ++ if (extension.sessionModes.includes(Main.sessionMode.currentMode)) ++ return true; ++ if (extension.sessionModes.includes(Main.sessionMode.parentMode)) ++ return true; ++ return false; ++ } ++ ++ _sessionModeCanUseExtension(uuid) { ++ if (!Main.sessionMode.allowExtensions) ++ return false; ++ ++ if (!this._extensionSupportsSessionMode(uuid)) ++ return false; ++ ++ return true; ++ } ++ + _callExtensionDisable(uuid) { + let extension = this.lookup(uuid); + if (!extension) +@@ -134,7 +156,7 @@ var ExtensionManager = class { + } + + _callExtensionEnable(uuid) { +- if (!Main.sessionMode.allowExtensions) ++ if (!this._sessionModeCanUseExtension(uuid)) + return; + + let extension = this.lookup(uuid); +@@ -316,6 +338,7 @@ var ExtensionManager = class { + hasPrefs: dir.get_child('prefs.js').query_exists(null), + hasUpdate: false, + canChange: false, ++ sessionModes: meta['session-modes'] ? meta['session-modes'] : [ 'user' ], + }; + this._extensions.set(uuid, extension); + +@@ -398,7 +421,7 @@ var ExtensionManager = class { + } + + _callExtensionInit(uuid) { +- if (!Main.sessionMode.allowExtensions) ++ if (!this._sessionModeCanUseExtension(uuid)) + return false; + + let extension = this.lookup(uuid); +@@ -487,13 +510,15 @@ var ExtensionManager = class { + // Find and enable all the newly enabled extensions: UUIDs found in the + // new setting, but not in the old one. + newEnabledExtensions +- .filter(uuid => !this._enabledExtensions.includes(uuid)) ++ .filter(uuid => !this._enabledExtensions.includes(uuid) && ++ this._extensionSupportsSessionMode(uuid)) + .forEach(uuid => this._callExtensionEnable(uuid)); + + // Find and disable all the newly disabled extensions: UUIDs found in the + // old setting, but not in the new one. + this._extensionOrder +- .filter(uuid => !newEnabledExtensions.includes(uuid)) ++ .filter(uuid => !newEnabledExtensions.includes(uuid) || ++ !this._extensionSupportsSessionMode(uuid)) + .reverse().forEach(uuid => this._callExtensionDisable(uuid)); + + this._enabledExtensions = newEnabledExtensions; +-- +2.33.1 + + +From c637d0a14ea7223ea7d763e1c4dedb4d6b6609a4 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 10 Aug 2021 15:31:00 -0400 +Subject: [PATCH 3/3] sessionMode: Allow extensions at the login and unlock + screens + +Now extensions can specify which session modes they work in, +but specifying the login screen or unlock screen session modes in +an extensions metadata still won't work, because those session +modes disallow extensions. + +This commit fixes that. +--- + js/ui/sessionMode.js | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index 4d4fb2444..0534fd1d4 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -43,6 +43,7 @@ const _modes = { + }, + + 'gdm': { ++ allowExtensions: true, + hasNotifications: true, + isGreeter: true, + isPrimary: true, +@@ -59,6 +60,7 @@ const _modes = { + }, + + 'unlock-dialog': { ++ allowExtensions: true, + isLocked: true, + unlockDialog: undefined, + components: ['polkitAgent', 'telepathyClient'], +-- +2.33.1 + diff --git a/SOURCES/restrict-dbus-callers.patch b/SOURCES/restrict-dbus-callers.patch new file mode 100644 index 0000000..914adcd --- /dev/null +++ b/SOURCES/restrict-dbus-callers.patch @@ -0,0 +1,1353 @@ +From eb26ea5e1bb0c6fc978aae5db99ed3427b34175b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 1 Apr 2022 19:40:31 +0200 +Subject: [PATCH 01/12] shell/global: Expose shim context property + +Parts of the following commits rely on the ShellGlobal:context +property that was added in GNOME 41 to expose the MetaContext +(likewise a GNOME 41 addition). + +To prepare for that, expose a small shim object as context +property that mimicks the expected upstream API. +--- + src/shell-global.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 92 insertions(+) + +diff --git a/src/shell-global.c b/src/shell-global.c +index 24e771f52..805c73145 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -47,6 +47,9 @@ + + static ShellGlobal *the_object = NULL; + ++#define SHIM_TYPE_META_CONTEXT shim_meta_context_get_type () ++G_DECLARE_FINAL_TYPE (ShimMetaContext, shim_meta_context, SHIM, META_CONTEXT, GObject) ++ + struct _ShellGlobal { + GObject parent; + +@@ -54,6 +57,7 @@ struct _ShellGlobal { + + MetaBackend *backend; + MetaDisplay *meta_display; ++ ShimMetaContext *meta_context; + MetaWorkspaceManager *workspace_manager; + Display *xdisplay; + +@@ -92,6 +96,7 @@ enum { + + PROP_SESSION_MODE, + PROP_BACKEND, ++ PROP_CONTEXT, + PROP_DISPLAY, + PROP_WORKSPACE_MANAGER, + PROP_SCREEN_WIDTH, +@@ -235,6 +240,9 @@ shell_global_get_property(GObject *object, + case PROP_BACKEND: + g_value_set_object (value, global->backend); + break; ++ case PROP_CONTEXT: ++ g_value_set_object (value, global->meta_context); ++ break; + case PROP_DISPLAY: + g_value_set_object (value, global->meta_display); + break; +@@ -514,6 +522,13 @@ shell_global_class_init (ShellGlobalClass *klass) + "MetaBackend object", + META_TYPE_BACKEND, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); ++ g_object_class_install_property (gobject_class, ++ PROP_CONTEXT, ++ g_param_spec_object ("context", ++ "Context", ++ "MetaContext object", ++ G_TYPE_OBJECT, ++ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_DISPLAY, + g_param_spec_object ("display", +@@ -996,6 +1011,7 @@ _shell_global_set_plugin (ShellGlobal *global, + + display = meta_plugin_get_display (plugin); + global->meta_display = display; ++ global->meta_context = g_object_new (SHIM_TYPE_META_CONTEXT, NULL); + global->workspace_manager = meta_display_get_workspace_manager (display); + + global->stage = CLUTTER_STAGE (meta_get_stage_for_display (display)); +@@ -1888,3 +1904,79 @@ _shell_global_locate_pointer (ShellGlobal *global) + { + g_signal_emit (global, shell_global_signals[LOCATE_POINTER], 0); + } ++ ++enum { ++ SHIM_PROP_0, ++ ++ SHIM_PROP_UNSAFE_MODE, ++ ++ N_SHIM_PROPS ++}; ++ ++static GParamSpec *shim_obj_props [N_SHIM_PROPS]; ++ ++struct _ShimMetaContext ++{ ++ GObject parent_instance; ++}; ++ ++G_DEFINE_TYPE (ShimMetaContext, shim_meta_context, G_TYPE_OBJECT); ++ ++static void ++shim_meta_context_get_property (GObject *object, ++ guint prop_id, ++ GValue *value, ++ GParamSpec *pspec) ++{ ++ switch (prop_id) ++ { ++ case SHIM_PROP_UNSAFE_MODE: ++ { ++ gboolean unsafe_mode; ++ ++ g_object_get (meta_get_backend (), "unsafe-mode", &unsafe_mode, NULL); ++ g_value_set_boolean (value, unsafe_mode); ++ } ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); ++ } ++} ++ ++static void ++shim_meta_context_set_property (GObject *object, ++ guint prop_id, ++ const GValue *value, ++ GParamSpec *pspec) ++{ ++ switch (prop_id) ++ { ++ case SHIM_PROP_UNSAFE_MODE: ++ g_object_set_property (G_OBJECT (meta_get_backend ()), "unsafe-mode", value); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); ++ } ++} ++ ++static void ++shim_meta_context_class_init (ShimMetaContextClass *klass) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ ++ object_class->get_property = shim_meta_context_get_property; ++ object_class->set_property = shim_meta_context_set_property; ++ ++ shim_obj_props[SHIM_PROP_UNSAFE_MODE] = ++ g_param_spec_boolean ("unsafe-mode", ++ "unsafe mode", ++ "Unsafe mode", ++ FALSE, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); ++ g_object_class_install_properties (object_class, N_SHIM_PROPS, shim_obj_props); ++} ++ ++static void ++shim_meta_context_init (ShimMetaContext *self) ++{ ++} +-- +2.35.1 + + +From 20fcc7bc78a3c227304e89deddc57266e560175c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 2 Sep 2021 17:15:36 +0200 +Subject: [PATCH 02/12] panel: Show warning indicator when unsafe-mode is on + +MetaContext added an unsafe-mode property, which we will use to restrict +a number of privileged operations unless it is enabled. It is meant to +only be enabled temporarily for development/debugging purposes, so add +a scary icon to the top bar as a reminder to turn it off again. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/ui/panel.js | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/js/ui/panel.js b/js/ui/panel.js +index 380480744..c57c3ba8e 100644 +--- a/js/ui/panel.js ++++ b/js/ui/panel.js +@@ -641,6 +641,20 @@ class PanelCorner extends St.DrawingArea { + } + }); + ++const UnsafeModeIndicator = GObject.registerClass( ++class UnsafeModeIndicator extends PanelMenu.SystemIndicator { ++ _init() { ++ super._init(); ++ ++ this._indicator = this._addIndicator(); ++ this._indicator.icon_name = 'channel-insecure-symbolic'; ++ ++ global.context.bind_property('unsafe-mode', ++ this._indicator, 'visible', ++ GObject.BindingFlags.SYNC_CREATE); ++ } ++}); ++ + var AggregateLayout = GObject.registerClass( + class AggregateLayout extends Clutter.BoxLayout { + _init(params = {}) { +@@ -702,6 +716,7 @@ class AggregateMenu extends PanelMenu.Button { + this._location = new imports.ui.status.location.Indicator(); + this._nightLight = new imports.ui.status.nightLight.Indicator(); + this._thunderbolt = new imports.ui.status.thunderbolt.Indicator(); ++ this._unsafeMode = new UnsafeModeIndicator(); + + this._indicators.add_child(this._remoteAccess); + this._indicators.add_child(this._thunderbolt); +@@ -713,6 +728,7 @@ class AggregateMenu extends PanelMenu.Button { + this._indicators.add_child(this._bluetooth); + this._indicators.add_child(this._rfkill); + this._indicators.add_child(this._volume); ++ this._indicators.add_child(this._unsafeMode); + this._indicators.add_child(this._power); + this._indicators.add_child(this._powerProfiles); + +-- +2.35.1 + + +From 158eeebc1d3a243e75de550cf5711e38a9f77f7f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 17 Jun 2021 01:50:50 +0200 +Subject: [PATCH 03/12] shellDBus: Use MetaContext:unsafe-mode to restrict + Eval() + +The Eval() method is unarguably the most sensitive D-Bus method +we expose, since it allows running arbitrary code in the compositor. + +It is currently tied to the `development-tools` settings that is +enabled by default. As users have become accustomed to the built-in +commands that are enabled by the same setting (restart, lg, ...), +that default cannot easily be changed. + +In order to restrict the method without affecting the rather harmless +commands, guard it by the new MetaContext:unsafe-mode property instead +of the setting. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/ui/shellDBus.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js +index 734ca4fc7..5a6edec74 100644 +--- a/js/ui/shellDBus.js ++++ b/js/ui/shellDBus.js +@@ -54,7 +54,7 @@ var GnomeShell = class { + * + */ + Eval(code) { +- if (!global.settings.get_boolean('development-tools')) ++ if (!global.context.unsafe_mode) + return [false, '']; + + let returnValue; +-- +2.35.1 + + +From 0882e04a11fe8db7abf05a5d7c786664dc54ad4f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 2 Sep 2021 16:23:38 +0200 +Subject: [PATCH 04/12] introspect: Make invocation check error-based + +If we throw an error when the invocation isn't allowed instead of +returning false, we can simply return that error instead of duplicating +the error handling. + +Part-of: +--- + js/misc/introspect.js | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/js/misc/introspect.js b/js/misc/introspect.js +index e46a7e8c5..318955be2 100644 +--- a/js/misc/introspect.js ++++ b/js/misc/introspect.js +@@ -134,21 +134,23 @@ var IntrospectService = class { + type == Meta.WindowType.UTILITY; + } + +- _isInvocationAllowed(invocation) { ++ _checkInvocation(invocation) { + if (this._isIntrospectEnabled()) +- return true; ++ return; + + if (this._isSenderAllowed(invocation.get_sender())) +- return true; ++ return; + +- return false; ++ throw new GLib.Error(Gio.DBusError, ++ Gio.DBusError.ACCESS_DENIED, ++ 'App introspection not allowed'); + } + + GetRunningApplicationsAsync(params, invocation) { +- if (!this._isInvocationAllowed(invocation)) { +- invocation.return_error_literal(Gio.DBusError, +- Gio.DBusError.ACCESS_DENIED, +- 'App introspection not allowed'); ++ try { ++ this._checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); + return; + } + +@@ -160,10 +162,10 @@ var IntrospectService = class { + let apps = this._appSystem.get_running(); + let windowsList = {}; + +- if (!this._isInvocationAllowed(invocation)) { +- invocation.return_error_literal(Gio.DBusError, +- Gio.DBusError.ACCESS_DENIED, +- 'App introspection not allowed'); ++ try { ++ this._checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); + return; + } + +-- +2.35.1 + + +From 33c3c3846f62cc4737f0029455f9dcd838876bca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 1 Sep 2021 21:18:42 +0200 +Subject: [PATCH 05/12] introspect: Use MetaContext:unsafe-mode instead of + setting + +The property was added precisely for this purpose, except that its +name isn't tied to the introspect API. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/misc/introspect.js | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/js/misc/introspect.js b/js/misc/introspect.js +index 318955be2..967e7b830 100644 +--- a/js/misc/introspect.js ++++ b/js/misc/introspect.js +@@ -1,8 +1,6 @@ + /* exported IntrospectService */ + const { Gio, GLib, Meta, Shell, St } = imports.gi; + +-const INTROSPECT_SCHEMA = 'org.gnome.shell'; +-const INTROSPECT_KEY = 'introspect'; + const APP_ALLOWLIST = ['org.freedesktop.impl.portal.desktop.gtk']; + + const INTROSPECT_DBUS_API_VERSION = 3; +@@ -33,10 +31,6 @@ var IntrospectService = class { + this._syncRunningApplications(); + }); + +- this._introspectSettings = new Gio.Settings({ +- schema_id: INTROSPECT_SCHEMA, +- }); +- + let tracker = Shell.WindowTracker.get_default(); + tracker.connect('notify::focus-app', + () => { +@@ -70,10 +64,6 @@ var IntrospectService = class { + return app.get_windows().some(w => w.transient_for == null); + } + +- _isIntrospectEnabled() { +- return this._introspectSettings.get_boolean(INTROSPECT_KEY); +- } +- + _isSenderAllowed(sender) { + return [...this._allowlistMap.values()].includes(sender); + } +@@ -135,7 +125,7 @@ var IntrospectService = class { + } + + _checkInvocation(invocation) { +- if (this._isIntrospectEnabled()) ++ if (global.context.unsafe_mode) + return; + + if (this._isSenderAllowed(invocation.get_sender())) +-- +2.35.1 + + +From 4238128ba403da2cc788b0b249ee34acbea5d743 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 1 Sep 2021 21:25:26 +0200 +Subject: [PATCH 06/12] data: Remove now unused "introspect" setting + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + data/org.gnome.shell.gschema.xml.in | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in +index d5ea1e35f..6f1c424ba 100644 +--- a/data/org.gnome.shell.gschema.xml.in ++++ b/data/org.gnome.shell.gschema.xml.in +@@ -104,14 +104,6 @@ + number can be used to effectively disable the dialog. + + +- +- false +- Enable introspection API +- +- Enables a D-Bus API that allows to introspect the application state of +- the shell. +- +- + + +Date: Wed, 16 Jun 2021 19:09:42 +0200 +Subject: [PATCH 07/12] introspect: Split out DBusSenderChecker + +Restricting callers to a list of allowed senders is useful for +other D-Bus services as well, so split out the existing code +into a reusable class. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/misc/introspect.js | 30 ++++------------------- + js/misc/util.js | 56 ++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 59 insertions(+), 27 deletions(-) + +diff --git a/js/misc/introspect.js b/js/misc/introspect.js +index 967e7b830..e9d9260c0 100644 +--- a/js/misc/introspect.js ++++ b/js/misc/introspect.js +@@ -6,6 +6,7 @@ const APP_ALLOWLIST = ['org.freedesktop.impl.portal.desktop.gtk']; + const INTROSPECT_DBUS_API_VERSION = 3; + + const { loadInterfaceXML } = imports.misc.fileUtils; ++const { DBusSenderChecker } = imports.misc.util; + + const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect'); + +@@ -40,14 +41,7 @@ var IntrospectService = class { + + this._syncRunningApplications(); + +- this._allowlistMap = new Map(); +- APP_ALLOWLIST.forEach(appName => { +- Gio.DBus.watch_name(Gio.BusType.SESSION, +- appName, +- Gio.BusNameWatcherFlags.NONE, +- (conn, name, owner) => this._allowlistMap.set(name, owner), +- (conn, name) => this._allowlistMap.delete(name)); +- }); ++ this._senderChecker = new DBusSenderChecker(APP_ALLOWLIST); + + this._settings = St.Settings.get(); + this._settings.connect('notify::enable-animations', +@@ -64,10 +58,6 @@ var IntrospectService = class { + return app.get_windows().some(w => w.transient_for == null); + } + +- _isSenderAllowed(sender) { +- return [...this._allowlistMap.values()].includes(sender); +- } +- + _getSandboxedAppId(app) { + let ids = app.get_windows().map(w => w.get_sandboxed_app_id()); + return ids.find(id => id != null); +@@ -124,21 +114,9 @@ var IntrospectService = class { + type == Meta.WindowType.UTILITY; + } + +- _checkInvocation(invocation) { +- if (global.context.unsafe_mode) +- return; +- +- if (this._isSenderAllowed(invocation.get_sender())) +- return; +- +- throw new GLib.Error(Gio.DBusError, +- Gio.DBusError.ACCESS_DENIED, +- 'App introspection not allowed'); +- } +- + GetRunningApplicationsAsync(params, invocation) { + try { +- this._checkInvocation(invocation); ++ this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -153,7 +131,7 @@ var IntrospectService = class { + let windowsList = {}; + + try { +- this._checkInvocation(invocation); ++ this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +diff --git a/js/misc/util.js b/js/misc/util.js +index 802398d18..e6c183fbf 100644 +--- a/js/misc/util.js ++++ b/js/misc/util.js +@@ -2,7 +2,7 @@ + /* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine, + formatTime, formatTimeSpan, createTimeLabel, insertSorted, + ensureActorVisibleInScrollView, wiggle, lerp, GNOMEversionCompare, +- Highlighter */ ++ DBusSenderChecker, Highlighter */ + + const { Clutter, Gio, GLib, Shell, St, GnomeDesktop } = imports.gi; + const Gettext = imports.gettext; +@@ -479,6 +479,60 @@ function GNOMEversionCompare(version1, version2) { + return 0; + } + ++var DBusSenderChecker = class { ++ /** ++ * @param {string[]} allowList - list of allowed well-known names ++ */ ++ constructor(allowList) { ++ this._allowlistMap = new Map(); ++ ++ this._watchList = allowList.map(name => { ++ return Gio.DBus.watch_name(Gio.BusType.SESSION, ++ name, ++ Gio.BusNameWatcherFlags.NONE, ++ (conn_, name_, owner) => this._allowlistMap.set(name, owner), ++ () => this._allowlistMap.delete(name)); ++ }); ++ } ++ ++ /** ++ * @param {string} sender - the bus name that invoked the checked method ++ * @returns {bool} ++ */ ++ _isSenderAllowed(sender) { ++ return [...this._allowlistMap.values()].includes(sender); ++ } ++ ++ /** ++ * Check whether the bus name that invoked @invocation maps ++ * to an entry in the allow list. ++ * ++ * @throws ++ * @param {Gio.DBusMethodInvocation} invocation - the invocation ++ * @returns {void} ++ */ ++ checkInvocation(invocation) { ++ if (global.context.unsafe_mode) ++ return; ++ ++ if (this._isSenderAllowed(invocation.get_sender())) ++ return; ++ ++ throw new GLib.Error(Gio.DBusError, ++ Gio.DBusError.ACCESS_DENIED, ++ '%s is not allowed'.format(invocation.get_method_name())); ++ } ++ ++ /** ++ * @returns {void} ++ */ ++ destroy() { ++ for (const id in this._watchList) ++ Gio.DBus.unwatch_name(id); ++ this._watchList = []; ++ } ++}; ++ + /* @class Highlighter Highlight given terms in text using markup. */ + var Highlighter = class { + /** +-- +2.35.1 + + +From c6679a876a3c73c2c691333a5b987e27965231f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 17 Jun 2021 15:29:42 +0200 +Subject: [PATCH 08/12] shellDBus: Implement all methods asynchronously + +In order to restrict callers, we will need access to the invocation, +not just the unpacked method parameters. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/ui/shellDBus.js | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js +index 5a6edec74..aa5b4dc3c 100644 +--- a/js/ui/shellDBus.js ++++ b/js/ui/shellDBus.js +@@ -72,11 +72,26 @@ var GnomeShell = class { + return [success, returnValue]; + } + +- FocusSearch() { ++ /** ++ * Focus the overview's search entry ++ * ++ * @param {...any} params - method parameters ++ * @param {Gio.DBusMethodInvocation} invocation - the invocation ++ * @returns {void} ++ */ ++ FocusSearchAsync(params, invocation) { + Main.overview.focusSearch(); ++ invocation.return_value(null); + } + +- ShowOSD(params) { ++ /** ++ * Show OSD with the specified parameters ++ * ++ * @param {...any} params - method parameters ++ * @param {Gio.DBusMethodInvocation} invocation - the invocation ++ * @returns {void} ++ */ ++ ShowOSDAsync([params], invocation) { + for (let param in params) + params[param] = params[param].deep_unpack(); + +@@ -97,6 +112,7 @@ var GnomeShell = class { + icon = Gio.Icon.new_for_string(serializedIcon); + + Main.osdWindowManager.show(monitorIndex, icon, label, level, maxLevel); ++ invocation.return_value(null); + } + + /** +@@ -118,10 +134,19 @@ var GnomeShell = class { + } + + Main.overview.selectApp(id); ++ invocation.return_value(null); + } + +- ShowApplications() { ++ /** ++ * Show the overview's app grid ++ * ++ * @param {...any} params - method parameters ++ * @param {Gio.DBusMethodInvocation} invocation - the invocation ++ * @returns {void} ++ */ ++ ShowApplicationsAsync(params, invocation) { + Main.overview.show(ControlsState.APP_GRID); ++ invocation.return_value(null); + } + + GrabAcceleratorAsync(params, invocation) { +-- +2.35.1 + + +From 3ad733997eecb069be543f1a4452d7a7916a0962 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 17 Jun 2021 15:29:42 +0200 +Subject: [PATCH 09/12] shellDBus: Restrict callers + +The org.gnome.Shell interface provides a private API to other core +components to implement desktop functionalities like Settings or +global keybindings. It is not meant as a public API, so limit it +to a set of expected callers. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/ui/shellDBus.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 76 insertions(+) + +diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js +index aa5b4dc3c..c511314f9 100644 +--- a/js/ui/shellDBus.js ++++ b/js/ui/shellDBus.js +@@ -10,6 +10,7 @@ const Main = imports.ui.main; + const Screenshot = imports.ui.screenshot; + + const { loadInterfaceXML } = imports.misc.fileUtils; ++const { DBusSenderChecker } = imports.misc.util; + const { ControlsState } = imports.ui.overviewControls; + + const GnomeShellIface = loadInterfaceXML('org.gnome.Shell'); +@@ -20,6 +21,11 @@ var GnomeShell = class { + this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this); + this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell'); + ++ this._senderChecker = new DBusSenderChecker([ ++ 'org.gnome.ControlCenter', ++ 'org.gnome.SettingsDaemon.MediaKeys', ++ ]); ++ + this._extensionsService = new GnomeShellExtensions(); + this._screenshotService = new Screenshot.ScreenshotService(); + +@@ -80,6 +86,13 @@ var GnomeShell = class { + * @returns {void} + */ + FocusSearchAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + Main.overview.focusSearch(); + invocation.return_value(null); + } +@@ -92,6 +105,13 @@ var GnomeShell = class { + * @returns {void} + */ + ShowOSDAsync([params], invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + for (let param in params) + params[param] = params[param].deep_unpack(); + +@@ -124,6 +144,13 @@ var GnomeShell = class { + * @returns {void} + */ + FocusAppAsync([id], invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + const appSys = Shell.AppSystem.get_default(); + if (appSys.lookup_app(id) === null) { + invocation.return_error_literal( +@@ -145,11 +172,25 @@ var GnomeShell = class { + * @returns {void} + */ + ShowApplicationsAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + Main.overview.show(ControlsState.APP_GRID); + invocation.return_value(null); + } + + GrabAcceleratorAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let [accel, modeFlags, grabFlags] = params; + let sender = invocation.get_sender(); + let bindingAction = this._grabAcceleratorForSender(accel, modeFlags, grabFlags, sender); +@@ -157,6 +198,13 @@ var GnomeShell = class { + } + + GrabAcceleratorsAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let [accels] = params; + let sender = invocation.get_sender(); + let bindingActions = []; +@@ -168,6 +216,13 @@ var GnomeShell = class { + } + + UngrabAcceleratorAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let [action] = params; + let sender = invocation.get_sender(); + let ungrabSucceeded = this._ungrabAcceleratorForSender(action, sender); +@@ -176,6 +231,13 @@ var GnomeShell = class { + } + + UngrabAcceleratorsAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let [actions] = params; + let sender = invocation.get_sender(); + let ungrabSucceeded = true; +@@ -256,6 +318,13 @@ var GnomeShell = class { + } + + ShowMonitorLabelsAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let sender = invocation.get_sender(); + let [dict] = params; + Main.osdMonitorLabeler.show(sender, dict); +@@ -263,6 +332,13 @@ var GnomeShell = class { + } + + HideMonitorLabelsAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let sender = invocation.get_sender(); + Main.osdMonitorLabeler.hide(sender); + invocation.return_value(null); +-- +2.35.1 + + +From 5b87782b4950742b6ae1b29777e7812c93892ad7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 16 Jun 2021 22:11:50 +0200 +Subject: [PATCH 10/12] screenshot: Restrict callers + +The shell D-Bus API was always meant as a private API for core +components, so enforce that by limiting caller to a list of +allowed well-known names. + +Applications that want to request a screenshot can use the corresponding +desktop portal. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3943 + +Part-of: +--- + js/ui/screenshot.js | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js +index 81ab516b1..bf537b7d6 100644 +--- a/js/ui/screenshot.js ++++ b/js/ui/screenshot.js +@@ -15,6 +15,7 @@ Gio._promisify(Shell.Screenshot.prototype, + 'screenshot_area', 'screenshot_area_finish'); + + const { loadInterfaceXML } = imports.misc.fileUtils; ++const { DBusSenderChecker } = imports.misc.util; + + const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot'); + +@@ -24,6 +25,12 @@ var ScreenshotService = class { + this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screenshot'); + + this._screenShooter = new Map(); ++ this._senderChecker = new DBusSenderChecker([ ++ 'org.gnome.SettingsDaemon.MediaKeys', ++ 'org.freedesktop.impl.portal.desktop.gtk', ++ 'org.freedesktop.impl.portal.desktop.gnome', ++ 'org.gnome.Screenshot', ++ ]); + + this._lockdownSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.lockdown' }); + +@@ -46,6 +53,13 @@ var ScreenshotService = class { + Gio.IOErrorEnum, Gio.IOErrorEnum.PERMISSION_DENIED, + 'Saving to disk is disabled'); + return null; ++ } else { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return null; ++ } + } + + let shooter = new Shell.Screenshot(); +@@ -254,6 +268,13 @@ var ScreenshotService = class { + } + + async SelectAreaAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let selectArea = new SelectArea(); + try { + let areaRectangle = await selectArea.selectAsync(); +@@ -269,6 +290,13 @@ var ScreenshotService = class { + } + + FlashAreaAsync(params, invocation) { ++ try { ++ this._senderChecker.checkInvocation(invocation); ++ } catch (e) { ++ invocation.return_gerror(e); ++ return; ++ } ++ + let [x, y, width, height] = params; + [x, y, width, height] = this._scaleArea(x, y, width, height); + if (!this._checkArea(x, y, width, height)) { +-- +2.35.1 + + +From b02e721663ed1481ff7b4cf40cae3a34d059d90c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Sat, 25 Sep 2021 14:15:32 +0200 +Subject: [PATCH 11/12] screenshot: Unrestrict PickColor + +Commit dd2cd6286cd3 restricted callers of the screenshot methods to +portal implementations, gnome-settings-daemon and gnome-screenshot. + +That restriction does make sense for the actual screenshot methods, +but `PickColor` is actually used by GTK in its color picker (and +therefore may be called from arbitrary applications). + +Fix this by unrestricting access to `PickColor` again. Considering that +the method is always interactive, it's not very privacy/security-sensitive +anyway. + +https://gitlab.gnome.org/GNOME/gtk/-/issues/4283 + +Part-of: +--- + js/ui/screenshot.js | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js +index bf537b7d6..ae1156f47 100644 +--- a/js/ui/screenshot.js ++++ b/js/ui/screenshot.js +@@ -37,7 +37,7 @@ var ScreenshotService = class { + Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null); + } + +- _createScreenshot(invocation, needsDisk = true) { ++ _createScreenshot(invocation, needsDisk = true, restrictCallers = true) { + let lockedDown = false; + if (needsDisk) + lockedDown = this._lockdownSettings.get_boolean('disable-save-to-disk'); +@@ -53,7 +53,7 @@ var ScreenshotService = class { + Gio.IOErrorEnum, Gio.IOErrorEnum.PERMISSION_DENIED, + 'Saving to disk is disabled'); + return null; +- } else { ++ } else if (restrictCallers) { + try { + this._senderChecker.checkInvocation(invocation); + } catch (e) { +@@ -311,7 +311,7 @@ var ScreenshotService = class { + } + + async PickColorAsync(params, invocation) { +- const screenshot = this._createScreenshot(invocation, false); ++ const screenshot = this._createScreenshot(invocation, false, false); + if (!screenshot) + return; + +-- +2.35.1 + + +From 9e8073afbf30aaea87aefd8201fc5e04f94edaf8 Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +Date: Tue, 23 Nov 2021 02:48:04 +0100 +Subject: [PATCH 12/12] util: Wait for initial name owners in DBusSenderCheck + before checking + +Otherwise an allowed caller might get rejected if the call is right +after a gnome-shell restart and the watchers have not finished running +their callbacks yet. + +Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4813 +Part-of: +(cherry picked from commit 85609a232d4088b058f23f4922b9a993dea95199) +--- + js/misc/introspect.js | 8 ++++---- + js/misc/util.js | 33 ++++++++++++++++++++++++++++----- + js/ui/screenshot.js | 18 +++++++++--------- + js/ui/shellDBus.js | 43 +++++++++++++++++++++++-------------------- + 4 files changed, 64 insertions(+), 38 deletions(-) + +diff --git a/js/misc/introspect.js b/js/misc/introspect.js +index e9d9260c0..f3c938af9 100644 +--- a/js/misc/introspect.js ++++ b/js/misc/introspect.js +@@ -114,9 +114,9 @@ var IntrospectService = class { + type == Meta.WindowType.UTILITY; + } + +- GetRunningApplicationsAsync(params, invocation) { ++ async GetRunningApplicationsAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -125,13 +125,13 @@ var IntrospectService = class { + invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications])); + } + +- GetWindowsAsync(params, invocation) { ++ async GetWindowsAsync(params, invocation) { + let focusWindow = global.display.get_focus_window(); + let apps = this._appSystem.get_running(); + let windowsList = {}; + + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +diff --git a/js/misc/util.js b/js/misc/util.js +index e6c183fbf..6a0f6f641 100644 +--- a/js/misc/util.js ++++ b/js/misc/util.js +@@ -486,20 +486,42 @@ var DBusSenderChecker = class { + constructor(allowList) { + this._allowlistMap = new Map(); + ++ this._uninitializedNames = new Set(allowList); ++ this._initializedPromise = new Promise(resolve => { ++ this._resolveInitialized = resolve; ++ }); ++ + this._watchList = allowList.map(name => { + return Gio.DBus.watch_name(Gio.BusType.SESSION, + name, + Gio.BusNameWatcherFlags.NONE, +- (conn_, name_, owner) => this._allowlistMap.set(name, owner), +- () => this._allowlistMap.delete(name)); ++ (conn_, name_, owner) => { ++ this._allowlistMap.set(name, owner); ++ this._checkAndResolveInitialized(name); ++ }, ++ () => { ++ this._allowlistMap.delete(name); ++ this._checkAndResolveInitialized(name); ++ }); + }); + } + + /** ++ * @param {string} name - bus name for which the watcher got initialized ++ */ ++ _checkAndResolveInitialized(name) { ++ if (this._uninitializedNames.delete(name) && ++ this._uninitializedNames.size === 0) ++ this._resolveInitialized(); ++ } ++ ++ /** ++ * @async + * @param {string} sender - the bus name that invoked the checked method + * @returns {bool} + */ +- _isSenderAllowed(sender) { ++ async _isSenderAllowed(sender) { ++ await this._initializedPromise; + return [...this._allowlistMap.values()].includes(sender); + } + +@@ -507,15 +529,16 @@ var DBusSenderChecker = class { + * Check whether the bus name that invoked @invocation maps + * to an entry in the allow list. + * ++ * @async + * @throws + * @param {Gio.DBusMethodInvocation} invocation - the invocation + * @returns {void} + */ +- checkInvocation(invocation) { ++ async checkInvocation(invocation) { + if (global.context.unsafe_mode) + return; + +- if (this._isSenderAllowed(invocation.get_sender())) ++ if (await this._isSenderAllowed(invocation.get_sender())) + return; + + throw new GLib.Error(Gio.DBusError, +diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js +index ae1156f47..97fcfacd0 100644 +--- a/js/ui/screenshot.js ++++ b/js/ui/screenshot.js +@@ -37,7 +37,7 @@ var ScreenshotService = class { + Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null); + } + +- _createScreenshot(invocation, needsDisk = true, restrictCallers = true) { ++ async _createScreenshot(invocation, needsDisk = true, restrictCallers = true) { + let lockedDown = false; + if (needsDisk) + lockedDown = this._lockdownSettings.get_boolean('disable-save-to-disk'); +@@ -55,7 +55,7 @@ var ScreenshotService = class { + return null; + } else if (restrictCallers) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return null; +@@ -200,7 +200,7 @@ var ScreenshotService = class { + "Invalid params"); + return; + } +- let screenshot = this._createScreenshot(invocation); ++ let screenshot = await this._createScreenshot(invocation); + if (!screenshot) + return; + +@@ -223,7 +223,7 @@ var ScreenshotService = class { + + async ScreenshotWindowAsync(params, invocation) { + let [includeFrame, includeCursor, flash, filename] = params; +- let screenshot = this._createScreenshot(invocation); ++ let screenshot = await this._createScreenshot(invocation); + if (!screenshot) + return; + +@@ -246,7 +246,7 @@ var ScreenshotService = class { + + async ScreenshotAsync(params, invocation) { + let [includeCursor, flash, filename] = params; +- let screenshot = this._createScreenshot(invocation); ++ let screenshot = await this._createScreenshot(invocation); + if (!screenshot) + return; + +@@ -269,7 +269,7 @@ var ScreenshotService = class { + + async SelectAreaAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -289,9 +289,9 @@ var ScreenshotService = class { + } + } + +- FlashAreaAsync(params, invocation) { ++ async FlashAreaAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -311,7 +311,7 @@ var ScreenshotService = class { + } + + async PickColorAsync(params, invocation) { +- const screenshot = this._createScreenshot(invocation, false, false); ++ const screenshot = await this._createScreenshot(invocation, false, false); + if (!screenshot) + return; + +diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js +index c511314f9..39bba7aa3 100644 +--- a/js/ui/shellDBus.js ++++ b/js/ui/shellDBus.js +@@ -81,13 +81,14 @@ var GnomeShell = class { + /** + * Focus the overview's search entry + * ++ * @async + * @param {...any} params - method parameters + * @param {Gio.DBusMethodInvocation} invocation - the invocation + * @returns {void} + */ +- FocusSearchAsync(params, invocation) { ++ async FocusSearchAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -100,13 +101,14 @@ var GnomeShell = class { + /** + * Show OSD with the specified parameters + * ++ * @async + * @param {...any} params - method parameters + * @param {Gio.DBusMethodInvocation} invocation - the invocation + * @returns {void} + */ +- ShowOSDAsync([params], invocation) { ++ async ShowOSDAsync([params], invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -143,9 +145,9 @@ var GnomeShell = class { + * @param {Gio.DBusMethodInvocation} invocation - the invocation + * @returns {void} + */ +- FocusAppAsync([id], invocation) { ++ async FocusAppAsync([id], invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -167,13 +169,14 @@ var GnomeShell = class { + /** + * Show the overview's app grid + * ++ * @async + * @param {...any} params - method parameters + * @param {Gio.DBusMethodInvocation} invocation - the invocation + * @returns {void} + */ +- ShowApplicationsAsync(params, invocation) { ++ async ShowApplicationsAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -183,9 +186,9 @@ var GnomeShell = class { + invocation.return_value(null); + } + +- GrabAcceleratorAsync(params, invocation) { ++ async GrabAcceleratorAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -197,9 +200,9 @@ var GnomeShell = class { + invocation.return_value(GLib.Variant.new('(u)', [bindingAction])); + } + +- GrabAcceleratorsAsync(params, invocation) { ++ async GrabAcceleratorsAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -215,9 +218,9 @@ var GnomeShell = class { + invocation.return_value(GLib.Variant.new('(au)', [bindingActions])); + } + +- UngrabAcceleratorAsync(params, invocation) { ++ async UngrabAcceleratorAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -230,9 +233,9 @@ var GnomeShell = class { + invocation.return_value(GLib.Variant.new('(b)', [ungrabSucceeded])); + } + +- UngrabAcceleratorsAsync(params, invocation) { ++ async UngrabAcceleratorsAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -317,9 +320,9 @@ var GnomeShell = class { + this._grabbers.delete(name); + } + +- ShowMonitorLabelsAsync(params, invocation) { ++ async ShowMonitorLabelsAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +@@ -331,9 +334,9 @@ var GnomeShell = class { + invocation.return_value(null); + } + +- HideMonitorLabelsAsync(params, invocation) { ++ async HideMonitorLabelsAsync(params, invocation) { + try { +- this._senderChecker.checkInvocation(invocation); ++ await this._senderChecker.checkInvocation(invocation); + } catch (e) { + invocation.return_gerror(e); + return; +-- +2.35.1 + diff --git a/SOURCES/support-choicelist-extension.patch b/SOURCES/support-choicelist-extension.patch new file mode 100644 index 0000000..54e226f --- /dev/null +++ b/SOURCES/support-choicelist-extension.patch @@ -0,0 +1,1210 @@ +From f821b65401284cc31f68f0eb1b2e71ae3a90a122 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 18 Jul 2017 12:58:14 -0400 +Subject: [PATCH 1/2] gdm: Add AuthList control + +Ultimately, we want to add support for GDM's new ChoiceList +PAM extension. That extension allows PAM modules to present +a list of choices to the user. Before we can support that +extension, however, we need to have a list control in the +login-screen/unlock screen. This commit adds that control. + +For the most part, it's a copy-and-paste of the gdm userlist, +but with less features. It lacks API specific to the users, +lacks the built in timed login indicator, etc. It does feature +a label heading. +--- + .../widgets/_login-dialog.scss | 26 +++ + js/gdm/authList.js | 176 ++++++++++++++++++ + js/js-resources.gresource.xml | 1 + + 3 files changed, 203 insertions(+) + create mode 100644 js/gdm/authList.js + +diff --git a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss +index 84539342d..f68d5de99 100644 +--- a/data/theme/gnome-shell-sass/widgets/_login-dialog.scss ++++ b/data/theme/gnome-shell-sass/widgets/_login-dialog.scss +@@ -86,60 +86,86 @@ + .caps-lock-warning-label, + .login-dialog-message-warning { + color: $osd_fg_color; + } + } + + .login-dialog-logo-bin { padding: 24px 0px; } + .login-dialog-banner { color: darken($osd_fg_color,10%); } + .login-dialog-button-box { width: 23em; spacing: 5px; } + .login-dialog-message { text-align: center; } + .login-dialog-message-hint, .login-dialog-message { + color: darken($osd_fg_color, 20%); + min-height: 2.75em; + } + .login-dialog-user-selection-box { padding: 100px 0px; } + .login-dialog-not-listed-label { + padding-left: 2px; + .login-dialog-not-listed-button:focus &, + .login-dialog-not-listed-button:hover & { + color: $osd_fg_color; + } + } + + .login-dialog-not-listed-label { + @include fontsize($base_font_size - 1); + font-weight: bold; + color: darken($osd_fg_color,30%); + padding-top: 1em; + } + ++.login-dialog-auth-list-view { -st-vfade-offset: 1em; } ++.login-dialog-auth-list { ++ spacing: 6px; ++ margin-left: 2em; ++} ++ ++.login-dialog-auth-list-title { ++ margin-left: 2em; ++} ++ ++.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; } ++} ++ ++.login-dialog-auth-list-label { ++ @include fontsize($base_font_size + 2); ++ font-weight: bold; ++ padding-left: 15px; ++ ++ &:ltr { padding-left: 14px; text-align: left; } ++ &:rtl { padding-right: 14px; text-align: right; } ++} ++ + .login-dialog-user-list-view { -st-vfade-offset: 1em; } + .login-dialog-user-list { + spacing: 12px; + width: 23em; + &:expanded .login-dialog-user-list-item:selected { background-color: $selected_bg_color; color: $selected_fg_color; } + &:expanded .login-dialog-user-list-item:logged-in { border-right: 2px solid $selected_bg_color; } + } + + .login-dialog-user-list-item { + border-radius: $base_border_radius + 4px; + padding: 6px; + color: darken($osd_fg_color,30%); + &:ltr .user-widget { padding-right: 1em; } + &:rtl .user-widget { padding-left: 1em; } + .login-dialog-timed-login-indicator { + height: 2px; + margin-top: 6px; + background-color: $osd_fg_color; + } + &:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; } + } + + .user-widget-label { + color: $osd_fg_color; + } + + .user-widget.horizontal .user-widget-label { + @include fontsize($base_font_size + 2); + font-weight: bold; + padding-left: 15px; +diff --git a/js/gdm/authList.js b/js/gdm/authList.js +new file mode 100644 +index 000000000..fb223a972 +--- /dev/null ++++ b/js/gdm/authList.js +@@ -0,0 +1,176 @@ ++// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- ++/* ++ * Copyright 2017 Red Hat, Inc ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++/* exported AuthList */ ++ ++const { Clutter, GObject, Meta, St } = imports.gi; ++ ++const SCROLL_ANIMATION_TIME = 500; ++ ++const AuthListItem = GObject.registerClass({ ++ Signals: { 'activate': {} }, ++}, class AuthListItem extends St.Button { ++ _init(key, text) { ++ this.key = key; ++ const label = new St.Label({ ++ text, ++ style_class: 'login-dialog-auth-list-label', ++ y_align: Clutter.ActorAlign.CENTER, ++ x_expand: false, ++ }); ++ ++ super._init({ ++ style_class: 'login-dialog-auth-list-item', ++ button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, ++ can_focus: true, ++ child: label, ++ reactive: true, ++ }); ++ ++ this.connect('key-focus-in', ++ () => this._setSelected(true)); ++ this.connect('key-focus-out', ++ () => this._setSelected(false)); ++ this.connect('notify::hover', ++ () => this._setSelected(this.hover)); ++ ++ this.connect('clicked', this._onClicked.bind(this)); ++ } ++ ++ _onClicked() { ++ this.emit('activate'); ++ } ++ ++ _setSelected(selected) { ++ if (selected) { ++ this.add_style_pseudo_class('selected'); ++ this.grab_key_focus(); ++ } else { ++ this.remove_style_pseudo_class('selected'); ++ } ++ } ++}); ++ ++var AuthList = GObject.registerClass({ ++ Signals: { ++ 'activate': { param_types: [GObject.TYPE_STRING] }, ++ 'item-added': { param_types: [AuthListItem.$gtype] }, ++ }, ++}, class AuthList extends St.BoxLayout { ++ _init() { ++ super._init({ ++ vertical: true, ++ style_class: 'login-dialog-auth-list-layout', ++ x_align: Clutter.ActorAlign.START, ++ y_align: Clutter.ActorAlign.CENTER, ++ }); ++ ++ this.label = new St.Label({ style_class: 'login-dialog-auth-list-title' }); ++ this.add_child(this.label); ++ ++ this._scrollView = new St.ScrollView({ ++ style_class: 'login-dialog-auth-list-view', ++ }); ++ this._scrollView.set_policy( ++ St.PolicyType.NEVER, St.PolicyType.AUTOMATIC); ++ this.add_child(this._scrollView); ++ ++ this._box = new St.BoxLayout({ ++ vertical: true, ++ style_class: 'login-dialog-auth-list', ++ pseudo_class: 'expanded', ++ }); ++ ++ this._scrollView.add_actor(this._box); ++ this._items = new Map(); ++ ++ this.connect('key-focus-in', this._moveFocusToItems.bind(this)); ++ } ++ ++ _moveFocusToItems() { ++ let hasItems = this.numItems > 0; ++ ++ if (!hasItems) ++ return; ++ ++ if (global.stage.get_key_focus() !== this) ++ return; ++ ++ let focusSet = this.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); ++ if (!focusSet) { ++ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { ++ this._moveFocusToItems(); ++ return false; ++ }); ++ } ++ } ++ ++ _onItemActivated(activatedItem) { ++ this.emit('activate', activatedItem.key); ++ } ++ ++ scrollToItem(item) { ++ let box = item.get_allocation_box(); ++ ++ let adjustment = this._scrollView.get_vscroll_bar().get_adjustment(); ++ ++ let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0); ++ adjustment.ease(value, { ++ duration: SCROLL_ANIMATION_TIME, ++ mode: Clutter.AnimationMode.EASE_OUT_QUAD, ++ }); ++ } ++ ++ addItem(key, text) { ++ this.removeItem(key); ++ ++ let item = new AuthListItem(key, text); ++ this._box.add(item); ++ ++ this._items.set(key, item); ++ ++ item.connect('activate', this._onItemActivated.bind(this)); ++ ++ // Try to keep the focused item front-and-center ++ item.connect('key-focus-in', () => this.scrollToItem(item)); ++ ++ this._moveFocusToItems(); ++ ++ this.emit('item-added', item); ++ } ++ ++ removeItem(key) { ++ if (!this._items.has(key)) ++ return; ++ ++ let item = this._items.get(key); ++ ++ item.destroy(); ++ ++ this._items.delete(key); ++ } ++ ++ get numItems() { ++ return this._items.size; ++ } ++ ++ clear() { ++ this.label.text = ''; ++ this._box.destroy_all_children(); ++ this._items.clear(); ++ } ++}); +diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml +index e65e0e9cf..b2c603a55 100644 +--- a/js/js-resources.gresource.xml ++++ b/js/js-resources.gresource.xml +@@ -1,33 +1,34 @@ + + + ++ gdm/authList.js + gdm/authPrompt.js + gdm/batch.js + gdm/loginDialog.js + gdm/oVirt.js + gdm/credentialManager.js + gdm/vmware.js + gdm/realmd.js + gdm/util.js + + misc/config.js + misc/extensionUtils.js + misc/fileUtils.js + misc/gnomeSession.js + misc/history.js + misc/ibusManager.js + misc/inputMethod.js + misc/introspect.js + misc/jsParse.js + misc/keyboardManager.js + misc/loginManager.js + misc/modemManager.js + misc/objectManager.js + misc/params.js + misc/parentalControlsManager.js + misc/permissionStore.js + misc/smartcardManager.js + misc/systemActions.js + misc/util.js + misc/weather.js + +-- +2.34.1 + +From 5a2fda2fe2526f81c4dbbee6512182f19fc76a74 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 17 Jul 2017 16:48:03 -0400 +Subject: [PATCH 2/2] gdmUtil: Enable support for GDM's ChoiceList PAM + extension + +This commit hooks up support for GDM's ChoiceList PAM extension. +--- + js/gdm/authPrompt.js | 71 +++++++++++++++++++++++++++++++++++++++++-- + js/gdm/loginDialog.js | 5 +++ + js/gdm/util.js | 28 +++++++++++++++++ + js/ui/unlockDialog.js | 7 +++++ + 4 files changed, 109 insertions(+), 2 deletions(-) + +diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js +index 84c608b2f..4da91e096 100644 +--- a/js/gdm/authPrompt.js ++++ b/js/gdm/authPrompt.js +@@ -1,36 +1,37 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + /* exported AuthPrompt */ + + const { Clutter, GLib, GObject, Meta, Pango, Shell, St } = imports.gi; + + const Animation = imports.ui.animation; ++const AuthList = imports.gdm.authList; + const Batch = imports.gdm.batch; + const GdmUtil = imports.gdm.util; + const OVirt = imports.gdm.oVirt; + const Vmware = imports.gdm.vmware; + const Params = imports.misc.params; + const ShellEntry = imports.ui.shellEntry; + const UserWidget = imports.ui.userWidget; + const Util = imports.misc.util; + + var DEFAULT_BUTTON_WELL_ICON_SIZE = 16; + var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000; + var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300; + + var MESSAGE_FADE_OUT_ANIMATION_TIME = 500; + + var AuthPromptMode = { + UNLOCK_ONLY: 0, + UNLOCK_OR_LOG_IN: 1, + }; + + var AuthPromptStatus = { + NOT_VERIFYING: 0, + VERIFYING: 1, + VERIFICATION_FAILED: 2, + VERIFICATION_SUCCEEDED: 3, + VERIFICATION_CANCELLED: 4, + VERIFICATION_IN_PROGRESS: 5, + }; + + var BeginRequestType = { +@@ -48,144 +49,164 @@ var AuthPrompt = GObject.registerClass({ + 'reset': { param_types: [GObject.TYPE_UINT] }, + }, + }, class AuthPrompt extends St.BoxLayout { + _init(gdmClient, mode) { + super._init({ + style_class: 'login-dialog-prompt-layout', + vertical: true, + x_expand: true, + x_align: Clutter.ActorAlign.CENTER, + }); + + this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; + + this._gdmClient = gdmClient; + this._mode = mode; + this._defaultButtonWellActor = null; + this._cancelledRetries = 0; + + this._idleMonitor = Meta.IdleMonitor.get_core(); + + let reauthenticationOnly; + if (this._mode == AuthPromptMode.UNLOCK_ONLY) + reauthenticationOnly = true; + else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) + reauthenticationOnly = false; + + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly }); + + 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('verification-failed', this._onVerificationFailed.bind(this)); + this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this)); + this._userVerifier.connect('reset', this._onReset.bind(this)); + this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this)); + this._userVerifier.connect('credential-manager-authenticated', this._onCredentialManagerAuthenticated.bind(this)); + this.smartcardDetected = this._userVerifier.smartcardDetected; + + this.connect('destroy', this._onDestroy.bind(this)); + + this._userWell = new St.Bin({ + x_expand: true, + y_expand: true, + }); + this.add_child(this._userWell); + + this._hasCancelButton = this._mode === AuthPromptMode.UNLOCK_OR_LOG_IN; + +- this._initEntryRow(); ++ this._initInputRow(); + + let capsLockPlaceholder = new St.Label(); + this.add_child(capsLockPlaceholder); + + this._capsLockWarningLabel = new ShellEntry.CapsLockWarning({ + x_expand: true, + x_align: Clutter.ActorAlign.CENTER, + }); + this.add_child(this._capsLockWarningLabel); + + this._capsLockWarningLabel.bind_property('visible', + capsLockPlaceholder, 'visible', + GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN); + + this._message = new St.Label({ + opacity: 0, + styleClass: 'login-dialog-message', + y_expand: true, + x_expand: true, + y_align: Clutter.ActorAlign.START, + x_align: Clutter.ActorAlign.CENTER, + }); + this._message.clutter_text.line_wrap = true; + this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; + this.add_child(this._message); + } + + _onDestroy() { + if (this._preemptiveAnswerWatchId) { + this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); + this._preemptiveAnswerWatchId = 0; + } + + this._userVerifier.destroy(); + this._userVerifier = null; + } + + vfunc_key_press_event(keyPressEvent) { + if (keyPressEvent.keyval == Clutter.KEY_Escape) + this.cancel(); + return super.vfunc_key_press_event(keyPressEvent); + } + +- _initEntryRow() { ++ _initInputRow() { + this._mainBox = new St.BoxLayout({ + style_class: 'login-dialog-button-box', + vertical: false, + }); + this.add_child(this._mainBox); + + this.cancelButton = new St.Button({ + style_class: 'modal-dialog-button button cancel-button', + accessible_name: _('Cancel'), + button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, + reactive: this._hasCancelButton, + can_focus: this._hasCancelButton, + x_align: Clutter.ActorAlign.START, + y_align: Clutter.ActorAlign.CENTER, + child: new St.Icon({ icon_name: 'go-previous-symbolic' }), + }); + if (this._hasCancelButton) + this.cancelButton.connect('clicked', () => this.cancel()); + else + this.cancelButton.opacity = 0; + this._mainBox.add_child(this.cancelButton); + ++ this._authList = new AuthList.AuthList(); ++ this._authList.set({ ++ visible: false, ++ }); ++ this._authList.connect('activate', (list, key) => { ++ this._authList.reactive = false; ++ this._authList.ease({ ++ opacity: 0, ++ duration: MESSAGE_FADE_OUT_ANIMATION_TIME, ++ mode: Clutter.AnimationMode.EASE_OUT_QUAD, ++ onComplete: () => { ++ this._authList.clear(); ++ this._authList.hide(); ++ this._userVerifier.selectChoice(this._queryingService, key); ++ }, ++ }); ++ }); ++ this._mainBox.add_child(this._authList); ++ + let entryParams = { + style_class: 'login-dialog-prompt-entry', + can_focus: true, + x_expand: true, + }; + + this._entry = null; + + this._textEntry = new St.Entry(entryParams); + ShellEntry.addContextMenu(this._textEntry, { actionMode: Shell.ActionMode.NONE }); + + this._passwordEntry = new St.PasswordEntry(entryParams); + ShellEntry.addContextMenu(this._passwordEntry, { actionMode: Shell.ActionMode.NONE }); + + this._entry = this._passwordEntry; + this._mainBox.add_child(this._entry); + this._entry.grab_key_focus(); + + this._timedLoginIndicator = new St.Bin({ + style_class: 'login-dialog-timed-login-indicator', + scale_x: 0, + }); + + this.add_child(this._timedLoginIndicator); + + [this._textEntry, this._passwordEntry].forEach(entry => { + entry.clutter_text.connect('text-changed', () => { + if (!this._userVerifier.hasPendingMessages && this._queryingService && !this._preemptiveAnswer) + this._fadeOutMessage(); + }); +@@ -276,60 +297,74 @@ var AuthPrompt = GObject.registerClass({ + this._entry = this._textEntry; + } + this._capsLockWarningLabel.visible = secret; + } + + _onAskQuestion(verifier, serviceName, question, secret) { + if (this._queryingService) + this.clear(); + + this._queryingService = serviceName; + if (this._preemptiveAnswer) { + this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); + this._preemptiveAnswer = null; + return; + } + + this._updateEntry(secret); + + // Hack: The question string comes directly from PAM, if it's "Password:" + // we replace it with our own to allow localization, if it's something + // else we remove the last colon and any trailing or leading spaces. + if (question === 'Password:' || question === 'Password: ') + this.setQuestion(_('Password')); + else + this.setQuestion(question.replace(/: *$/, '').trim()); + + this.updateSensitivity(true); + this.emit('prompted'); + } + ++ _onShowChoiceList(userVerifier, serviceName, promptMessage, choiceList) { ++ if (this._queryingService) ++ this.clear(); ++ ++ this._queryingService = serviceName; ++ ++ if (this._preemptiveAnswer) ++ this._preemptiveAnswer = null; ++ ++ this.setChoiceList(promptMessage, choiceList); ++ this.updateSensitivity(true); ++ this.emit('prompted'); ++ } ++ + _onCredentialManagerAuthenticated() { + if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) + this.reset(); + } + + _onSmartcardStatusChanged() { + this.smartcardDetected = this._userVerifier.smartcardDetected; + + // Most of the time we want to reset if the user inserts or removes + // a smartcard. Smartcard insertion "preempts" what the user was + // doing, and smartcard removal aborts the preemption. + // The exceptions are: 1) Don't reset on smartcard insertion if we're already verifying + // with a smartcard + // 2) Don't reset if we've already succeeded at verification and + // the user is getting logged in. + if (this._userVerifier.serviceIsDefault(GdmUtil.SMARTCARD_SERVICE_NAME) && + this.verificationStatus == AuthPromptStatus.VERIFYING && + this.smartcardDetected) + return; + + if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) + this.reset(); + } + + _onShowMessage(_userVerifier, serviceName, message, type) { + this.setMessage(serviceName, message, type); + this.emit('prompted'); + } + + _onVerificationFailed(userVerifier, serviceName, canRetry) { +@@ -411,109 +446,141 @@ var AuthPrompt = GObject.registerClass({ + if (actor) { + if (isSpinner) + this._spinner.play(); + + if (!animate) { + actor.opacity = 255; + } else { + actor.ease({ + opacity: 255, + duration: DEFAULT_BUTTON_WELL_ANIMATION_TIME, + delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY, + mode: Clutter.AnimationMode.LINEAR, + }); + } + } + + this._defaultButtonWellActor = actor; + } + + startSpinning() { + this.setActorInDefaultButtonWell(this._spinner, true); + } + + stopSpinning() { + this.setActorInDefaultButtonWell(null, false); + } + + clear() { + this._entry.text = ''; + this.stopSpinning(); ++ this._authList.clear(); ++ this._authList.hide(); + } + + setQuestion(question) { + if (this._preemptiveAnswerWatchId) { + this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId); + this._preemptiveAnswerWatchId = 0; + } + + this._entry.hint_text = question; + ++ this._authList.hide(); + this._entry.show(); + this._entry.grab_key_focus(); + } + ++ _fadeInChoiceList() { ++ this._authList.set({ ++ opacity: 0, ++ visible: true, ++ reactive: false, ++ }); ++ this._authList.ease({ ++ opacity: 255, ++ duration: MESSAGE_FADE_OUT_ANIMATION_TIME, ++ transition: Clutter.AnimationMode.EASE_OUT_QUAD, ++ onComplete: () => (this._authList.reactive = true), ++ }); ++ } ++ ++ setChoiceList(promptMessage, choiceList) { ++ this._authList.clear(); ++ this._authList.label.text = promptMessage; ++ for (let key in choiceList) { ++ let text = choiceList[key]; ++ this._authList.addItem(key, text); ++ } ++ ++ this._entry.hide(); ++ if (this._message.text === '') ++ this._message.hide(); ++ this._fadeInChoiceList(); ++ } ++ + getAnswer() { + let text; + + if (this._preemptiveAnswer) { + text = this._preemptiveAnswer; + this._preemptiveAnswer = null; + } else { + text = this._entry.get_text(); + } + + return text; + } + + _fadeOutMessage() { + if (this._message.opacity == 0) + return; + this._message.remove_all_transitions(); + this._message.ease({ + opacity: 0, + duration: MESSAGE_FADE_OUT_ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + }); + } + + setMessage(serviceName, message, type) { + if (type == GdmUtil.MessageType.ERROR) + this._message.add_style_class_name('login-dialog-message-warning'); + else + this._message.remove_style_class_name('login-dialog-message-warning'); + + if (type == GdmUtil.MessageType.HINT) + this._message.add_style_class_name('login-dialog-message-hint'); + else + this._message.remove_style_class_name('login-dialog-message-hint'); + ++ this._message.show(); + if (message) { + this._message.remove_all_transitions(); + this._message.text = message; + this._message.opacity = 255; + } else { + this._message.opacity = 0; + } + + if (type === GdmUtil.MessageType.ERROR && + this._userVerifier.serviceIsFingerprint(serviceName)) { + // TODO: Use Await for wiggle to be over before unfreezing the user verifier queue + const wiggleParameters = { + duration: 65, + wiggleCount: 3, + }; + this._userVerifier.increaseCurrentMessageTimeout( + wiggleParameters.duration * (wiggleParameters.wiggleCount + 2)); + Util.wiggle(this._message, wiggleParameters); + } + } + + updateSensitivity(sensitive) { + if (this._entry.reactive === sensitive) + return; + + this._entry.reactive = sensitive; + + if (sensitive) { + this._entry.grab_key_focus(); + } else { +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index d2a82b43d..41dd99646 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -391,60 +391,65 @@ var SessionMenuButton = GObject.registerClass({ + let item = new PopupMenu.PopupMenuItem(sessionName); + this._menu.addMenuItem(item); + this._items[id] = item; + + item.connect('activate', () => { + this.setActiveSession(id); + this.emit('session-activated', this._activeSessionId); + }); + } + } + }); + + var LoginDialog = GObject.registerClass({ + Signals: { + 'failed': {}, + 'wake-up-screen': {}, + }, + }, class LoginDialog extends St.Widget { + _init(parentActor) { + super._init({ style_class: 'login-dialog', visible: false }); + + this.get_accessible().set_role(Atk.Role.WINDOW); + + this.add_constraint(new Layout.MonitorConstraint({ primary: true })); + this.connect('destroy', this._onDestroy.bind(this)); + parentActor.add_child(this); + + this._userManager = AccountsService.UserManager.get_default(); + this._gdmClient = new Gdm.Client(); + ++ try { ++ this._gdmClient.set_enabled_extensions([Gdm.UserVerifierChoiceList.interface_info().name]); ++ } catch (e) { ++ } ++ + this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA }); + + this._settings.connect('changed::%s'.format(GdmUtil.BANNER_MESSAGE_KEY), + this._updateBanner.bind(this)); + this._settings.connect('changed::%s'.format(GdmUtil.BANNER_MESSAGE_TEXT_KEY), + this._updateBanner.bind(this)); + this._settings.connect('changed::%s'.format(GdmUtil.DISABLE_USER_LIST_KEY), + this._updateDisableUserList.bind(this)); + this._settings.connect('changed::%s'.format(GdmUtil.LOGO_KEY), + this._updateLogo.bind(this)); + + this._textureCache = St.TextureCache.get_default(); + this._updateLogoTextureId = this._textureCache.connect('texture-file-changed', + this._updateLogoTexture.bind(this)); + + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER, + vertical: true, + visible: false }); + this.add_child(this._userSelectionBox); + + this._userList = new UserList(); + this._userSelectionBox.add_child(this._userList); + + this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); + this._authPrompt.connect('prompted', this._onPrompted.bind(this)); + this._authPrompt.connect('reset', this._onReset.bind(this)); + this._authPrompt.hide(); + this.add_child(this._authPrompt); +diff --git a/js/gdm/util.js b/js/gdm/util.js +index e62114cb1..3f327400f 100644 +--- a/js/gdm/util.js ++++ b/js/gdm/util.js +@@ -211,90 +211,98 @@ var ShellUserVerifier = class { + this._cancellable = new Gio.Cancellable(); + this._hold = hold; + this._userName = userName; + this.reauthenticating = false; + + this._checkForFingerprintReader(); + + // If possible, reauthenticate an already running session, + // so any session specific credentials get updated appropriately + if (userName) + this._openReauthenticationChannel(userName); + else + this._getUserVerifier(); + } + + cancel() { + if (this._cancellable) + this._cancellable.cancel(); + + if (this._userVerifier) { + this._userVerifier.call_cancel_sync(null); + this.clear(); + } + } + + _clearUserVerifier() { + if (this._userVerifier) { + this._disconnectSignals(); + this._userVerifier.run_dispose(); + this._userVerifier = null; ++ if (this._userVerifierChoiceList) { ++ this._userVerifierChoiceList.run_dispose(); ++ this._userVerifierChoiceList = null; ++ } + } + } + + clear() { + if (this._cancellable) { + this._cancellable.cancel(); + this._cancellable = null; + } + + this._clearUserVerifier(); + this._clearMessageQueue(); + } + + destroy() { + this.cancel(); + + this._settings.run_dispose(); + this._settings = null; + + this._smartcardManager.disconnect(this._smartcardInsertedId); + this._smartcardManager.disconnect(this._smartcardRemovedId); + this._smartcardManager = null; + + for (let service in this._credentialManagers) { + let credentialManager = this._credentialManagers[service]; + credentialManager.disconnect(credentialManager._authenticatedSignalId); + credentialManager = null; + } + } + ++ selectChoice(serviceName, key) { ++ this._userVerifierChoiceList.call_select_choice(serviceName, key, this._cancellable, null); ++ } ++ + answerQuery(serviceName, answer) { + if (!this.hasPendingMessages) { + this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); + } else { + const cancellable = this._cancellable; + let signalId = this.connect('no-more-messages', () => { + this.disconnect(signalId); + if (!cancellable.is_cancelled()) + this._userVerifier.call_answer_query(serviceName, answer, cancellable, null); + }); + } + } + + _getIntervalForMessage(message) { + if (!message) + return 0; + + // We probably could be smarter here + return message.length * USER_READ_TIME; + } + + finishMessageQueue() { + if (!this.hasPendingMessages) + return; + + this._messageQueue = []; + + this.emit('no-more-messages'); + } + +@@ -429,103 +437,116 @@ var ShellUserVerifier = class { + _reportInitError(where, error, serviceName) { + logError(error, where); + this._hold.release(); + + this._queueMessage(serviceName, _('Authentication error'), MessageType.ERROR); + this._failCounter++; + this._verificationFailed(serviceName, false); + } + + async _openReauthenticationChannel(userName) { + try { + this._clearUserVerifier(); + this._userVerifier = await this._client.open_reauthentication_channel( + userName, this._cancellable); + } catch (e) { + if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) + return; + if (e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) && + !this._reauthOnly) { + // Gdm emits org.freedesktop.DBus.Error.AccessDenied when there + // is no session to reauthenticate. Fall back to performing + // verification from this login session + this._getUserVerifier(); + return; + } + + this._reportInitError('Failed to open reauthentication channel', e); + return; + } + ++ if (this._client.get_user_verifier_choice_list) ++ this._userVerifierChoiceList = this._client.get_user_verifier_choice_list(); ++ else ++ this._userVerifierChoiceList = null; ++ + this.reauthenticating = true; + this._connectSignals(); + this._beginVerification(); + this._hold.release(); + } + + async _getUserVerifier() { + try { + this._clearUserVerifier(); + this._userVerifier = + await this._client.get_user_verifier(this._cancellable); + } catch (e) { + if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) + return; + this._reportInitError('Failed to obtain user verifier', e); + return; + } + ++ if (this._client.get_user_verifier_choice_list) ++ this._userVerifierChoiceList = this._client.get_user_verifier_choice_list(); ++ else ++ this._userVerifierChoiceList = null; ++ + this._connectSignals(); + this._beginVerification(); + this._hold.release(); + } + + _connectSignals() { + this._disconnectSignals(); + this._signalIds = []; + + let id = this._userVerifier.connect('info', this._onInfo.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('problem', this._onProblem.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('info-query', this._onInfoQuery.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('service-unavailable', this._onServiceUnavailable.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('reset', this._onReset.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this)); + this._signalIds.push(id); ++ ++ if (this._userVerifierChoiceList) ++ this._userVerifierChoiceList.connect('choice-query', this._onChoiceListQuery.bind(this)); + } + + _disconnectSignals() { + if (!this._signalIds || !this._userVerifier) + return; + + this._signalIds.forEach(s => this._userVerifier.disconnect(s)); + this._signalIds = []; + } + + _getForegroundService() { + if (this._preemptingService) + return this._preemptingService; + + return this._defaultService; + } + + serviceIsForeground(serviceName) { + return serviceName == this._getForegroundService(); + } + + serviceIsDefault(serviceName) { + return serviceName == this._defaultService; + } + + serviceIsFingerprint(serviceName) { + return this._fingerprintReaderType !== FingerprintReaderType.NONE && + serviceName === FINGERPRINT_SERVICE_NAME; + } + +@@ -554,60 +575,67 @@ var ShellUserVerifier = class { + } else { + await this._userVerifier.call_begin_verification( + serviceName, this._cancellable); + } + } catch (e) { + if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) + return; + if (!this.serviceIsForeground(serviceName)) { + logError(e, 'Failed to start %s for %s'.format(serviceName, this._userName)); + this._hold.release(); + return; + } + this._reportInitError(this._userName + ? 'Failed to start %s verification for user'.format(serviceName) + : 'Failed to start %s verification'.format(serviceName), e, + serviceName); + return; + } + this._hold.release(); + } + + _beginVerification() { + this._startService(this._getForegroundService()); + + if (this._userName && + this._fingerprintReaderType !== FingerprintReaderType.NONE && + !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) + this._startService(FINGERPRINT_SERVICE_NAME); + } + ++ _onChoiceListQuery(client, serviceName, promptMessage, list) { ++ if (!this.serviceIsForeground(serviceName)) ++ return; ++ ++ this.emit('show-choice-list', serviceName, promptMessage, list.deep_unpack()); ++ } ++ + _onInfo(client, serviceName, info) { + if (this.serviceIsForeground(serviceName)) { + this._queueMessage(serviceName, info, MessageType.INFO); + } else if (this.serviceIsFingerprint(serviceName)) { + // We don't show fingerprint messages directly since it's + // not the main auth service. Instead we use the messages + // as a cue to display our own message. + if (this._fingerprintReaderType === FingerprintReaderType.SWIPE) { + // Translators: this message is shown below the password entry field + // to indicate the user can swipe their finger on the fingerprint reader + this._queueMessage(serviceName, _('(or swipe finger across reader)'), + MessageType.HINT); + } else { + // Translators: this message is shown below the password entry field + // to indicate the user can place their finger on the fingerprint reader instead + this._queueMessage(serviceName, _('(or place finger on reader)'), + MessageType.HINT); + } + } + } + + _onProblem(client, serviceName, problem) { + const isFingerprint = this.serviceIsFingerprint(serviceName); + + if (!this.serviceIsForeground(serviceName) && !isFingerprint) + return; + + this._queuePriorityMessage(serviceName, problem, MessageType.ERROR); + + if (isFingerprint) { +diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js +index 5b55cb08a..f4655b25b 100644 +--- a/js/ui/unlockDialog.js ++++ b/js/ui/unlockDialog.js +@@ -466,60 +466,67 @@ class UnlockDialogLayout extends Clutter.LayoutManager { + else + actorBox.x1 = box.x2 - (natWidth * 2); + + actorBox.y1 = box.y2 - (natHeight * 2); + actorBox.x2 = actorBox.x1 + natWidth; + actorBox.y2 = actorBox.y1 + natHeight; + + this._switchUserButton.allocate(actorBox); + } + } + }); + + var UnlockDialog = GObject.registerClass({ + Signals: { + 'failed': {}, + 'wake-up-screen': {}, + }, + }, class UnlockDialog extends St.Widget { + _init(parentActor) { + super._init({ + accessible_role: Atk.Role.WINDOW, + style_class: 'unlock-dialog', + visible: false, + reactive: true, + }); + + parentActor.add_child(this); + + this._gdmClient = new Gdm.Client(); + ++ try { ++ this._gdmClient.set_enabled_extensions([ ++ Gdm.UserVerifierChoiceList.interface_info().name, ++ ]); ++ } catch (e) { ++ } ++ + this._adjustment = new St.Adjustment({ + actor: this, + lower: 0, + upper: 2, + page_size: 1, + page_increment: 1, + }); + this._adjustment.connect('notify::value', () => { + this._setTransitionProgress(this._adjustment.value); + }); + + this._swipeTracker = new SwipeTracker.SwipeTracker(this, + Clutter.Orientation.VERTICAL, + Shell.ActionMode.UNLOCK_SCREEN); + this._swipeTracker.connect('begin', this._swipeBegin.bind(this)); + this._swipeTracker.connect('update', this._swipeUpdate.bind(this)); + this._swipeTracker.connect('end', this._swipeEnd.bind(this)); + + this.connect('scroll-event', (o, event) => { + if (this._swipeTracker.canHandleScrollEvent(event)) + return Clutter.EVENT_PROPAGATE; + + let direction = event.get_scroll_direction(); + if (direction === Clutter.ScrollDirection.UP) + this._showClock(); + else if (direction === Clutter.ScrollDirection.DOWN) + this._showPrompt(); + return Clutter.EVENT_STOP; + }); + +-- +2.34.1 + diff --git a/SPECS/gnome-shell.spec b/SPECS/gnome-shell.spec new file mode 100644 index 0000000..4c92db5 --- /dev/null +++ b/SPECS/gnome-shell.spec @@ -0,0 +1,1682 @@ +%global tarball_version %%(echo %{version} | tr '~' '.') + +Name: gnome-shell +Version: 40.10 +Release: 3%{?dist} +Summary: Window management and application launching for GNOME + +License: GPLv2+ +URL: https://wiki.gnome.org/Projects/GnomeShell +Source0: http://download.gnome.org/sources/gnome-shell/40/%{name}-%{tarball_version}.tar.xz + +Recommends: gnome-shell-extension-background-logo + +# Replace Epiphany with Firefox in the default favourite apps list, etc +# and enable background extension by default +Patch1: gnome-shell-favourite-apps-firefox.patch +Patch2: gnome-shell-favourite-apps-yelp.patch +Patch3: gnome-shell-favourite-apps-terminal.patch +Patch4: gnome-shell-enabled-extensions-background-logos.patch + +# GDM/Lock stuff +Patch10: 0001-screenShield-unblank-when-inserting-smartcard.patch +Patch11: enforce-smartcard-at-unlock.patch +Patch12: disable-unlock-entry-until-question.patch +Patch13: 0001-loginDialog-make-info-messages-themed.patch +Patch14: support-choicelist-extension.patch +Patch15: gdm-networking.patch +Patch16: login-screen-extensions.patch + +# Misc. +Patch30: 0001-panel-add-an-icon-to-the-ActivitiesButton.patch +Patch31: 0001-app-Fall-back-to-window-title-instead-of-WM_CLASS.patch +Patch32: 0001-windowMenu-Bring-back-workspaces-submenu-for-static-.patch +Patch33: 0001-main-Dump-stack-on-segfaults-by-default.patch +Patch34: 0001-extensionDownloader-Refuse-to-override-system-extens.patch +Patch35: fix-some-js-warnings.patch +Patch36: 0001-st-texture-cache-purge-on-resume.patch +Patch37: 0001-Update-generated-stylesheets.patch +Patch38: add-power-profiles-menu.patch +Patch39: 0001-status-network-Use-wwan-settings-panel-for-GSM-LTE-M.patch +Patch40: 0001-welcomeDialog-Adapt-dialog-title.patch +Patch41: 0001-main-Leak-the-GJS-context-and-ShellGlobal.patch +Patch42: fix-markup-in-highlighter.patch +Patch43: restrict-dbus-callers.patch +Patch44: 0001-Revert-dash-Subtract-vertical-margins-from-availHeig.patch +Patch45: 0001-status-volume-Hide-sliders-initially.patch +Patch46: 0001-kbdA11yDialog-Use-MetaKeyboardA11yFlags.patch + +%define eds_version 3.33.1 +%define gnome_desktop_version 3.35.91 +%define glib2_version 2.56.0 +%define gobject_introspection_version 1.49.1 +%define gjs_version 1.57.3 +%define gtk3_version 3.15.0 +%define gtk4_version 4.0.0 +%define mutter_version 40.0~alpha.1.1 +%define polkit_version 0.100 +%define gsettings_desktop_schemas_version 40~alpha +%define ibus_version 1.5.2 +%define gnome_bluetooth_version 1:3.9.0 +%define gstreamer_version 1.4.5 +%define pipewire_version 0.3.0 +%define gnome_settings_daemon_version 3.37.1 +%define libgweather_version 40~alpha + +BuildRequires: bash-completion +BuildRequires: gcc +BuildRequires: meson +BuildRequires: git +BuildRequires: ibus-devel >= %{ibus_version} +BuildRequires: chrpath +BuildRequires: desktop-file-utils +BuildRequires: evolution-data-server-devel >= %{eds_version} +BuildRequires: gcr-devel +BuildRequires: gjs-devel >= %{gjs_version} +BuildRequires: glib2-devel >= %{glib2_version} +BuildRequires: gnome-autoar-devel +BuildRequires: pkgconfig(gnome-desktop-3.0) +BuildRequires: gobject-introspection >= %{gobject_introspection_version} +BuildRequires: mesa-libGL-devel +BuildRequires: mesa-libEGL-devel +BuildRequires: NetworkManager-libnm-devel +BuildRequires: polkit-devel >= %{polkit_version} +BuildRequires: startup-notification-devel +BuildRequires: systemd-devel +# for screencast recorder functionality +BuildRequires: gstreamer1-devel >= %{gstreamer_version} +BuildRequires: pkgconfig(libpipewire-0.3) >= %{pipewire_version} +BuildRequires: gtk3-devel >= %{gtk3_version} +BuildRequires: gtk4-devel >= %{gtk4_version} +BuildRequires: gettext >= 0.19.6 +BuildRequires: libcanberra-devel +BuildRequires: python3 + +# for barriers +BuildRequires: libXfixes-devel >= 5.0 +# used in unused BigThemeImage +BuildRequires: librsvg2-devel +BuildRequires: mutter-devel >= %{mutter_version} +BuildRequires: pulseaudio-libs-devel +%ifnarch s390 s390x ppc ppc64 ppc64p7 +BuildRequires: gnome-bluetooth-libs-devel >= %{gnome_bluetooth_version} +%endif +# Bootstrap requirements +BuildRequires: gtk-doc +%ifnarch s390 s390x +Requires: gnome-bluetooth%{?_isa} >= %{gnome_bluetooth_version} +%endif +Requires: gnome-desktop3%{?_isa} >= %{gnome_desktop_version} +%if 0%{?rhel} != 7 +# Disabled on RHEL 7 to allow logging into KDE session by default +Recommends: gnome-session-xsession +%endif +# wrapper script uses to restart old GNOME session if run --replace +# from the command line +Requires: gobject-introspection%{?_isa} >= %{gobject_introspection_version} +Requires: gjs%{?_isa} >= %{gjs_version} +Requires: gtk3%{?_isa} >= %{gtk3_version} +Requires: gtk4%{?_isa} >= %{gtk4_version} +Requires: highcontrast-icon-theme +Requires: libnma%{?_isa} +# needed for loading SVG's via gdk-pixbuf +Requires: librsvg2%{?_isa} +Requires: mutter%{?_isa} >= %{mutter_version} +Requires: upower%{?_isa} +Requires: polkit%{?_isa} >= %{polkit_version} +Requires: gnome-desktop3%{?_isa} >= %{gnome_desktop_version} +Requires: glib2%{?_isa} >= %{glib2_version} +Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas_version} +Requires: gnome-settings-daemon%{?_isa} >= %{gnome_settings_daemon_version} +Requires: gstreamer1%{?_isa} >= %{gstreamer_version} +# needed for screen recorder +Requires: gstreamer1-plugins-good%{?_isa} +Requires: pipewire-gstreamer%{?_isa} +Requires: xdg-user-dirs-gtk +# needed for schemas +Requires: at-spi2-atk%{?_isa} +# needed for on-screen keyboard +Requires: ibus%{?_isa} >= %{ibus_version} +# needed for "show keyboard layout" +Requires: libgnomekbd +# needed for the user menu +Requires: accountsservice-libs%{?_isa} +Requires: gdm-libs%{?_isa} +# needed for settings items in menus +Requires: control-center +# needed by some utilities +Requires: python3%{_isa} +# needed for the dual-GPU launch menu +Requires: switcheroo-control +# needed for clocks/weather integration +Requires: geoclue2-libs%{?_isa} +Requires: libgweather%{?_isa} >= %{libgweather_version} +# needed for thunderbolt support +Requires: bolt%{?_isa} +# Needed for launching flatpak apps etc +# 1.8.0 is needed for source type support in the screencast portal. +Requires: xdg-desktop-portal-gtk >= 1.8.0 +# needed by the welcome dialog +Recommends: gnome-tour + +Provides: desktop-notification-daemon = %{version}-%{release} +Provides: PolicyKit-authentication-agent = %{version}-%{release} +Provides: bundled(gvc) +Provides: bundled(libcroco) = 0.6.13 + +%if 0%{?rhel} +# In Fedora, fedora-obsolete-packages obsoletes caribou +Obsoletes: caribou < 0.4.21-10 +Obsoletes: caribou-antler < 0.4.21-10 +Obsoletes: caribou-devel < 0.4.21-10 +Obsoletes: caribou-gtk2-module < 0.4.21-10 +Obsoletes: caribou-gtk3-module < 0.4.21-10 +Obsoletes: python-caribou < 0.4.21-10 +Obsoletes: python2-caribou < 0.4.21-10 +Obsoletes: python3-caribou < 0.4.21-10 +%endif + +# https://bugzilla.redhat.com/show_bug.cgi?id=1740897 +Conflicts: gnome-shell-extension-background-logo < 3.34.0 + +%description +GNOME Shell provides core user interface functions for the GNOME 3 desktop, +like switching to windows and launching applications. GNOME Shell takes +advantage of the capabilities of modern graphics hardware and introduces +innovative user interface concepts to provide a visually attractive and +easy to use experience. + +%prep +%autosetup -S git -n %{name}-%{tarball_version} + +%build +%meson -Dextensions_app=false +%meson_build + +%install +%meson_install + +# Create empty directories where other packages can drop extensions +mkdir -p %{buildroot}%{_datadir}/gnome-shell/extensions +mkdir -p %{buildroot}%{_datadir}/gnome-shell/search-providers + +%find_lang %{name} + +%check +desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Shell.desktop +desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.desktop + +%files -f %{name}.lang +%license COPYING +%doc README.md +%{_bindir}/gnome-shell +%{_bindir}/gnome-extensions +%{_bindir}/gnome-shell-extension-prefs +%{_bindir}/gnome-shell-extension-tool +%{_bindir}/gnome-shell-perf-tool +%{_datadir}/glib-2.0/schemas/*.xml +%{_datadir}/glib-2.0/schemas/00_org.gnome.shell.gschema.override +%{_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/ +%{_datadir}/dbus-1/services/org.gnome.ScreenSaver.service +%{_datadir}/dbus-1/services/org.gnome.Shell.CalendarServer.service +%{_datadir}/dbus-1/services/org.gnome.Shell.Extensions.service +%{_datadir}/dbus-1/services/org.gnome.Shell.HotplugSniffer.service +%{_datadir}/dbus-1/services/org.gnome.Shell.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 +%{_datadir}/dbus-1/interfaces/org.gnome.Shell.PadOsd.xml +%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Screencast.xml +%{_datadir}/dbus-1/interfaces/org.gnome.Shell.Screenshot.xml +%{_datadir}/dbus-1/interfaces/org.gnome.ShellSearchProvider.xml +%{_datadir}/dbus-1/interfaces/org.gnome.ShellSearchProvider2.xml +%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Shell.Extensions.svg +%{_datadir}/icons/hicolor/symbolic/apps/org.gnome.Shell.Extensions-symbolic.svg +%{_userunitdir}/org.gnome.Shell-disable-extensions.service +%{_userunitdir}/org.gnome.Shell.target +%{_userunitdir}/org.gnome.Shell@wayland.service +%{_userunitdir}/org.gnome.Shell@x11.service +%{_sysconfdir}/xdg/autostart/gnome-shell-overrides-migration.desktop +# Co own directory instead of pulling in xdg-desktop-portal - we +# are providing a backend to the portal, not depending on it +%dir %{_datadir}/xdg-desktop-portal/portals/ +%{_datadir}/xdg-desktop-portal/portals/gnome-shell.portal +%{_libdir}/gnome-shell/ +%{_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 +%dir %{_datadir}/GConf +%dir %{_datadir}/GConf/gsettings +%{_datadir}/GConf/gsettings/gnome-shell-overrides.convert +%{_mandir}/man1/gnome-extensions.1* +%{_mandir}/man1/gnome-shell.1* + +%changelog +* Mon Jun 20 2022 Florian Müllner - 40.10-3 +- Fix keyboard a11y confirmation dialog + Resolves: #2047644 + +* Wed May 11 2022 Florian Müllner - 40.10-2 +- Hide volume sliders initially + Related: #2052808 + +* Tue Apr 19 2022 Florian Müllner - 40.10-1 +- Update to 40.10 + Related: #2066169 + +* Tue Apr 05 2022 Florian Müllner - 40.9-5 +- Keep new ShimMetaContext type private + Related: #2055366 + +* Fri Apr 01 2022 Florian Müllner - 40.9-4 +- Restrict D-Bus callers + Resolves: #2055366 + +* Wed Mar 30 2022 Florian Müllner - 40.9-3 +- Fix markup handling in highlighter + Resolves: #2049194 +- Fix warning on restacking + Resolves: #2053638 + +* Mon Feb 28 2022 Ray Strode - 40.9-2 +- Depend on and use background extension + Related: #2057150 + +* Tue Feb 22 2022 Florian Müllner - 40.9-1 +- Update to 40.9 + Resolves: #2056411 + +* Tue Feb 08 2022 Ray Strode - 40.8-3 +- Backport latest, working, version of ChoiceList extension +- Regenerate stylesheet patch + Related: #1993954 + +* Thu Jan 27 2022 Florian Müllner - 40.8-2 +- Do not hardcode OS name in welcome dialog + Resolves: #2044040 + +* Mon Jan 17 2022 Florian Müllner - 40.8-1 +- Update to 40.8 + Resolves: #2040061 + +* Mon Dec 13 2021 Florian Müllner - 40.7-1 +- Update to 40.7 + Resolves: #2031655 + +* Thu Nov 04 2021 Florian Müllner - 40.6-1 +- Update to 40.6 +- Work around crashy tear down + Resolves: #2008065 + +* Wed Oct 27 2021 Florian Müllner - 40.4-5 +- Adapt welcome dialog title + Resolves: #2013989 + +* Wed Oct 13 2021 Ray Strode - 40.4-4 +- Ensure extensions are reenabled after unlock + Resolves: #2013801 + +* Mon Sep 27 2021 Ray Strode - 40.4-3 +- Allow extensions at the login screen + Related: #2006985 + +* Thu Aug 19 2021 Florian Müllner - 40.4-2 +- Use wwan setting panel for GSM/LTE modems + Resolves: #1995560 + +* Wed Aug 18 2021 Florian Müllner - 40.4-1 +- Update to 40.4 + Resolves: #1995094 + +* Wed Aug 18 2021 Florian Müllner - 40.3-4 +- Add power profiles menu + Resolves: #1994471 + +* Mon Aug 09 2021 Mohan Boddu - 40.3-3 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Mon Aug 09 2021 Florian Müllner - 40.3-2 +- Avoid a gjs warning + Resolves: #1990821 + +* Mon Jul 12 2021 Florian Müllner - 40.3-1 +- Update to 40.3 + Resolves: #1979143 +- Fix some more JS warnings + Resolves: #1980414 + +* Tue Jun 15 2021 Florian Müllner - 40.2-1 +- Update to 40.2-1 + Resolves: #1971432 + +* Fri Jun 04 2021 Florian Müllner - 40.1-5 +- Don't set CAP_SYS_NICE + Resolves: #1967973 + +* Wed Jun 02 2021 Florian Müllner - 40.1-4 +- Fix regression in AuthList rebase + Resolves: #1966841 + +* Thu May 27 2021 Florian Müllner - 40.1-3 +- Update generated stylesheets + Resolves: #1965327 + +* Wed May 19 2021 Florian Müllner - 40.1-2 +- Re-apply RHEL8 downstream patches that are still valid + Resolves: #1949133 + +* Fri May 14 2021 Florian Müllner - 40.1-1 +- Update to 40.1 + Resolves: #1951132 + +* Fri Apr 30 2021 Kalev Lember - 40.0-4 +- Move gnome-tour dep here from gnome-initial-setup (#1955179) + +* Thu Apr 15 2021 Mohan Boddu - 40.0-3 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Apr 13 2021 Ray Strode - 40.0-2 +- Fix timed login when user list is disabled + Resolves: #1940618 + +* Sat Mar 20 2021 Florian Müllner - 40.0-1 +- Update to 40.0 + +* Mon Mar 15 2021 Florian Müllner - 40.0~rc-1 +- Update to 40.rc + +* Thu Mar 11 2021 Kalev Lember - 40.0~beta-4.20210304git7a57528bd +- Recommend gnome-session-xsession rather than hard-require it + +* Mon Mar 08 2021 Florian Müllner - 40.0~beta-3.20210304git40.7a57528bd +- Fix crash after launching apps via drag-and-drop + +* Thu Mar 04 2021 Florian Müllner - 40.0~beta-2.20210304git40.7a57528bd +- Build snapshot of current upstream + +* Tue Feb 23 2021 Florian Müllner - 40.0~beta-1 +- Update to 40.beta + +* Mon Feb 22 2021 Kalev Lember - 40.0~alpha.1.1-9.20210212git829a096ba +- Add missing requires on gstreamer1-plugins-good and xdg-user-dirs-gtk (#1931342) + +* Sun Feb 14 2021 Florian Müllner - 40.0~alpha.1.1-8.20210212git829a096ba +- Only open app picker on left-click/touch + +* Sun Feb 14 2021 Florian Müllner - 40.0~alpha.1.1-7.20210212git829a096ba +- Don't open app picker when clicking minimap + +* Fri Feb 12 2021 Florian Müllner - 40.0~alpha.1.1-6.20210212git829a096ba +- Update snapshot to current upstream +- Allow opening app picker by clicking overview background + +* Fri Feb 12 2021 Milan Crha - 40.0~alpha.1.1-5.20210202git9ce666ac1 +- Rebuilt for evolution-data-server soname version bump + +* Tue Feb 02 2021 Florian Müllner - 40.0~alpha.1.1-4.20210202git9ce666ac1 +- Build snapshot of current upstream + +* Tue Jan 26 2021 Fedora Release Engineering - 40.0~alpha.1.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jan 19 2021 Kalev Lember - 40.0~alpha.1.1-2 +- Require libgweather >= 40~alpha for new application_id property + +* Mon Jan 18 2021 Florian Müllner - 40.alpha.1.1-1 +- Update to 40.alpha.1.1 + +* Fri Jan 15 2021 Florian Müllner - 40.alpha.1-1 +- Update to 40.alpha.1 + +* Wed Dec 02 2020 Florian Müllner - 40.alpha-1 +- Update to 40.alpha + +* Tue Oct 13 2020 Florian Müllner - 3.38.1-2 +- Fix crash on size change (non-)transitions + +* Mon Oct 05 2020 Florian Müllner - 3.38.1-1 +- Update to 3.38.1 + +* Tue Sep 29 2020 David King - 3.38.0-2 +- Better specify xdg-desktop-portal-gtk dependency (#1882894) + +* Mon Sep 14 2020 Florian Müllner - 3.38.0-1 +- Update to 3.38.0 + +* Thu Sep 10 2020 Kalev Lember - 3.37.92-5 +- Set minimum gnome-settings-daemon version for Screencast proxy changes + +* Wed Sep 09 2020 Kalev Lember - 3.37.92-4 +- Add missing pipewire-gstreamer dependency for screen recorder + +* Sun Sep 06 2020 Florian Müllner - 3.37.92-1 +- Update to 3.37.92 + +* Wed Sep 02 2020 Florian Müllner - 3.37.91-3 +- Add missing pipewire dependency for screen recorder + +* Wed Aug 26 2020 Kalev Lember - 3.37.91-2 +- Add PolicyKit-authentication-agent virtual provides + +* Mon Aug 24 2020 Florian Müllner - 3.37.91-1 +- Update to 3.37.91 + +* Sun Aug 23 2020 Kalev Lember - 3.37.90-2 +- Backport a fix for launching apps under X11 (#1870234) + +* Fri Aug 14 2020 Florian Müllner - 3.37.90-1 +- Update to 3.37.90 + +* Sat Aug 01 2020 Fedora Release Engineering - 3.37.3-4 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 3.37.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 13 2020 Milan Crha - 3.37.3-2 +- Rebuilt for evolution-data-server soname version bump + +* Tue Jul 07 2020 Florian Müllner - 3.37.3-1 +- Update to 3.37.3 + +* Fri Jul 03 2020 Milan Crha - 3.37.2-2 +- Rebuilt for evolution-data-server soname version bump + +* Wed Jun 03 2020 Florian Müllner - 3.37.2-1 +- Update to 3.37.2 + +* Wed May 20 2020 Stephen Gallagher - 3.37.1-3 +- Fix crashes when locking the screen while certain extensions are active +- Resolves: rhbz#1817082 + +* Mon May 04 2020 Adam Williamson - 3.37.1-2 +- Fix panel to show input methods (MR #1235) + +* Thu Apr 30 2020 Florian Müllner - 3.36.1-2 +- Backport fixup for spring animation fix + +* Tue Mar 31 2020 Florian Müllner - 3.36.1-1 +- Update to 3.36.1 +- Remove gnome-extensions-app subpackage (will move to a separate .spec) + +* Wed Mar 25 2020 Ray Strode - 3.36.0-4 +- Clear environment on logout + Fixes log in to Xorg right after log out from wayland + Resolves: #1815487 + +* Wed Mar 11 2020 Adam Williamson - 3.36.0-3 +- Backport fix for input method preedit issue (MR #1084) + +* Tue Mar 10 2020 Adam Williamson - 3.36.0-2 +- Backport fix for ibus failing to start automatically (MR #1080) + +* Sat Mar 07 2020 Florian Müllner - 3.36.0-1 +- Update to 3.36.0 + +* Sun Mar 01 2020 Florian Müllner - 3.35.92-1 +- Update to 3.35.92 + +* Tue Feb 18 2020 Florian Müllner - 3.35.91-1 +- Update to 3.35.91 + +* Fri Feb 07 2020 Kalev Lember - 3.35.90-2 +- Adjust the favorites patch to include the apps we install by default + +* Thu Feb 06 2020 Florian Müllner - 3.35.90-1 +- Update to 3.35.90 + +* Tue Jan 28 2020 Fedora Release Engineering - 3.35.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jan 16 2020 Kalev Lember - 3.35.3-2 +- Rebuilt for libgnome-desktop soname bump + +* Sun Jan 05 2020 Florian Müllner - 3.35.3-2 +- Update to 3.35.3 + +* Wed Dec 11 2019 Florian Müllner - 3.35.2-1 +- Udpate to 3.35.2 + +* Sat Oct 12 2019 Florian Müllner - 3.35.1-1 +- Update to 3.35.1 + +* Sat Oct 12 2019 Adam Williamson - 3.34.1-2 +- Backport MR #754 to fix #1749433 + +* Wed Oct 09 2019 Florian Müllner - 3.34.1-1 +- Update to 3.34.1 + +* Tue Sep 24 2019 Debarshi Ray - 3.34.0-3 +- Stop NOTIFY_SOCKET from leaking into the GNOME environment + +* Fri Sep 20 2019 Florian Müllner - 3.34.0-2 +- Fix disappearing icons in frequent view + +* Mon Sep 09 2019 Florian Müllner - 3.34.0-1 +- Update to 3.34.0 + +* Thu Sep 05 2019 Kalev Lember - 3.33.92-1 +- Update to 3.33.92 + +* Mon Aug 26 2019 Kalev Lember - 3.33.91-1 +- Update to 3.33.91 + +* Fri Aug 23 2019 Adam Williamson - 3.33.90-2 +- Revert commit that causes #1740897 (overview type-to-search bug) + Resolves: #1740897 + +* Sat Aug 10 2019 Florian Müllner - 3.33.90-1 +- Update to 3.33.90 + +* Thu Jul 25 2019 Fedora Release Engineering - 3.33.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Sat Jul 20 2019 Florian Müllner - 3.33.4-1 +- Update to 3.33.4 + +* Mon Jun 24 2019 Florian Mülllner - 3.33.3-1 +- Update to 3.33.3 + +* Wed May 22 2019 Florian Müllner - 3.33.2-1 +- Update to 3.33.2 + +* Wed May 22 2019 Kalev Lember - 3.33.1-2 +- Rebuild for libecal-2.0 + +* Tue May 14 2019 Florian Müllner - 3.33.1-1 +- Update to 3.33.1 + +* Wed Apr 17 2019 Florian Müllner - 3.32.1-1 +- Update to 3.32.1 + +* Wed Apr 17 2019 Adam Williamson - 3.32.0-3 +- Backport MR #463 and MR #494 to fix a couple of bugs + Resolves: #1696270 + Resolves: #1690429 + +* Sat Mar 23 2019 Phil Wyett - 3.32.0-2 +- Update source URL +- Add gcc BuildRequires +- Update versions required for gjs and mutter + +* Tue Mar 12 2019 Florian Müllner - 3.32.0-1 +- Update to 3.32.0 + +* Tue Mar 05 2019 Florian Müllner - 3.31.92-1 +- Update to 3.31.92 + +* Thu Feb 21 2019 Florian Müllner - 3.31.91-1 +- Update to 3.31.91 + +* Mon Feb 11 2019 Adam Williamson - 3.31.90-2 +- Backport MR #402 to fix missing logo on login screen + +* Thu Feb 07 2019 Florian Müllner - 3.31.90-1 +- Update to 3.31.90 + +* Thu Jan 31 2019 Fedora Release Engineering - 3.31.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Jan 10 2019 Florian Müllner - 3.31.4-1 +- Update to 3.31.4 + +* Fri Dec 14 2018 Adam Williamson - 3.31.2-3 +- Backport several bugfix commits from current git master + +* Fri Nov 30 2018 Adam Williamson - 3.31.2-2 +- Backport PR #293 to fix 'empty input method indicator' bug + +* Wed Nov 14 2018 Florian Müllner - 3.31.2-1 +- Update to 3.31.2 + +* Mon Nov 12 2018 Mohan Boddu - 3.30.1-3 +- Rebuilt for evolution-data-server soname bump + +* Tue Oct 23 2018 Jonas Ådahl - 3.30.1-2 +- Backport keyboard layout change fixes (rhbz#1637418) + +* Mon Oct 08 2018 Florian Müllner - 3.30.1-1 +- Update to 3.30.1 + +* Thu Sep 27 2018 Hans de Goede - 3.30.0-9 +- Add downstream patches implementing the "Boot Options" menu from: + https://wiki.gnome.org/Design/OS/BootOptions + +* Sat Sep 22 2018 Adam Williamson - 3.30.0-8 +- Backport fix for IBus type issue (GGO MR #228) + +* Wed Sep 19 2018 Adam Williamson - 3.30.0-7 +- Replace dnd fix from -5 with upstream version (GGO MR #209) +- Fix a window destroy crash which can occur with new gjs (GGO #539) +- Fix a window menu issue on multi-monitor systems (GGO MR #227) +- Fix hover and active states for some buttons (GGO #523) + +* Wed Sep 19 2018 Adam Williamson - 3.30.0-6 +- Fix missing key description in ssh key unlock prompt (GGO #574) + +* Wed Sep 19 2018 Ray Strode - 3.30.0-5 +- Fix lock up when dropping icon on dash + Resolves: #1630134 + +* Tue Sep 18 2018 Adam Williamson - 3.30.0-4 +- Fix connecting to wifi from user menu (RHBZ #1628263) + +* Sat Sep 15 2018 Adam Williamson - 3.30.0-3 +- Backport fix for GGO #140 from upstream master + +* Thu Sep 13 2018 Kalev Lember - 3.30.0-2 +- Require xdg-desktop-portal-gtk + +* Tue Sep 04 2018 Florian Müllner - 3.30.0-1 +- Update to 3.30.0 + +* Wed Aug 29 2018 Florian Müllner - 3.29.92-1 +- Update to 3.29.92 + +* Mon Aug 20 2018 Florian Müllner - 3.29.91-1 +- Update to 3.29.91 + +* Thu Aug 09 2018 Debarshi Ray - 3.29.90-2 +- Remove telepathy-logger and telepathy-glib runtime dependencies + +* Wed Aug 01 2018 Florian Müllner - 3.29.90-1 +- Update to 3.29.90 + +* Wed Jul 18 2018 Florian Müllner - 3.29.4-1 +- Update to 3.29.4 + +* Fri Jul 13 2018 Fedora Release Engineering - 3.29.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu May 24 2018 Florian Müllner - 3.29.2-1 +- Update to 3.29.2 + +* Wed May 09 2018 Florian Müllner - 3.29.1-3 +- Fix automatic connection to wireless networks without stored secrets + +* Sun Apr 29 2018 Adam Williamson - 3.29.1-2 +- Backport fix for password entry modifier key issues (#1569211) + +* Wed Apr 25 2018 Florian Müllner - 3.29.1-1 +- Update to 3.29.1 + +* Tue Apr 24 2018 Ray Strode - 3.28.1-2 +- pull polkit cancel lock up from upstream + Resolves: #1568213 + +* Fri Apr 13 2018 Florian Müllner - 3.28.1-1 +- Update to 3.28.1 + +* Mon Mar 12 2018 Florian Müllner - 3.28.0-1 +- Update to 3.28.0 + +* Mon Mar 05 2018 Florian Müllner - 3.27.92-1 +- Update to 3.27.92 + +* Thu Feb 22 2018 Lubomir Rintel - 3.27.91-2 +- Replace libnm-gtk with libnma + +* Wed Feb 21 2018 Florian Müllner - 3.27.91-1 +- Update to 3.27.91 + +* Wed Feb 07 2018 Kalev Lember - 3.27.1-5 +- Rebuilt for evolution-data-server soname bump + +* Mon Jan 22 2018 Adam Williamson - 3.27.1-4 +- Backport fix for crasher bug BGO #788931 (#1469129) + +* Tue Dec 19 2017 Kalev Lember - 3.27.1-3 +- Explicitly require libnm-gtk (#1509496) + +* Wed Nov 08 2017 Milan Crha - 3.27.1-2 +- Rebuild for newer libical + +* Tue Oct 17 2017 Florian Müllner - 3.27.1-1 +- Update to 3.27.1 + +* Wed Oct 04 2017 Florian Müllner - 3.26.1-1 +- Update to 3.26.1 + +* Thu Sep 21 2017 Florian Müllner - 3.26.0-2 +- Fix crash on fast status icon remapping + +* Tue Sep 12 2017 Florian Müllner - 3.26.0-1 +- Update to 3.26.0 + +* Tue Aug 22 2017 Florian Müllner - 3.25.91-1 +- Update to 3.25.91 + +* Fri Aug 11 2017 Kevin Fenzi - 3.25.90-2 +- Rebuild with older working rpm + +* Thu Aug 10 2017 Florian Müllner - 3.25.90-1 +- Update to 3.25.90 + +* Wed Aug 02 2017 Fedora Release Engineering - 3.25.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.25.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Thu Jul 20 2017 Florian Müllner - 3.25.4-1 +- Update to 3.25.4 + +* Wed Jun 21 2017 Florian Müllner - 3.25.3-1 +- Update to 3.25.3 + +* Thu May 25 2017 Florian Müllner - 3.25.2-1 +- Update to 3.25.2 + +* Thu Apr 27 2017 Florian Müllner - 3.25.1-1 +- Update to 3.25.1 + +* Tue Apr 11 2017 Florian Müllner - 3.24.1-1 +- Update to 3.24.1 + +* Mon Mar 20 2017 Florian Müllner - 3.24.0-1 +- Update to 3.24.0 + +* Thu Mar 16 2017 Igor Gnatenko - 3.23.92-2 +- Fix wrong runtime requirements + +* Tue Mar 14 2017 Florian Müllner - 3.23.92-1 +- Update to 3.23.92 + +* Wed Mar 01 2017 Florian Müllner - 3.23.91-1 +- Update to 3.23.91 + +* Thu Feb 16 2017 Florian Müllner - 3.23.90-1 +- Update to 3.23.90 + +* Tue Feb 14 2017 Richard Hughes - 3.23.3-1 +- Update to 3.23.3 + +* Fri Feb 10 2017 Fedora Release Engineering - 3.23.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Dec 19 2016 Miro Hrončok - 3.23.2-3 +- Rebuild for Python 3.6 + +* Tue Dec 6 2016 Rui Matos - 3.23.2-2 +- Tighten mutter version dependency for plugin API changes + Resolves: #1401886 + +* Wed Nov 23 2016 Florian Müllner - 3.23.2-1 +- Update to 3.23.2 + +* Sun Oct 30 2016 Florian Müllner - 3.23.1-1 +- Update to 3.23.1 + +* Fri Oct 21 2016 Bastien Nocera - 3.22.1-2 +- Add patches to allow launching on discrete GPU when available + +* Tue Oct 11 2016 Florian Müllner - 3.22.1 +- Update to 3.22.1 + +* Mon Sep 19 2016 Florian Müllner - 3.22.0 +- Update to 3.22.0 + +* Tue Sep 13 2016 Florian Müllner - 3.21.92 +- Update to 3.21.92 + +* Fri Sep 09 2016 Kalev Lember - 3.21.91-2 +- Drop libgsystem dependency + +* Tue Aug 30 2016 Florian Müllner - 3.21.91 +- Update to 3.21.91 + +* Sat Aug 20 2016 Florian Müllner - 3.21.90.1-1 +- Update to 3.21.90.1 + (Fixes a corrupt .desktop file that made it from the build directory into + the 3.21.90 tarball) + +* Fri Aug 19 2016 Florian Müllner - 3.21.90-1 +- Update to 3.21.90 + +* Wed Jul 20 2016 Florian Müllner - 3.21.4-1 +- Update to 3.21.4 + +* Mon Jul 18 2016 Milan Crha - 3.21.3-2 +- Rebuild for newer evolution-data-server + +* Tue Jun 21 2016 Florian Müllner - 3.21.3-1 +- Update to 3.21.3 + +* Tue Jun 21 2016 Milan Crha - 3.21.2-2 +- Rebuild for newer evolution-data-server + +* Thu May 26 2016 Florian Müllner - 3.21.2-1 +- Update to 3.21.2 + +* Fri Apr 29 2016 Florian Müllner - 3.21.1-1 +- Update to 3.21.1 + +* Fri Apr 15 2016 David Tardon - 3.20.1-2 +- rebuild for ICU 57.1 + +* Wed Apr 13 2016 Florian Müllner - 3.20.1-1 +- Update to 3.20.1 + +* Tue Mar 22 2016 Florian Müllner - 3.20.0-1 +- Update to 3.20.0 + +* Wed Mar 16 2016 Florian Müllner - 3.19.92-1 +- Update to 3.19.92 + +* Thu Mar 03 2016 Florian Müllner - 3.19.91-1 +- Update to 3.19.91 + +* Fri Feb 19 2016 Florian Müllner - 3.19.90-1 +- Update to 3.19.90 + +* Tue Feb 16 2016 Milan Crha - 3.19.4-3 +- Rebuild for newer evolution-data-server + +* Wed Feb 03 2016 Fedora Release Engineering - 3.19.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 21 2016 Florian Müllner - 3.19.4-1 +- Update to 3.19.4 + +* Mon Jan 18 2016 David Tardon - 3.19.3-2 +- rebuild for libical 2.0.0 + +* Thu Dec 17 2015 Florian Müllner - 3.19.3-1 +- Update to 3.19.3 + +* Tue Dec 01 2015 Kalev Lember - 3.19.2-2 +- Bump gsettings-desktop-schemas dep to 3.19.2 + +* Wed Nov 25 2015 Florian Müllner - 3.19.2-1 +- Update to 3.19.2 + +* Tue Nov 10 2015 Ray Strode 3.19.1-3.20151110 +- Update to git snapshot + +* Sun Nov 01 2015 Kalev Lember - 3.19.1-2 +- Fix gnome-shell crashing in gdm mode (#1276833) + +* Thu Oct 29 2015 Florian Müllner - 3.19.1-1 +- Update to 3.19.1 + +* Thu Oct 15 2015 Florian Müllner - 3.18.1-1 +- Update to 3.18.1 + +* Mon Sep 21 2015 Florian Müllner - 3.18.0-1 +- Update to 3.18.0 + +* Wed Sep 16 2015 Florian Müllner - 3.17.92-1 +- Update to 3.17.92 + +* Thu Sep 03 2015 Florian Müllner - 3.17.91-1 +- Update to 3.17.91 + +* Thu Aug 20 2015 Florian Müllner - 3.17.90-1 +- Update to 3.17.90 + +* Wed Aug 19 2015 Kalev Lember - 3.17.4-2 +- Create empty directories for extensions and search providers +- Move desktop file validation to %%check section +- Use make_install macro + +* Thu Jul 23 2015 Florian Müllner - 3.17.4-1 +- Update to 3.17.4 + +* Wed Jul 22 2015 Milan Crha - 3.17.3-3 +- Rebuild for newer evolution-data-server + +* Sat Jul 04 2015 Kalev Lember - 3.17.3-2 +- Require gobject-introspection 1.45.3 + +* Thu Jul 02 2015 Florian Müllner - 3.17.3-1 +- Update to 3.17.3 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.17.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed May 27 2015 Florian Müllner - 3.17.2-1 +- Update to 3.17.2 + +* Thu Apr 30 2015 Florian Müllner - 3.17.1-1 +- Update to 3.17.1 + +* Tue Apr 28 2015 Milan Crha - 3.16.1-2 +- Rebuild for newer evolution-data-server + +* Tue Apr 14 2015 Florian Müllner - 3.16.1-1 +- Update to 3.16.1 + +* Mon Mar 23 2015 Florian Müllner - 3.16.0-1 +- Update to 3.16.0 + +* Tue Mar 17 2015 Kalev Lember - 3.15.92-2 +- Update minimum dep versions +- Use license macro for the COPYING file + +* Tue Mar 17 2015 Florian Müllner - 3.15.92-1 +- Update to 3.15.92 + +* Tue Mar 17 2015 Ray Strode 3.15.91-2 +- Drop dep on NetworkManager-config-connectivity-fedora + It's already required by fedora-release-workstation + +* Wed Mar 04 2015 Florian Müllner - 3.15.91-1 +- Update to 3.15.91 + +* Fri Feb 20 2015 Florian Müllner - 3.15.90-1 +- Update to 3.15.90 + +* Tue Feb 17 2015 Milan Crha - 3.15.4-2 +- Rebuild against newer evolution-data-server + +* Wed Jan 21 2015 Florian Müllner - 3.15.4-1 +- Update to 3.15.4 + +* Fri Dec 19 2014 Florian Müllner - 3.15.3-1 +- Update to 3.15.3 + +* Thu Nov 27 2014 Florian Müllner - 3.15.2-1 +- Update to 3.15.2 + +* Thu Oct 30 2014 Florian Müllner - 3.15.1-1 +- Update to 3.15.1 + +* Tue Oct 14 2014 Florian Müllner - 3.14.1-1 +- Update to 3.14.1 + +* Tue Sep 23 2014 Kalev Lember - 3.14.0-2 +- Drop unused gnome-menus dependency + +* Mon Sep 22 2014 Florian Müllner - 3.14.0-1 +- Update to 3.14.0 + +* Wed Sep 17 2014 Florian Müllner - 3.13.92-1 +- Update to 3.13.92 + +* Wed Sep 03 2014 Florian Müllner - 3.13.91-1 +- Update to 3.13.91 + +* Wed Aug 20 2014 Florian Müllner - 3.13.90-1 +- Update to 3.13.90 + +* Sat Aug 16 2014 Fedora Release Engineering - 3.13.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 31 2014 Milan Crha - 3.13.4-3 +- Rebuild against newer evolution-data-server + +* Mon Jul 28 2014 Adel Gadllah - 3.13.4-2 +- Require NetworkManager-config-connectivity-fedora + +* Wed Jul 23 2014 Florian Müllner - 3.13.4-1 +- Update to 3.13.4 + +* Tue Jul 22 2014 Kalev Lember - 3.13.3-2 +- Rebuilt for gobject-introspection 1.41.4 + +* Fri Jun 27 2014 Florian Müllner - 3.13.3-1 +- New gobject-introspection has been built, drop the last patch again + +* Wed Jun 25 2014 Florian Müllner - 3.13.3-1 +- Revert annotation updates until we get a new gobject-introspection build + +* Wed Jun 25 2014 Florian Müllner - 3.13.3-1 +- Update to 3.13.3 + +* Sat Jun 07 2014 Fedora Release Engineering - 3.13.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue May 27 2014 Florian Müllner - 3.13.2-1 +- Update to 3.13.2 + +* Thu May 01 2014 Kalev Lember - 3.13.1-2 +- Pull in libgsystem + +* Wed Apr 30 2014 Florian Müllner - 3.13.1-1 +- Update to 3.13.1 + +* Tue Apr 15 2014 Florian Müllner - 3.12.1-1 +- Update to 3.12.1 + +* Sat Apr 05 2014 Kalev Lember - 3.12.0-2 +- Update dep versions + +* Tue Mar 25 2014 Florian Müllner - 3.12.0-1 +- Update to 3.12.0 + +* Wed Mar 19 2014 Florian Müllner - 3.11.92-1 +- Update to 3.11.92 + +* Wed Mar 12 2014 Adam Williamson - 3.11.91-2 +- update to final revision of background bug fix from upstream (BGO #722149) + +* Thu Mar 06 2014 Florian Müllner - 3.11.91-1 +- Update to 3.11.91 + +* Mon Mar 03 2014 Adam Williamson - 3.11.90-5 +- backport fixes to fix drag-and-drop workspace creation (BGO #724686) + +* Wed Feb 26 2014 Adam Williamson - 3.11.90-4 +- backport a couple of bugfixes from BGO for things that annoy me + +* Sat Feb 22 2014 Florian Müllner - 3.11.90-3 +- Add dependency on gnome-control-center - several panels are referenced + by a number of menu items + +* Thu Feb 20 2014 Kalev Lember - 3.11.90-2 +- Rebuilt for cogl soname bump + +* Thu Feb 20 2014 Florian Müllner - 3.11.90-1 +- Update to 3.11.90 + +* Mon Feb 10 2014 Peter Hutterer - 3.11.5-3 +- Rebuild for libevdev soname bump + +* Wed Feb 05 2014 Adam Williamson - 3.11.5-2 +- build against new gjs (and hence mozjs24) + +* Wed Feb 05 2014 Richard Hughes - 3.11.5-1 +- Update to 3.11.5 + +* Mon Feb 03 2014 Milan Crha - 3.11.4-2 +- Rebuild against newer evolution-data-server + +* Thu Jan 16 2014 Florian Müllner - 3.11.4-1 +- Update to 3.11.4 + +* Tue Jan 14 2014 Milan Crha - 3.11.3-2 +- Rebuild against newer evolution-data-server + +* Fri Dec 20 2013 Florian Müllner - 3.11.3-1 +- Update to 3.11.3 + +* Thu Nov 21 2013 Milan Crha - 3.11.2-3 +- Rebuild for new libical (RH bug #1023020) + +* Tue Nov 19 2013 Milan Crha - 3.11.2-2 +- Rebuild against newer evolution-data-server + +* Wed Nov 13 2013 Florian Müllner - 3.11.2-1 +- Update to 3.11.2 + +* Wed Oct 30 2013 Florian Müllner - 3.11.1-1 +- Update to 3.11.1 + +* Fri Oct 25 2013 Florian Müllner - 3.10.1-2 +- Rebuild for new e-d-s + +* Tue Oct 15 2013 Florian Müllner - 3.10.1-1 +- Update to 3.10.1 + +* Wed Sep 25 2013 Kalev Lember - 3.10.0.1-1 +- Update to 3.10.0.1 + +* Tue Sep 24 2013 Florian Müllner - 3.10.0-1 +- Update to 3.10.0 + +* Wed Sep 18 2013 Matthias Clasen - 3.9.92-3 +- Build against mutter-wayland + +* Tue Sep 17 2013 Florian Müllner - 3.9.92-1 +- Update to 3.9.92 + +* Tue Sep 03 2013 Florian Müllner - 3.9.91-1 +- Update to 3.9.91 + +* Thu Aug 22 2013 Florian Müllner - 3.9.90-1 +- Update to 3.9.90 + +* Mon Aug 19 2013 Adam Williamson - 3.9.5-3 +- Rebuild for new e-d-s + +* Sat Aug 10 2013 Kalev Lember - 3.9.5-2 +- Drop the bluez revert patch as we now have new enough gnome-bluetooth + +* Tue Jul 30 2013 Florian Müllner - 3.9.5 +- Update to 3.9.5 + +* Mon Jul 29 2013 Adam Williamson - 3.9.4-2 +- rebuild against updated evolution-data-server + +* Wed Jul 10 2013 Florian Müllner - 3.9.4-1 +- Update to 3.9.4 + +* Wed Jul 10 2013 Milan Crha - 3.9.3-3 +- Rebuild against newer evolution-data-server + +* Wed Jul 10 2013 Kalev Lember - 3.9.3-2 +- Add a downstream patch to revert back to bluez 4 + +* Tue Jun 18 2013 Florian Müllner - 3.9.3-1 +- Update to 3.9.3 + +* Tue May 28 2013 Florian Müllner - 3.9.2-1 +- Update to 3.9.2 + +* Sat May 25 2013 Rex Dieter 3.9.1-3 +- rebuild (libical) + +* Wed May 01 2013 Kalev Lember - 3.9.1-2 +- Add missing telepathy-logger runtime dep +- Depend on gnome-session-xsession so that it gets pulled in for + typical GNOME installs + +* Wed May 01 2013 Florian Müllner - 3.9.1-1 +- Update to 3.9.1 + +* Tue Apr 16 2013 Florian Müllner - 3.8.1-1 +- Update to 3.8.1 + +* Thu Mar 28 2013 Adel Gadllah - 3.8.0.1-2 +- Ship the perf tool + +* Wed Mar 27 2013 Ray Strode - 3.8.0.1-1 +- Update to 3.8.0.1 + +* Tue Mar 26 2013 Florian Müllner - 3.8.0-1 +- Update to 3.8.0 + +* Tue Mar 19 2013 Florian Müllner - 3.7.92-1 +- Update to 3.7.92 + +* Tue Mar 05 2013 Florian Müllner - 3.7.91-1 +- Update to 3.7.91 + +* Wed Feb 20 2013 Florian Müllner - 3.7.90-1 +- Update to 3.7.90 + +* Wed Feb 06 2013 Kalev Lember - 3.7.5-2 +- Rebuilt for libgcr soname bump + +* Wed Feb 06 2013 Florian Müllner - 3.7.5-1 +- Update to 3.7.5 + +* Fri Jan 25 2013 Peter Robinson 3.7.4.1-2 +- Rebuild for new cogl + +* Thu Jan 17 2013 Florian Müllner - 3.7.4.1-1 +- Update to 3.7.4.1 + +* Tue Jan 15 2013 Florian Müllner - 3.7.4-1 +- Update to 3.7.4 + +* Wed Jan 09 2013 Richard Hughes - 3.7.3.1-1 +- Update to 3.7.3.1 + +* Tue Dec 18 2012 Florian Müllner 3.7.3-1 +- Update to 3.7.3 + +* Mon Dec 17 2012 Adam Jackson 3.7.2-3 +- Also don't mangle rpath on power + +* Mon Dec 10 2012 Adam Jackson 3.7.2-2 +- Disable bluetooth on power + +* Mon Nov 19 2012 Florian Müllner - 3.7.2-1 +- Update to 3.7.2 + +* Tue Nov 13 2012 Dan Horák - 3.7.1-2 +- don't Require: gnome-bluetooth on s390(x) + +* Fri Nov 09 2012 Kalev Lember - 3.7.1-1 +- Update to 3.7.1 + +* Wed Oct 31 2012 Brian Pepple - 3.6.1-5 +- Rebuild against latest telepathy-logger + +* Thu Oct 25 2012 Milan Crha - 3.6.1-4 +- Rebuild against newer evolution-data-server + +* Sat Oct 20 2012 Dan Horák - 3.6.1-3 +- explicit BR: control-center as it isn't brought in indirectly on s390(x) + +* Thu Oct 18 2012 Florian Müllner - 3.6.1-2 +- Remove avoid-redhat-menus patch + + The standard way of supporting a desktop-specific menu layout is + to set XDG_MENU_PREFIX (which we made gnome-session do now). + +* Mon Oct 15 2012 Florian Müllner - 3.6.1-1 +- Update to 3.6.1 + +* Tue Sep 25 2012 Florian Müllner - 3.6.0-1 +- Update to 3.6.0 + +* Wed Sep 19 2012 Florian Müllner - 3.5.92-1 +- Update to 3.5.92 + +* Tue Sep 11 2012 Florian Müllner - 3.5.91-1 +- Update dependencies + +* Tue Sep 04 2012 Richard Hughes - 3.5.91-1 +- Update to 3.5.91 + +* Tue Aug 28 2012 Matthias Clasen - 3.5.90-3 +- Rebuild against new cogl/clutter + +* Mon Aug 27 2012 Debarshi Ray - 3.5.90-2 +- Rebuild for new libcamel and synchronize gnome-bluetooth Requires with + BuildRequires. + +* Wed Aug 22 2012 Richard Hughes - 3.5.90-1 +- Update to 3.5.90 + +* Tue Aug 14 2012 Debarshi Ray - 3.5.5-2 +- Add Requires: gnome-bluetooth >= 3.5.5 + +* Mon Aug 13 2012 Debarshi Ray - 3.5.5-1 +- Update to 3.5.5 + +* Fri Jul 27 2012 Fedora Release Engineering - 3.5.4-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat Jul 21 2012 Kalev Lember - 3.5.4-4 +- Tighten runtime requires + +* Thu Jul 19 2012 Matthias Clasen - 3.5.4-3 +- Add a gdm-libs dependency + +* Wed Jul 18 2012 Colin Walters - 3.5.4-2 +- Bump release + +* Wed Jul 18 2012 Ray Strode 3.5.4-1 +- Update to 3.5.4 + +* Tue Jun 26 2012 Matthias Clasen - 3.5.3-2 +- Rebuild against new e-d-s + +* Tue Jun 26 2012 Matthias Clasen - 3.5.3-1 +- Update to 3.5.3 + +* Thu Jun 07 2012 Richard Hughes - 3.5.2-2 +- Remove upstreamed patch + +* Thu Jun 07 2012 Richard Hughes - 3.5.2-1 +- Update to 3.5.2 + +* Mon May 28 2012 Peter Robinson - 3.4.1-6 +- Cherry pick F17 changes, bump build for new evo soname + +* Wed May 16 2012 Owen Taylor - 3.4.1-5 +- New version of unmount notification + +* Tue May 15 2012 Owen Taylor - 3.4.1-4 +- Add a patch to display a notification until it's safe to remove a drive (#819492) + +* Fri Apr 20 2012 Owen Taylor - 3.4.1-3 +- Add a patch from upstream to avoid a crash when Evolution is not installed (#814401) + +* Wed Apr 18 2012 Kalev Lember - 3.4.1-2 +- Silence glib-compile-schemas scriplets + +* Wed Apr 18 2012 Kalev Lember - 3.4.1-1 +- Update to 3.4.1 + +* Thu Apr 5 2012 Owen Taylor - 3.4.0-2 +- Change gnome-shell-favourite-apps-firefox.patch to also patch the JS code + to handle the transition from mozilla-firefox.desktop to firefox.desktop. + (#808894, reported by Jonathan Kamens) + +* Tue Mar 27 2012 Richard Hughes - 3.4.0-1 +- Update to 3.4.0 + +* Wed Mar 21 2012 Matthias Clasen - 3.3.92-1 +- Update to 3.3.92 + +* Sat Mar 10 2012 Matthias Clasen - 3.3.90-2 +- Rebuild for new cogl + +* Sat Feb 25 2012 Matthias Clasen - 3.3.90-1 +- Update to 3.3.90 + +* Thu Feb 9 2012 Matthias Clasen - 3.3.5-2 +- Depend on accountsservice-libs (#755112) + +* Tue Feb 7 2012 Matthias Clasen - 3.3.5-1 +- Update to 3.3.5 + +* Fri Jan 20 2012 Matthias Clasen - 3.3.4-1 +- Update to 3.3.4 + +* Thu Jan 19 2012 Matthias Clasen - 3.3.3-2 +- Rebuild for new cogl + +* Thu Jan 5 2012 Matthias Clasen - 3.3.3-1 +- Update to 3.3.3 + +* Sun Nov 27 2011 Peter Robinson - 3.3.2-2 +- Rebuild for new clutter and e-d-s + +* Wed Nov 23 2011 Matthias Clasen - 3.3.2-1 +- Update to 3.3.2 + +* Wed Nov 09 2011 Kalev Lember - 3.2.1-6 +- Adapt to firefox desktop file name change in F17 + +* Thu Nov 03 2011 Adam Jackson 3.2.1-5 +- Build with -Wno-error=disabled-declarations for the moment + +* Wed Nov 02 2011 Brian Pepple - 3.2.1-4 +- Rebuld against tp-logger. + +* Sun Oct 30 2011 Bruno Wolff III - 3.2.1-3 +- Rebuild for new evolution-data-server + +* Wed Oct 26 2011 Fedora Release Engineering - 3.2.1-2 +- Rebuilt for glibc bug#747377 + +* Wed Oct 19 2011 Matthias Clasen - 3.2.1-1 +- Update to 3.2.1 + +* Wed Sep 28 2011 Ray Strode 3.2.0-2 +- rebuild + +* Mon Sep 26 2011 Owen Taylor - 3.2.0-1 +- Update to 3.2.0 + +* Tue Sep 20 2011 Matthias Clasen - 3.1.92-1 +- Update to 3.1.92 + +* Fri Sep 16 2011 Kalev Lember - 3.1.91.1-2 +- Tighten dependencies by specifying the required arch (#739130) + +* Wed Sep 14 2011 Owen Taylor - 3.1.91.1-1 +- Update to 3.1.91.1 (adds browser plugin) + Update Requires + +* Thu Sep 08 2011 Dan Horák - 3.1.91-3 +- workaround a chrpath issue on s390(x) + +* Wed Sep 07 2011 Kalev Lember - 3.1.91-2 +- Replace Epiphany with Firefox in the default favourite apps + +* Wed Sep 7 2011 Matthias Clasen - 3.1.91-1 +- Update to 3.1.91 + +* Thu Sep 1 2011 Matthias Clasen - 3.1.90.1-2 +- Require caribou + +* Wed Aug 31 2011 Matthias Clasen - 3.1.90.1-1 +- Update to 3.1.90.1 + +* Wed Aug 31 2011 Adam Williamson - 3.1.4-3.gite7b9933 +- rebuild against e-d-s + +* Fri Aug 19 2011 Matthias Clasen - 3.1.4-2.gite7b9933 +- git snapshot that builds against gnome-menus 3.1.5 + +* Thu Aug 18 2011 Matthew Barnes - 3.1.5-1 +- Rebuild against newer eds libraries. + +* Wed Jul 27 2011 Matthias Clasen - 3.1.4-1 +- Update to 3.1.4 + +* Wed Jul 27 2011 Matthias Clasen - 3.1.3-4 +- Rebuild + +* Tue Jul 26 2011 Matthias Clasen - 3.1.3-3 +- Add necessary requires + +* Mon Jul 25 2011 Matthias Clasen - 3.1.3-2 +- Rebuild + +* Tue Jul 5 2011 Peter Robinson - 3.1.3-1 +- Upstream 3.1.3 dev release + +* Mon Jun 27 2011 Adam Williamson - 3.0.2-4 +- add fixes from f15 branch (gjs dep and rpath) + +* Wed Jun 22 2011 Owen Taylor - 3.0.2-3 +- Add a patch from upstream to avoid g_file_get_contents() + +* Fri Jun 17 2011 Tomas Bzatek - 3.0.2-2 +- Rebuilt for new gtk3 and gnome-desktop3 + +* Wed May 25 2011 Owen Taylor - 3.0.2-1 +- Update to 3.0.2 + +* Tue May 10 2011 Dan Williams - 3.0.1-4 +- Fix initial connections to WPA Enterprise access points (#699014) +- Fix initial connections to mobile broadband networks + +* Thu Apr 28 2011 Dan Horák - 3.0.1-3 +- no bluetooth on s390(x) + +* Wed Apr 27 2011 Owen Taylor - 3.0.1-2 +- Add a patch from upstream to fix duplicate applications in application display + +* Mon Apr 25 2011 Owen Taylor - 3.0.1-1 +- Update to 3.0.1 + +* Mon Apr 11 2011 Colin Walters - 3.0.0.2-2 +- We want to use the GNOME menus which has the designed categories, + not the legacy redhat-menus. + +* Fri Apr 08 2011 Nils Philippsen - 3.0.0.2-1 +- Update to 3.0.0.2 (fixes missing import that was preventing extensions from + loading.) +- Update source URL + +* Tue Apr 5 2011 Owen Taylor - 3.0.0.1-1 +- Update to 3.0.0.1 (fixes bug where network menu could leave + Clutter event handling stuck.) + +* Mon Apr 4 2011 Owen Taylor - 3.0.0-1 +- Update to 3.0.0 + +* Tue Mar 29 2011 Brian Pepple - 2.91.93-3 +- Bump + +* Tue Mar 29 2011 Brian Pepple - 2.91.93-2 +- Rebuild for new tp-logger + +* Mon Mar 28 2011 Owen Taylor - 2.91.93-1 +- Update to 2.91.93. + +* Fri Mar 25 2011 Ray Strode 2.91.92-3 +- Adjustments for More nm-client api changes. +- Fix VPN indicator + +* Thu Mar 24 2011 Christopher Aillon - 2.91.92-2 +- Make activating vpn connections work from the shell indicator + +* Wed Mar 23 2011 Matthias Clasen - 2.91.92-1 +- Update to 2.91.92 + +* Wed Mar 16 2011 Michel Salim - 2.91.91-2 +- Fix alt-tab behavior on when primary display is not leftmost (# 683932) + +* Tue Mar 8 2011 Owen Taylor - 2.91.91-1 +- Update to 2.91.91 + +* Tue Feb 22 2011 Matthias Clasen - 2.91.90-2 +- Require upower and polkit at runtime + +* Tue Feb 22 2011 Matthias Clasen - 2.91.90-1 +- Update to 2.91.90 + +* Thu Feb 10 2011 Matthias Clasen - 2.91.6-6 +- Rebuild against newer gtk + +* Tue Feb 08 2011 Fedora Release Engineering - 2.91.6-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Feb 3 2011 Bill Nottingham - 2.91.6-4 +- buildrequire gnome-bluetooth to fix bluetooth status icon (#674874) + +* Wed Feb 2 2011 Matthias Clasen - 2.91.6-3 +- Rebuild against newer gtk + +* Tue Feb 1 2011 Owen Taylor - 2.91.6-2 +- Build-requires evolution-data-server-devel + +* Tue Feb 1 2011 Owen Taylor - 2.91.6-1 +- Update to 2.91.6 + +* Thu Jan 13 2011 Mattihas Clasen - 2.91.5-3 +- Drop desktop-effects dependency + +* Wed Jan 12 2011 Colin Walters - 2.91.5-2 +- BR latest g-i, handles flags as arguments better + +* Tue Jan 11 2011 Matthias Clasen - 2.91.5-1 +- Update to 2.91.5 + +* Sat Jan 8 2011 Matthias Clasen - 2.91.4-1 +- Update to 2.91.4 +- Rebuild against new gtk + +* Fri Dec 3 2010 Matthias Clasen - 2.91.3-2 +- Rebuild aginst new gtk + +* Mon Nov 29 2010 Owen Taylor - 2.91.2-1 +- Update to 2.91.3 + +* Thu Nov 18 2010 Owen Taylor - 2.91.2-3 +- Add another memory-management crasher fix from upstream + +* Mon Nov 15 2010 Owen Taylor - 2.91.2-2 +- Add a patch from upstream fixing a memory-management crasher + +* Tue Nov 9 2010 Owen Taylor - 2.91.2-1 +- Update to 2.91.2 + +* Mon Nov 1 2010 Owen Taylor - 2.91.1-1 +- Update to 2.91.1 +- Add libcroco-devel to BuildRequires, apparently it was getting + pulled in indirectly before +- Add libcanberra-devel and pulseaudio-libs-devel BuildRequires + +* Mon Oct 4 2010 Owen Taylor - 2.91.0-1 +- Update to 2.91.0 +- Remove patch to disable VBlank syncing + +* Thu Aug 12 2010 Colin Walters - 2.31.5-7 +- Add patch to disable vblank syncing + +* Tue Jul 13 2010 Colin Walters - 2.31.5-5 +- Run glib-compile-schemas + +* Tue Jul 13 2010 Colin Walters - 2.31.5-4 +- Bless stuff in files section + +* Tue Jul 13 2010 Colin Walters - 2.31.5-3 +- Axe gnome-desktop-devel + +* Tue Jul 13 2010 Adel Gadllah - 2.31.5-2 +- BuildRequire gnome-desktop3-devel, gtk3 + +* Mon Jul 12 2010 Colin Walters - 2.31.5-1 +- New upstream version +- Drop rpath goop, shouldn't be necessary any more + +* Fri Jun 25 2010 Colin Walters - 2.31.2-3 +- Drop gir-repository-devel build dependency + +* Fri May 28 2010 Adam Miller - 2.31.2-2 +- Added new version requirements for dependencies based on upstream releases +- Added new file listings for gnome-shell-clock-preferences binary and .desktop +- Added gnome-shell man page file listing + +* Wed May 26 2010 Adam Miller - 2.31.2-1 +- New upstream release + +* Fri Mar 26 2010 Colin Walters - 2.29.1-3 +- Specify V=1 for build, readd smp_mflags since parallel is fixed upstream + +* Thu Mar 25 2010 Adam Miller - 2.29.1-2 +- Bumped for new version of mutter and clutter +- Added version requirement to gjs-devel because of dependency of build + +* Wed Mar 24 2010 Adam Miller - 2.29.1-1 +- Update to latest version 2.29.1 + +* Sun Feb 21 2010 Bastien Nocera 2.28.1-0.2.20100128git +- Require json-glib +- Rebuild for new clutter with json split out +- Fix deprecation in COGL + +* Thu Jan 28 2010 Adam Miller - 2.28.1-0.1.20100128git +- New git snapshot +- Fixed Version for alphatag use + +* Fri Jan 15 2010 Adam Miller - 2.28.0.20101015git-1 +- Added dependency on a git build of gobject-introspect to solve some breakage +- Also went ahead and made a new git tarball + +* Tue Jan 12 2010 Adam Miller - 2.28.0.20100112git-1 +- New git snapshot + +* Mon Dec 07 2009 Adam Miller - 2.28.0.20091206git-5 +- Added libtool, glib-gettext for the libtoolize dep of git snapshot + +* Mon Dec 07 2009 Adam Miller - 2.28.0.20091206git-4 +- Added gnome-common needed by autogen.sh in git snapshot build + +* Sun Dec 06 2009 Adam Miller - 2.28.0.20091206git-3 +- Added the autotools needed to build the git snapshot to the build requires + +* Sun Dec 06 2009 Adam Miller - 2.28.0.20091206git-2 +- Fixed the setup naming issue with the git snapshot directory naming + +* Sun Dec 06 2009 Adam Miller - 2.28.0.20091206git-1 +- Update to git snapshot on 20091206 + +* Wed Oct 7 2009 Owen Taylor - 2.28.0-2 +- Update to 2.28.0 + +* Tue Sep 15 2009 Owen Taylor - 2.27.3-1 +- Update to 2.27.3 + +* Fri Sep 4 2009 Owen Taylor - 2.27.2-2 +- Test for gobject-introspection version should be >= not > + +* Fri Sep 4 2009 Owen Taylor - 2.27.2-1 +- Update to 2.27.2 +- Add an explicit dep on gobject-introspection 0.6.5 which is required + for the new version + +* Sat Aug 29 2009 Owen Taylor - 2.27.1-4 +- Fix GConf %%preun script to properly be for package removal + +* Fri Aug 28 2009 Owen Taylor - 2.27.1-3 +- Replace libgnomeui with gnome-desktop in BuildRequires + +* Fri Aug 28 2009 Owen Taylor - 2.27.1-2 +- BuildRequire intltool +- Add find_lang + +* Fri Aug 28 2009 Owen Taylor - 2.27.1-1 +- Update to 2.27.1 +- Update Requires, add desktop-effects + +* Wed Aug 12 2009 Owen Taylor - 2.27.0-4 +- Add an explicit dependency on GConf2 for pre/post + +* Tue Aug 11 2009 Owen Taylor - 2.27.0-3 +- Add missing BuildRequires on gir-repository-devel + +* Tue Aug 11 2009 Owen Taylor - 2.27.0-2 +- Temporarily use a non-parallel-build until gnome-shell is fixed + +* Mon Aug 10 2009 Owen Taylor - 2.27.0-1 +- Initial version