File gnome-shell-domain.patch of Package gnome-shell
Index: gnome-shell-45.3/js/gdm/domain.js
===================================================================
--- /dev/null
+++ gnome-shell-45.3/js/gdm/domain.js
@@ -0,0 +1,236 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/*
+ * Copyright 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+import Atk from 'gi://Atk';
+import Gio from 'gi://Gio';
+import GLib from 'gi://GLib';
+import St from 'gi://St';
+
+import * as Main from '../ui/main.js';
+import * as PopupMenu from '../ui/popupMenu.js';
+import * as Signals from '../misc/signals.js';
+
+const DomainLoadStatus = {
+ INIT : 0,
+ SEPARATOR : 1,
+ OWN_DOMAIN : 2,
+ TRUSTED_DOMAINS : 3,
+ DONE : 4,
+ ERR : 5
+};
+
+export class DomainMenuButton extends Signals.EventEmitter {
+ constructor(scope, handler) {
+ super();
+
+ this._separator = null;
+ this.domain_enabled = false;
+ this._domains = new Array();
+ this._load_config();
+ }
+
+ _domainsPush(domain) {
+ let valid_content = domain.replace(/\s+/g, '');
+
+ if (valid_content.length > 0) {
+ if (this._domains.indexOf(valid_content) == -1)
+ this._domains.push (valid_content);
+ }
+ }
+
+ _generate() {
+ let gearIcon = new St.Icon({ icon_name: 'samba-window',
+ icon_size: 24
+ });
+ this._button = new St.Button({ style_class: 'login-dialog-session-list-button', //FIXME
+ reactive: true,
+ track_hover: true,
+ can_focus: true,
+ accessible_name: _("Choose Domain"),
+ accessible_role: Atk.Role.MENU,
+ child: gearIcon });
+
+ gearIcon.show();
+ this.actor = new St.Bin({ child: this._button });
+
+ this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP);
+ Main.uiGroup.add_actor(this._menu.actor);
+ this._menu.actor.hide();
+
+ this._menu.connect('open-state-changed',
+ (menu, isOpen) => {
+ if (isOpen)
+ this._button.add_style_pseudo_class('active');
+ else
+ this._button.remove_style_pseudo_class('active');
+ });
+
+ this._manager = new PopupMenu.PopupMenuManager({ actor: this._button });
+ this._manager.addMenu(this._menu);
+
+ this._button.connect('clicked', () => {
+ this._menu.toggle();
+ });
+
+ this._populate();
+ }
+
+ _load_config() {
+ let keyfile = new GLib.KeyFile();
+ let path = "/etc/gdm/custom.conf";
+ let domain_group = "domains";
+
+ //? Why must use 'try'
+ try {
+ keyfile.load_from_file(path, GLib.KeyFileFlags.NONE);
+ } catch(e) {
+ }
+
+ if (!keyfile.has_group(domain_group)) {
+ return;
+ }
+
+ this.domain_enabled = keyfile.get_boolean(domain_group, 'Enable');
+ if (this.domain_enabled) {
+ let content = keyfile.get_string(domain_group, 'Domains');
+ let domains = content.split(';');
+ for (let i = 0; i < domains.length; i++) {
+ this._domainsPush(domains[i]);
+ }
+ this._generate();
+ }
+ }
+
+ _readStdout(data) {
+ this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (this, function(stream, result) {
+ let [line, len] = this._dataStdout.read_line_finish_utf8(result);
+
+ if (line == null) {
+ // end of file
+ this._stdout.close(null);
+ this.loadDomains(data, null);
+ return;
+ }
+
+ data.push(line);
+ this._readStdout(data);
+ }));
+ }
+
+ loadCommand(argv) {
+ try {
+ let data = new Array();
+ let [success, pid, stdin, stdout, stderr] = GLib.spawn_async_with_pipes(null,
+ argv,
+ null,
+ GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
+ null);
+ this._stdout = new Gio.UnixInputStream({ fd: stdout, close_fd: true });
+ GLib.close(stdin);
+ GLib.close(stderr);
+ this._dataStdout = new Gio.DataInputStream({ base_stream: this._stdout });
+ this._readStdout(data);
+ } catch (e) {
+ this.loadDomains(null, e);
+ }
+ }
+
+ loadDomains(data, err) {
+ /*FIXME: reload every 5 minutes? */
+ /*TODO: load the setting file */
+ switch (this._status) {
+ case DomainLoadStatus.INIT:
+ this._status = DomainLoadStatus.SEPARATOR;
+ this.loadCommand(["wbinfo", "--separator"]);
+ break;
+ case DomainLoadStatus.SEPARATOR:
+ if (data) {
+ this._separator = data[0];
+ this._status = DomainLoadStatus.OWN_DOMAIN;
+ this.loadCommand(["wbinfo", "--own-domain"]);
+ } else {
+ this._status = DomainLoadStatus.ERR;
+ this._menu.removeAll();
+ item = new PopupMenu.PopupMenuItem(_("Cannot receive 'separator'"));
+ item.setSensitive(false);
+ this._menu.addMenuItem(item);
+ }
+ break;
+ case DomainLoadStatus.OWN_DOMAIN:
+ if (data) {
+ for (let i = 0; i < data.length; i++) {
+ this._domainsPush(data[i]);
+ }
+ }
+ this._status = DomainLoadStatus.TRUSTED_DOMAINS;
+ this.loadCommand(["wbinfo", "--trusted-domains"]);
+ break;
+ case DomainLoadStatus.TRUSTED_DOMAINS:
+ if (data) {
+ for (let i = 0; i < data.length; i++) {
+ this._domainsPush(data[i]);
+ }
+ }
+ this._status = DomainLoadStatus.DONE;
+ this._menu.removeAll();
+ for (let i = 0; i < this._domains.length; i++) {
+ item = new PopupMenu.PopupMenuItem(this._domains[i]);
+ this._menu.addMenuItem(item);
+ item.connect('activate', (item) => {
+ //?? Why it does not work
+ //this.setActiveDomain(this._domains[i]);
+ this.setActiveDomain(item.label.text);
+ });
+ }
+ break;
+ }
+ }
+
+ _populate() {
+ //TODO Recent domains?
+ item = new PopupMenu.PopupMenuItem(_("loading the wbinfos..."));
+ item.setSensitive(false);
+ this._menu.addMenuItem(item);
+ this._status = DomainLoadStatus.INIT;
+ this.loadDomains(null, null);
+ }
+
+ setActiveDomain(domain) {
+ this._activeDomain = domain;
+ //this.emit('domain-activated', this._activeDomain);
+ this.emit('domain-activated');
+ }
+
+ getActiveDomain(domain) {
+ return this._activeDomain;
+ }
+
+ getQuestionMessage() {
+ return _("User for ") + this._activeDomain;
+ }
+
+ getHintMessage() {
+ return _("Contact dliang to get help");
+ }
+
+ getDomainUser(user) {
+ return this._activeDomain + this._separator + user;
+ }
+}
Index: gnome-shell-45.3/js/gdm/loginDialog.js
===================================================================
--- gnome-shell-45.3.orig/js/gdm/loginDialog.js
+++ gnome-shell-45.3/js/gdm/loginDialog.js
@@ -29,6 +29,7 @@ import Shell from 'gi://Shell';
import St from 'gi://St';
import * as AuthPrompt from './authPrompt.js';
+import * as Domain from './domain.js';
import * as Batch from './batch.js';
import * as BoxPointer from '../ui/boxpointer.js';
import * as CtrlAltTab from '../ui/ctrlAltTab.js';
@@ -464,6 +465,10 @@ export const LoginDialog = GObject.regis
this._authPrompt.hide();
this.add_child(this._authPrompt);
+ this._userLayout = new St.BoxLayout({ vertical: false,
+ x_expand: true });
+ this._userSelectionBox.add_child(this._userLayout);
+
// translators: this message is shown below the user list on the
// login screen. It can be activated to reveal an entry for
// manually entering the username.
@@ -485,7 +490,18 @@ export const LoginDialog = GObject.regis
this._notListedButton.hide();
- this._userSelectionBox.add_child(this._notListedButton);
+ this._userLayout.add_child(this._notListedButton);
+
+ // we add domain menu button
+ this._domainMenuButton = new Domain.DomainMenuButton();
+ if (this._domainMenuButton.domain_enabled) {
+ this._domainMenuButton.actor.hide();
+
+ this._domainMenuButton.connect('domain-activated',
+ (list) => {
+ this._hideUserListAskForDomainUsernameAndBeginVerification(); });
+ this._userLayout.add_child(this._domainMenuButton.actor);
+ } // domain end
this._bannerView = new St.ScrollView({
style_class: 'login-dialog-banner-view',
@@ -1004,6 +1020,37 @@ export const LoginDialog = GObject.regis
}, this);
}
+ _askForDomainUsernameAndBeginVerification(domain) {
+ this._authPrompt.setPasswordChar('');
+ this._authPrompt.setQuestion(this._domainMenuButton.getQuestionMessage());
+
+ //FIXME: I sugguest to add this info for customer to contact their account manager
+ this._authPrompt.setMessage(this._domainMenuButton.getHintMessage(), GdmUtil.MessageType.HINT);
+
+ let realmManager = new Realmd.Manager();
+ let realmSignalId = realmManager.connect('login-format-changed',
+ this._showRealmLoginHint.bind(this), this);
+ this._showRealmLoginHint(realmManager.loginFormat);
+
+ let nextSignalId = this._authPrompt.connect('next',
+ () => {
+ this._authPrompt.disconnect(nextSignalId);
+ this._authPrompt.updateSensitivity(false);
+ let answer = this._authPrompt.getAnswer();
+ let domain_answer = this._domainMenuButton.getDomainUser(answer);
+ this._user = this._userManager.get_user(domain_answer);
+ this._authPrompt.clear();
+ this._authPrompt.startSpinning();
+ this._authPrompt.begin({ userName: domain_answer});
+ this._updateCancelButton();
+
+ realmManager.disconnect(realmSignalId)
+ realmManager.release();
+ });
+ this._updateCancelButton();
+ this._showPrompt();
+ }
+
_startSession(serviceName) {
this._bindOpacity();
this.ease({
@@ -1178,6 +1225,11 @@ export const LoginDialog = GObject.regis
this._askForUsernameAndBeginVerification();
}
+ _hideUserListAskForDomainUsernameAndBeginVerification() {
+ this._hideUserList();
+ this._askForDomainUsernameAndBeginVerification();
+ }
+
_hideUserListAndBeginVerification() {
this._hideUserList();
this._authPrompt.begin();
@@ -1191,6 +1243,9 @@ export const LoginDialog = GObject.regis
this._sessionMenuButton.hide();
this._setUserListExpanded(true);
this._notListedButton.show();
+ if (this._domainMenuButton.domain_enabled)
+ this._domainMenuButton.actor.show();
+ this._userLayout.show();
this._userList.grab_key_focus();
}
Index: gnome-shell-45.3/js/js-resources.gresource.xml
===================================================================
--- gnome-shell-45.3.orig/js/js-resources.gresource.xml
+++ gnome-shell-45.3/js/js-resources.gresource.xml
@@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/shell">
<file>gdm/authList.js</file>
<file>gdm/authPrompt.js</file>
+ <file>gdm/domain.js</file>
<file>gdm/batch.js</file>
<file>gdm/credentialManager.js</file>
<file>gdm/loginDialog.js</file>
Index: gnome-shell-45.3/po/POTFILES.in
===================================================================
--- gnome-shell-45.3.orig/po/POTFILES.in
+++ gnome-shell-45.3/po/POTFILES.in
@@ -9,6 +9,7 @@ data/org.gnome.Shell.Extensions.desktop.
data/org.gnome.Shell.PortalHelper.desktop.in.in
js/dbusServices/extensions/ui/extension-error-page.ui
js/gdm/authPrompt.js
+js/gdm/domain.js
js/gdm/loginDialog.js
js/gdm/util.js
js/misc/systemActions.js