~ubuntu-branches/ubuntu/utopic/gnome-shell/utopic

« back to all changes in this revision

Viewing changes to .pc/git_fix_dialog_activate_signals.patch/js/ui/unlockDialog.js

  • Committer: Package Import Robot
  • Author(s): Tim Lunn
  • Date: 2013-04-18 12:02:18 UTC
  • Revision ID: package-import@ubuntu.com-20130418120218-3zwv8xjfbct7awz9
Tags: 3.6.3.1-0ubuntu5
* debian/patches: 
    - git_fix_autocompletion_in_dialogs.patch,
      git_fix_dialog_activate_signals.patch
        backport fix for incorrect activation of dialogs (LP: #1077546)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
2
 
 
3
const AccountsService = imports.gi.AccountsService;
 
4
const Clutter = imports.gi.Clutter;
 
5
const Gdm  = imports.gi.Gdm;
 
6
const Gio = imports.gi.Gio;
 
7
const GLib = imports.gi.GLib;
 
8
const Gtk = imports.gi.Gtk;
 
9
const Lang = imports.lang;
 
10
const Signals = imports.signals;
 
11
const Shell = imports.gi.Shell;
 
12
const St = imports.gi.St;
 
13
 
 
14
const Main = imports.ui.main;
 
15
const ModalDialog = imports.ui.modalDialog;
 
16
const ShellEntry = imports.ui.shellEntry;
 
17
const Tweener = imports.ui.tweener;
 
18
const UserMenu = imports.ui.userMenu;
 
19
 
 
20
const Batch = imports.gdm.batch;
 
21
const GdmUtil = imports.gdm.util;
 
22
 
 
23
// The timeout before going back automatically to the lock screen (in seconds)
 
24
const IDLE_TIMEOUT = 2 * 60;
 
25
 
 
26
function versionCompare(required, reference) {
 
27
    required = required.split('.');
 
28
    reference = reference.split('.');
 
29
 
 
30
    for (let i = 0; i < required.length; i++) {
 
31
        if (required[i] != reference[i])
 
32
            return required[i] < reference[i];
 
33
    }
 
34
 
 
35
    return true;
 
36
}
 
37
 
 
38
function isSupported() {
 
39
    try {
 
40
        let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
 
41
        let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
 
42
                                               '/org/gnome/DisplayManager/Manager',
 
43
                                               'org.freedesktop.DBus.Properties',
 
44
                                               'Get', params, null,
 
45
                                               Gio.DBusCallFlags.NONE,
 
46
                                               -1, null);
 
47
 
 
48
        let version = result.deep_unpack()[0].deep_unpack();
 
49
        return versionCompare('3.5.91', version);
 
50
    } catch(e) {
 
51
        return false;
 
52
    }
 
53
}
 
54
 
 
55
// A widget showing the user avatar and name
 
56
const UserWidget = new Lang.Class({
 
57
    Name: 'UserWidget',
 
58
 
 
59
    _init: function(user) {
 
60
        this._user = user;
 
61
 
 
62
        this.actor = new St.BoxLayout({ style_class: 'unlock-dialog-user-name-container',
 
63
                                        vertical: false });
 
64
 
 
65
        this._avatar = new UserMenu.UserAvatarWidget(user);
 
66
        this.actor.add(this._avatar.actor,
 
67
                       { x_fill: true, y_fill: true });
 
68
 
 
69
        this._label = new St.Label({ style_class: 'login-dialog-username' });
 
70
        this.actor.add(this._label,
 
71
                       { expand: true,
 
72
                         x_fill: true,
 
73
                         y_fill: false,
 
74
                         y_align: St.Align.MIDDLE });
 
75
 
 
76
        this._userLoadedId = this._user.connect('notify::is-loaded',
 
77
                                                Lang.bind(this, this._updateUser));
 
78
        this._userChangedId = this._user.connect('changed',
 
79
                                                 Lang.bind(this, this._updateUser));
 
80
        if (this._user.is_loaded)
 
81
            this._updateUser();
 
82
    },
 
83
 
 
84
    destroy: function() {
 
85
        if (this._userLoadedId != 0) {
 
86
            this._user.disconnect(this._userLoadedId);
 
87
            this._userLoadedId = 0;
 
88
        }
 
89
 
 
90
        if (this._userChangedId != 0) {
 
91
            this._user.disconnect(this._userChangedId);
 
92
            this._userChangedId = 0;
 
93
        }
 
94
 
 
95
        this.actor.destroy();
 
96
    },
 
97
 
 
98
    _updateUser: function() {
 
99
        if (this._user.is_loaded)
 
100
            this._label.text = this._user.get_real_name();
 
101
        else
 
102
            this._label.text = '';
 
103
 
 
104
        this._avatar.update();
 
105
    }
 
106
});
 
107
 
 
108
const UnlockDialog = new Lang.Class({
 
109
    Name: 'UnlockDialog',
 
110
    Extends: ModalDialog.ModalDialog,
 
111
 
 
112
    _init: function(parentActor) {
 
113
        this.parent({ shellReactive: true,
 
114
                      styleClass: 'login-dialog',
 
115
                      parentActor: parentActor
 
116
                    });
 
117
 
 
118
        this._userManager = AccountsService.UserManager.get_default();
 
119
        this._userName = GLib.get_user_name();
 
120
        this._user = this._userManager.get_user(this._userName);
 
121
 
 
122
        this._failCounter = 0;
 
123
        this._firstQuestion = true;
 
124
 
 
125
        this._greeterClient = new Gdm.Client();
 
126
        this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
 
127
 
 
128
        this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
 
129
        this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
 
130
        this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
 
131
        this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
 
132
        this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
 
133
 
 
134
        this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
 
135
        this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
 
136
 
 
137
        this._userWidget = new UserWidget(this._user);
 
138
        this.contentLayout.add_actor(this._userWidget.actor);
 
139
 
 
140
        this._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
 
141
                                                vertical: true });
 
142
 
 
143
        this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' });
 
144
        this._promptLayout.add(this._promptLabel,
 
145
                               { x_align: St.Align.START });
 
146
 
 
147
        this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
 
148
                                           can_focus: true });
 
149
        this._promptEntry.clutter_text.set_password_char('\u25cf');
 
150
        ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
 
151
        this.setInitialKeyFocus(this._promptEntry);
 
152
        this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
 
153
 
 
154
        this._promptLayout.add(this._promptEntry,
 
155
                               { expand: true,
 
156
                                 x_fill: true });
 
157
 
 
158
        this.contentLayout.add_actor(this._promptLayout);
 
159
 
 
160
        this._promptMessage = new St.Label({ visible: false });
 
161
        this.contentLayout.add(this._promptMessage, { x_fill: true });
 
162
 
 
163
        this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint' });
 
164
        this._promptLoginHint.hide();
 
165
        this.contentLayout.add_actor(this._promptLoginHint);
 
166
 
 
167
        this.allowCancel = false;
 
168
        let cancelButton = { label: _("Cancel"),
 
169
                             action: Lang.bind(this, this._escape),
 
170
                             key: Clutter.KEY_Escape };
 
171
        this._okButton = { label: _("Unlock"),
 
172
                           action: Lang.bind(this, this._doUnlock),
 
173
                           default: true };
 
174
        this.setButtons([cancelButton, this._okButton]);
 
175
 
 
176
        this._updateSensitivity(true);
 
177
 
 
178
        let otherUserLabel = new St.Label({ text: _("Log in as another user"),
 
179
                                            style_class: 'login-dialog-not-listed-label' });
 
180
        this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
 
181
                                                can_focus: true,
 
182
                                                child: otherUserLabel,
 
183
                                                reactive: true,
 
184
                                                x_align: St.Align.START,
 
185
                                                x_fill: true });
 
186
        this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
 
187
        this.dialogLayout.add(this._otherUserButton,
 
188
                              { x_align: St.Align.START,
 
189
                                x_fill: false });
 
190
 
 
191
        let batch = new Batch.Hold();
 
192
        this._userVerifier.begin(this._userName, batch);
 
193
 
 
194
        GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
 
195
            this.emit('loaded');
 
196
            return false;
 
197
        }));
 
198
 
 
199
        this._idleMonitor = Shell.IdleMonitor.get();
 
200
        // this dialog is only created after user activity (curtain drag or
 
201
        // escape key press), so the timeout will fire after IDLE_TIMEOUT seconds of inactivity
 
202
        this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
 
203
    },
 
204
 
 
205
    _updateSensitivity: function(sensitive) {
 
206
        this._promptEntry.reactive = sensitive;
 
207
        this._promptEntry.clutter_text.editable = sensitive;
 
208
        this._okButton.button.reactive = sensitive;
 
209
        this._okButton.button.can_focus = sensitive;
 
210
    },
 
211
 
 
212
    _showMessage: function(userVerifier, message, styleClass) {
 
213
        if (message) {
 
214
            this._promptMessage.text = message;
 
215
            this._promptMessage.styleClass = styleClass;
 
216
            GdmUtil.fadeInActor(this._promptMessage);
 
217
        } else {
 
218
            GdmUtil.fadeOutActor(this._promptMessage);
 
219
        }
 
220
    },
 
221
 
 
222
    _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
 
223
        if (this._firstQuestion && this._firstQuestionAnswer) {
 
224
            this._userVerifier.answerQuery(serviceName, this._firstQuestionAnswer);
 
225
            this._firstQuestionAnswer = null;
 
226
            this._firstQuestion = false;
 
227
            return;
 
228
        }
 
229
 
 
230
        this._promptLabel.text = question;
 
231
 
 
232
        if (!this._firstQuestion)
 
233
            this._promptEntry.text = '';
 
234
        else
 
235
            this._firstQuestion = false;
 
236
 
 
237
        this._promptEntry.clutter_text.set_password_char(passwordChar);
 
238
        this._promptEntry.menu.isPassword = passwordChar != '';
 
239
 
 
240
        this._currentQuery = serviceName;
 
241
        this._updateSensitivity(true);
 
242
    },
 
243
 
 
244
    _showLoginHint: function(verifier, message) {
 
245
        this._promptLoginHint.set_text(message)
 
246
        GdmUtil.fadeInActor(this._promptLoginHint);
 
247
    },
 
248
 
 
249
    _hideLoginHint: function() {
 
250
        GdmUtil.fadeOutActor(this._promptLoginHint);
 
251
    },
 
252
 
 
253
    _doUnlock: function() {
 
254
        if (this._firstQuestion) {
 
255
            // we haven't received a query yet, so stash the answer
 
256
            // and make ourself non-reactive
 
257
            // the actual reply to GDM will be sent as soon as asked
 
258
            this._firstQuestionAnswer = this._promptEntry.text;
 
259
            this._updateSensitivity(false);
 
260
            return;
 
261
        }
 
262
 
 
263
        if (!this._currentQuery)
 
264
            return;
 
265
 
 
266
        let query = this._currentQuery;
 
267
        this._currentQuery = null;
 
268
 
 
269
        this._updateSensitivity(false);
 
270
 
 
271
        this._userVerifier.answerQuery(query, this._promptEntry.text);
 
272
    },
 
273
 
 
274
    _onVerificationComplete: function() {
 
275
        this._userVerifier.clear();
 
276
        this.emit('unlocked');
 
277
    },
 
278
 
 
279
    _onReset: function() {
 
280
        this.emit('failed');
 
281
    },
 
282
 
 
283
    _onVerificationFailed: function() {
 
284
        this._currentQuery = null;
 
285
        this._firstQuestion = true;
 
286
 
 
287
        this._promptEntry.text = '';
 
288
        this._promptEntry.clutter_text.set_password_char('\u25cf');
 
289
        this._promptEntry.menu.isPassword = true;
 
290
 
 
291
        this._updateSensitivity(false);
 
292
    },
 
293
 
 
294
    _escape: function() {
 
295
        if (this.allowCancel) {
 
296
            this._userVerifier.cancel();
 
297
            this.emit('failed');
 
298
        }
 
299
    },
 
300
 
 
301
    _otherUserClicked: function(button, event) {
 
302
        Gdm.goto_login_session_sync(null);
 
303
 
 
304
        this._userVerifier.cancel();
 
305
        this.emit('failed');
 
306
    },
 
307
 
 
308
    destroy: function() {
 
309
        this._userVerifier.clear();
 
310
 
 
311
        if (this._idleWatchId) {
 
312
            this._idleMonitor.remove_watch(this._idleWatchId);
 
313
            this._idleWatchId = 0;
 
314
        }
 
315
 
 
316
        this.parent();
 
317
    },
 
318
 
 
319
    cancel: function() {
 
320
        this._userVerifier.cancel(null);
 
321
 
 
322
        this.destroy();
 
323
    },
 
324
});