Compare commits
40 Commits
citadel
...
uajain/ada
Author | SHA1 | Date | |
---|---|---|---|
|
05bed41dd1 | ||
|
e56f81b29c | ||
|
01c2313c16 | ||
|
92b57ee992 | ||
|
468fde932a | ||
|
05719ce674 | ||
|
d7befc5875 | ||
|
ca046cd29b | ||
|
4c288bd122 | ||
|
24d36e13ec | ||
|
3387c8787c | ||
|
47d3203622 | ||
|
852cefb6fc | ||
|
cfce9550a4 | ||
|
15692b618a | ||
|
ce1b4b9f43 | ||
|
cb89b7c0c4 | ||
|
cb914b8095 | ||
|
806d3b37cd | ||
|
803a6dcfb0 | ||
|
d2111d1bb3 | ||
|
4a62c072d2 | ||
|
8395f8bad5 | ||
|
37c41af1b7 | ||
|
262b600490 | ||
|
c937103071 | ||
|
a3a00434b1 | ||
|
28f85a3308 | ||
|
2a1ea497c0 | ||
|
e64c12dd27 | ||
|
a6897c5f90 | ||
|
e3f87bac23 | ||
|
57cff9a48b | ||
|
7274ed52dd | ||
|
5e8943340d | ||
|
044ef27c7e | ||
|
ef716a7eb5 | ||
|
0cead8c074 | ||
|
b41ae733a9 | ||
|
768193ab20 |
@ -826,8 +826,7 @@ StScrollBar {
|
|||||||
font-feature-settings: "tnum";
|
font-feature-settings: "tnum";
|
||||||
|
|
||||||
&.unlock-screen,
|
&.unlock-screen,
|
||||||
&.login-screen,
|
&.login-screen {
|
||||||
&.lock-screen {
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,7 +844,7 @@ StScrollBar {
|
|||||||
-panel-corner-border-color: lighten($selected_bg_color,5%);
|
-panel-corner-border-color: lighten($selected_bg_color,5%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.lock-screen, &.login-screen, &.unlock-screen {
|
&.login-screen, &.unlock-screen {
|
||||||
-panel-corner-radius: 0;
|
-panel-corner-radius: 0;
|
||||||
-panel-corner-background-color: transparent;
|
-panel-corner-background-color: transparent;
|
||||||
-panel-corner-border-color: transparent;
|
-panel-corner-border-color: transparent;
|
||||||
@ -879,8 +878,7 @@ StScrollBar {
|
|||||||
|
|
||||||
.system-status-icon { icon-size: 1.09em; padding: 0 5px; }
|
.system-status-icon { icon-size: 1.09em; padding: 0 5px; }
|
||||||
.unlock-screen &,
|
.unlock-screen &,
|
||||||
.login-screen &,
|
.login-screen & {
|
||||||
.lock-screen & {
|
|
||||||
color: lighten($fg_color, 10%);
|
color: lighten($fg_color, 10%);
|
||||||
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
|
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
|
||||||
}
|
}
|
||||||
@ -1886,6 +1884,7 @@ StScrollBar {
|
|||||||
.user-icon {
|
.user-icon {
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
color: $osd_fg_color;
|
color: $osd_fg_color;
|
||||||
|
text-align: center;
|
||||||
border-radius: 99px;
|
border-radius: 99px;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: lighten($osd_fg_color,30%);
|
color: lighten($osd_fg_color,30%);
|
||||||
@ -1966,6 +1965,16 @@ StScrollBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.cancel-button {
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 16px;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-color: transparentize($bg_color,0.7);
|
||||||
|
background-color: transparentize($bg_color,0.7);
|
||||||
|
|
||||||
|
StIcon { icon-size: 16px; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-dialog-logo-bin { padding: 24px 0px; }
|
.login-dialog-logo-bin { padding: 24px 0px; }
|
||||||
@ -2012,15 +2021,10 @@ StScrollBar {
|
|||||||
.login-dialog-username,
|
.login-dialog-username,
|
||||||
.user-widget-label {
|
.user-widget-label {
|
||||||
color: $osd_fg_color;
|
color: $osd_fg_color;
|
||||||
font-size: 120%;
|
font-size: 16pt;
|
||||||
font-weight: bold;
|
text-align: center;
|
||||||
text-align: left;
|
padding-top: 24px;
|
||||||
padding-left: 15px;
|
|
||||||
}
|
}
|
||||||
.user-widget-label {
|
|
||||||
&:ltr { padding-left: 14px; }
|
|
||||||
&:rtl { padding-right: 14px; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-dialog-prompt-layout {
|
.login-dialog-prompt-layout {
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
@ -2047,69 +2051,58 @@ StScrollBar {
|
|||||||
|
|
||||||
//SCREEN SHIELD
|
//SCREEN SHIELD
|
||||||
|
|
||||||
$_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
|
$_unlockdialog_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
|
||||||
|
|
||||||
.screen-shield-arrows {
|
.unlock-dialog-clock {
|
||||||
padding-bottom: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.screen-shield-arrows Gjs_Arrow {
|
|
||||||
color: white;
|
|
||||||
width: 80px;
|
|
||||||
height: 48px;
|
|
||||||
-arrow-thickness: 12px;
|
|
||||||
-arrow-shadow: $_screenshield_shadow;
|
|
||||||
}
|
|
||||||
|
|
||||||
.screen-shield-clock {
|
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: $_screenshield_shadow;
|
font-weight: 300;
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-bottom: 1.5em;
|
padding-bottom: 2.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.screen-shield-clock-time {
|
.unlock-dialog-clock-time {
|
||||||
font-size: 72pt;
|
font-size: 64pt;
|
||||||
text-shadow: $_screenshield_shadow;
|
padding-bottom: 24px;
|
||||||
|
padding-top: 42px;
|
||||||
font-feature-settings: "tnum";
|
font-feature-settings: "tnum";
|
||||||
}
|
}
|
||||||
|
|
||||||
.screen-shield-clock-date {
|
.unlock-dialog-clock-date {
|
||||||
font-size: 28pt;
|
font-size: 16pt;
|
||||||
font-weight: normal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.screen-shield-notifications-container {
|
.unlock-dialog-user-name {
|
||||||
|
padding: 12px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unlock-dialog-notifications-container {
|
||||||
|
margin: 12px 0;
|
||||||
spacing: 6px;
|
spacing: 6px;
|
||||||
width: 30em;
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
max-height: 500px;
|
|
||||||
.summary-notification-stack-scrollview {
|
.summary-notification-stack-scrollview {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification,
|
.notification,
|
||||||
.screen-shield-notification-source {
|
.unlock-dialog-notification-source {
|
||||||
padding: 12px 6px;
|
padding: 12px 6px;
|
||||||
border: 1px solid $osd_outer_borders_color;
|
border: 1px solid $osd_outer_borders_color;
|
||||||
background-color: transparentize($osd_bg_color,0.5);
|
background-color: transparentize($osd_bg_color,0.5);
|
||||||
color: $osd_fg_color;
|
color: $osd_fg_color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.notification { margin-right: 15px; } //compensate for space allocated to the scrollbar
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.screen-shield-notification-label {
|
.unlock-dialog-notification-label {
|
||||||
font-weight: bold;
|
|
||||||
padding: 0px 0px 0px 12px;
|
padding: 0px 0px 0px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.screen-shield-notification-count-text { padding: 0px 0px 0px 12px; }
|
.unlock-dialog-notification-count-text {
|
||||||
|
weight: bold;
|
||||||
#panel.lock-screen { background-color: transparentize($osd_bg_color, 0.5); }
|
padding: 0px 12px 0px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.screen-shield-background { //just the shadow, really
|
.screen-shield-background { //just the shadow, really
|
||||||
background: black;
|
background: black;
|
||||||
@ -2121,7 +2114,7 @@ $_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
|
|||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#screenShieldNotifications {
|
#unlockDialogNotifications {
|
||||||
StButton#vhandle, StButton#hhandle {
|
StButton#vhandle, StButton#hhandle {
|
||||||
background-color: transparentize($bg_color,0.7);
|
background-color: transparentize($bg_color,0.7);
|
||||||
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
|
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
|
||||||
|
@ -98,17 +98,8 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.add_child(this._label);
|
this.add_child(this._label);
|
||||||
this._entry = new St.Entry({
|
|
||||||
style_class: 'login-dialog-prompt-entry',
|
|
||||||
can_focus: true,
|
|
||||||
x_expand: false,
|
|
||||||
y_expand: true,
|
|
||||||
});
|
|
||||||
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
|
|
||||||
|
|
||||||
this.add_child(this._entry);
|
this._initEntryRow();
|
||||||
|
|
||||||
this._entry.grab_key_focus();
|
|
||||||
|
|
||||||
this._message = new St.Label({
|
this._message = new St.Label({
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
@ -120,26 +111,6 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
this._message.clutter_text.line_wrap = true;
|
this._message.clutter_text.line_wrap = true;
|
||||||
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
this.add_child(this._message);
|
this.add_child(this._message);
|
||||||
|
|
||||||
this._buttonBox = new St.BoxLayout({
|
|
||||||
style_class: 'login-dialog-button-box',
|
|
||||||
vertical: false,
|
|
||||||
y_align: Clutter.ActorAlign.END,
|
|
||||||
});
|
|
||||||
this.add_child(this._buttonBox);
|
|
||||||
|
|
||||||
this._defaultButtonWell = new St.Widget({
|
|
||||||
layout_manager: new Clutter.BinLayout(),
|
|
||||||
x_align: Clutter.ActorAlign.END,
|
|
||||||
y_align: Clutter.ActorAlign.CENTER,
|
|
||||||
});
|
|
||||||
|
|
||||||
this._initButtons();
|
|
||||||
|
|
||||||
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
|
|
||||||
this._spinner.opacity = 0;
|
|
||||||
this._spinner.show();
|
|
||||||
this._defaultButtonWell.add_child(this._spinner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
@ -153,46 +124,55 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
return Clutter.EVENT_PROPAGATE;
|
return Clutter.EVENT_PROPAGATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_initButtons() {
|
_initEntryRow() {
|
||||||
|
let mainBox = new St.BoxLayout({
|
||||||
|
style_class: 'login-dialog-button-box',
|
||||||
|
vertical: false,
|
||||||
|
});
|
||||||
|
this.add_child(mainBox);
|
||||||
|
|
||||||
this.cancelButton = new St.Button({
|
this.cancelButton = new St.Button({
|
||||||
style_class: 'modal-dialog-button button',
|
style_class: 'modal-dialog-button button cancel-button',
|
||||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||||
reactive: true,
|
reactive: true,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
label: _("Cancel"),
|
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
x_align: Clutter.ActorAlign.START,
|
x_align: Clutter.ActorAlign.START,
|
||||||
y_align: Clutter.ActorAlign.END,
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
child: new St.Icon({ icon_name: 'go-previous-symbolic' }),
|
||||||
});
|
});
|
||||||
this.cancelButton.connect('clicked', () => this.cancel());
|
this.cancelButton.connect('clicked', () => this.cancel());
|
||||||
this._buttonBox.add_child(this.cancelButton);
|
mainBox.add_child(this.cancelButton);
|
||||||
|
|
||||||
this._buttonBox.add_child(this._defaultButtonWell);
|
this._entry = new St.Entry({
|
||||||
this.nextButton = new St.Button({
|
style_class: 'login-dialog-prompt-entry',
|
||||||
style_class: 'modal-dialog-button button',
|
|
||||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
|
||||||
reactive: true,
|
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
label: _("Next"),
|
x_expand: false,
|
||||||
x_align: Clutter.ActorAlign.END,
|
y_expand: true,
|
||||||
y_align: Clutter.ActorAlign.END,
|
hint_text: "Enter Password…",
|
||||||
});
|
});
|
||||||
this.nextButton.connect('clicked', () => this.emit('next'));
|
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
|
||||||
this.nextButton.add_style_pseudo_class('default');
|
|
||||||
this._buttonBox.add_child(this.nextButton);
|
|
||||||
|
|
||||||
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
mainBox.add_child(this._entry);
|
||||||
|
|
||||||
|
this._entry.grab_key_focus();
|
||||||
|
this._entry.clutter_text.connect('activate', () => this.emit('next'));
|
||||||
this._entry.clutter_text.connect('text-changed', () => {
|
this._entry.clutter_text.connect('text-changed', () => {
|
||||||
if (!this._userVerifier.hasPendingMessages)
|
if (!this._userVerifier.hasPendingMessages)
|
||||||
this._fadeOutMessage();
|
this._fadeOutMessage();
|
||||||
|
});
|
||||||
|
|
||||||
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
this._defaultButtonWell = new St.Widget({
|
||||||
});
|
layout_manager: new Clutter.BinLayout(),
|
||||||
this._entry.clutter_text.connect('activate', () => {
|
x_align: Clutter.ActorAlign.END,
|
||||||
if (this.nextButton.reactive)
|
y_align: Clutter.ActorAlign.CENTER,
|
||||||
this.emit('next');
|
|
||||||
});
|
});
|
||||||
|
mainBox.add_child(this._defaultButtonWell);
|
||||||
|
|
||||||
|
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
|
||||||
|
this._spinner.opacity = 0;
|
||||||
|
this._spinner.show();
|
||||||
|
this._defaultButtonWell.add_child(this._spinner);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onAskQuestion(verifier, serviceName, question, passwordChar) {
|
_onAskQuestion(verifier, serviceName, question, passwordChar) {
|
||||||
@ -208,15 +188,6 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
this.setPasswordChar(passwordChar);
|
this.setPasswordChar(passwordChar);
|
||||||
this.setQuestion(question);
|
this.setQuestion(question);
|
||||||
|
|
||||||
if (passwordChar) {
|
|
||||||
if (this._userVerifier.reauthenticating)
|
|
||||||
this.nextButton.label = _("Unlock");
|
|
||||||
else
|
|
||||||
this.nextButton.label = C_("button", "Sign In");
|
|
||||||
} else {
|
|
||||||
this.nextButton.label = _("Next");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateSensitivity(true);
|
this.updateSensitivity(true);
|
||||||
this.emit('prompted');
|
this.emit('prompted');
|
||||||
}
|
}
|
||||||
@ -416,13 +387,7 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateNextButtonSensitivity(sensitive) {
|
|
||||||
this.nextButton.reactive = sensitive;
|
|
||||||
this.nextButton.can_focus = sensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSensitivity(sensitive) {
|
updateSensitivity(sensitive) {
|
||||||
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
|
||||||
this._entry.reactive = sensitive;
|
this._entry.reactive = sensitive;
|
||||||
this._entry.clutter_text.editable = sensitive;
|
this._entry.clutter_text.editable = sensitive;
|
||||||
}
|
}
|
||||||
@ -445,7 +410,7 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
let userWidget = new UserWidget.UserWidget(user);
|
let userWidget = new UserWidget.UserWidget(user);
|
||||||
userWidget.x_align = Clutter.ActorAlign.START;
|
userWidget.x_align = Clutter.ActorAlign.CENTER;
|
||||||
this._userWell.set_child(userWidget);
|
this._userWell.set_child(userWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,7 +419,6 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
let oldStatus = this.verificationStatus;
|
let oldStatus = this.verificationStatus;
|
||||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||||
this.cancelButton.reactive = true;
|
this.cancelButton.reactive = true;
|
||||||
this.nextButton.label = _("Next");
|
|
||||||
this._preemptiveAnswer = null;
|
this._preemptiveAnswer = null;
|
||||||
|
|
||||||
if (this._userVerifier)
|
if (this._userVerifier)
|
||||||
|
@ -409,7 +409,10 @@ var SessionMenuButton = GObject.registerClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
var LoginDialog = GObject.registerClass({
|
var LoginDialog = GObject.registerClass({
|
||||||
Signals: { 'failed': {} },
|
Signals: {
|
||||||
|
'failed': {},
|
||||||
|
'wake-up-screen': {},
|
||||||
|
},
|
||||||
}, class LoginDialog extends St.Widget {
|
}, class LoginDialog extends St.Widget {
|
||||||
_init(parentActor) {
|
_init(parentActor) {
|
||||||
super._init({ style_class: 'login-dialog', visible: false });
|
super._init({ style_class: 'login-dialog', visible: false });
|
||||||
|
@ -496,6 +496,8 @@ var ShellUserVerifier = class {
|
|||||||
// The only question asked by this service is "Token?"
|
// The only question asked by this service is "Token?"
|
||||||
this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
|
this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
|
||||||
return;
|
return;
|
||||||
|
} else if (serviceName == PASSWORD_SERVICE_NAME) {
|
||||||
|
secretQuestion = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
|
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
|
||||||
|
@ -1,21 +1,16 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const { AccountsService, Clutter, Gio, GLib,
|
const { AccountsService, Clutter, Gio,
|
||||||
GnomeDesktop, GObject, Graphene, Meta, Shell, St } = imports.gi;
|
GLib, Graphene, Meta, Shell, St } = imports.gi;
|
||||||
const Cairo = imports.cairo;
|
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const Background = imports.ui.background;
|
|
||||||
const GnomeSession = imports.misc.gnomeSession;
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
const Layout = imports.ui.layout;
|
|
||||||
const OVirt = imports.gdm.oVirt;
|
|
||||||
const LoginManager = imports.misc.loginManager;
|
const LoginManager = imports.misc.loginManager;
|
||||||
const Lightbox = imports.ui.lightbox;
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const ShellDBus = imports.ui.shellDBus;
|
const ShellDBus = imports.ui.shellDBus;
|
||||||
const SmartcardManager = imports.misc.smartcardManager;
|
|
||||||
|
|
||||||
const { adjustAnimationTime } = imports.ui.environment;
|
const { adjustAnimationTime } = imports.ui.environment;
|
||||||
|
|
||||||
@ -27,17 +22,6 @@ const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
|||||||
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
||||||
|
|
||||||
const LOCKED_STATE_STR = 'screenShield.locked';
|
const LOCKED_STATE_STR = 'screenShield.locked';
|
||||||
// fraction of screen height the arrow must reach before completing
|
|
||||||
// the slide up automatically
|
|
||||||
var ARROW_DRAG_THRESHOLD = 0.1;
|
|
||||||
|
|
||||||
// Parameters for the arrow animation
|
|
||||||
var N_ARROWS = 3;
|
|
||||||
var ARROW_ANIMATION_TIME = 600;
|
|
||||||
var ARROW_ANIMATION_PEAK_OPACITY = 0.4;
|
|
||||||
var ARROW_IDLE_TIME = 30000; // ms
|
|
||||||
|
|
||||||
var SUMMARY_ICON_SIZE = 48;
|
|
||||||
|
|
||||||
// ScreenShield animation time
|
// ScreenShield animation time
|
||||||
// - STANDARD_FADE_TIME is used when the session goes idle
|
// - STANDARD_FADE_TIME is used when the session goes idle
|
||||||
@ -48,384 +32,6 @@ var STANDARD_FADE_TIME = 10000;
|
|||||||
var MANUAL_FADE_TIME = 300;
|
var MANUAL_FADE_TIME = 300;
|
||||||
var CURTAIN_SLIDE_TIME = 300;
|
var CURTAIN_SLIDE_TIME = 300;
|
||||||
|
|
||||||
var Clock = GObject.registerClass(
|
|
||||||
class ScreenShieldClock extends St.BoxLayout {
|
|
||||||
_init() {
|
|
||||||
super._init({ style_class: 'screen-shield-clock', vertical: true });
|
|
||||||
|
|
||||||
this._time = new St.Label({
|
|
||||||
style_class: 'screen-shield-clock-time',
|
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
|
||||||
});
|
|
||||||
this._date = new St.Label({
|
|
||||||
style_class: 'screen-shield-clock-date',
|
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.add_child(this._time);
|
|
||||||
this.add_child(this._date);
|
|
||||||
|
|
||||||
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
|
|
||||||
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
|
|
||||||
|
|
||||||
this._updateClock();
|
|
||||||
|
|
||||||
this.connect('destroy', this._onDestroy.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateClock() {
|
|
||||||
this._time.text = this._wallClock.clock;
|
|
||||||
|
|
||||||
let date = new Date();
|
|
||||||
/* Translators: This is a time format for a date in
|
|
||||||
long format */
|
|
||||||
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d"));
|
|
||||||
this._date.text = date.toLocaleFormat(dateFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDestroy() {
|
|
||||||
this._wallClock.run_dispose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var NotificationsBox = GObject.registerClass({
|
|
||||||
Signals: { 'wake-up-screen': {} },
|
|
||||||
}, class NotificationsBox extends St.BoxLayout {
|
|
||||||
_init() {
|
|
||||||
super._init({
|
|
||||||
vertical: true,
|
|
||||||
name: 'screenShieldNotifications',
|
|
||||||
style_class: 'screen-shield-notifications-container',
|
|
||||||
});
|
|
||||||
|
|
||||||
this._scrollView = new St.ScrollView({ hscrollbar_policy: St.PolicyType.NEVER });
|
|
||||||
this._notificationBox = new St.BoxLayout({ vertical: true,
|
|
||||||
style_class: 'screen-shield-notifications-container' });
|
|
||||||
this._scrollView.add_actor(this._notificationBox);
|
|
||||||
|
|
||||||
this.add_child(this._scrollView);
|
|
||||||
|
|
||||||
this._sources = new Map();
|
|
||||||
Main.messageTray.getSources().forEach(source => {
|
|
||||||
this._sourceAdded(Main.messageTray, source, true);
|
|
||||||
});
|
|
||||||
this._updateVisibility();
|
|
||||||
|
|
||||||
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
|
|
||||||
|
|
||||||
this.connect('destroy', this._onDestroy.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDestroy() {
|
|
||||||
if (this._sourceAddedId) {
|
|
||||||
Main.messageTray.disconnect(this._sourceAddedId);
|
|
||||||
this._sourceAddedId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let items = this._sources.entries();
|
|
||||||
for (let [source, obj] of items)
|
|
||||||
this._removeSource(source, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateVisibility() {
|
|
||||||
this._notificationBox.visible =
|
|
||||||
this._notificationBox.get_children().some(a => a.visible);
|
|
||||||
|
|
||||||
this.visible = this._notificationBox.visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
_makeNotificationCountText(count, isChat) {
|
|
||||||
if (isChat)
|
|
||||||
return ngettext("%d new message", "%d new messages", count).format(count);
|
|
||||||
else
|
|
||||||
return ngettext("%d new notification", "%d new notifications", count).format(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
_makeNotificationSource(source, box) {
|
|
||||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
|
||||||
box.add_child(sourceActor);
|
|
||||||
|
|
||||||
let textBox = new St.BoxLayout({ vertical: true });
|
|
||||||
box.add_child(textBox);
|
|
||||||
|
|
||||||
let title = new St.Label({ text: source.title,
|
|
||||||
style_class: 'screen-shield-notification-label' });
|
|
||||||
textBox.add(title);
|
|
||||||
|
|
||||||
let count = source.unseenCount;
|
|
||||||
let countLabel = new St.Label({ text: this._makeNotificationCountText(count, source.isChat),
|
|
||||||
style_class: 'screen-shield-notification-count-text' });
|
|
||||||
textBox.add(countLabel);
|
|
||||||
|
|
||||||
box.visible = count != 0;
|
|
||||||
return [title, countLabel];
|
|
||||||
}
|
|
||||||
|
|
||||||
_makeNotificationDetailedSource(source, box) {
|
|
||||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
|
||||||
let sourceBin = new St.Bin({ child: sourceActor });
|
|
||||||
box.add(sourceBin);
|
|
||||||
|
|
||||||
let textBox = new St.BoxLayout({ vertical: true });
|
|
||||||
box.add_child(textBox);
|
|
||||||
|
|
||||||
let title = new St.Label({ text: source.title,
|
|
||||||
style_class: 'screen-shield-notification-label' });
|
|
||||||
textBox.add(title);
|
|
||||||
|
|
||||||
let visible = false;
|
|
||||||
for (let i = 0; i < source.notifications.length; i++) {
|
|
||||||
let n = source.notifications[i];
|
|
||||||
|
|
||||||
if (n.acknowledged)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let body = '';
|
|
||||||
if (n.bannerBodyText) {
|
|
||||||
body = n.bannerBodyMarkup
|
|
||||||
? n.bannerBodyText
|
|
||||||
: GLib.markup_escape_text(n.bannerBodyText, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let label = new St.Label({ style_class: 'screen-shield-notification-count-text' });
|
|
||||||
label.clutter_text.set_markup(`<b>${n.title}</b> ${body}`);
|
|
||||||
textBox.add(label);
|
|
||||||
|
|
||||||
visible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
box.visible = visible;
|
|
||||||
return [title, null];
|
|
||||||
}
|
|
||||||
|
|
||||||
_shouldShowDetails(source) {
|
|
||||||
return source.policy.detailsInLockScreen ||
|
|
||||||
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
_showSource(source, obj, box) {
|
|
||||||
if (obj.detailed)
|
|
||||||
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
|
|
||||||
else
|
|
||||||
[obj.titleLabel, obj.countLabel] = this._makeNotificationSource(source, box);
|
|
||||||
|
|
||||||
box.visible = obj.visible && (source.unseenCount > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
_sourceAdded(tray, source, initial) {
|
|
||||||
let obj = {
|
|
||||||
visible: source.policy.showInLockScreen,
|
|
||||||
detailed: this._shouldShowDetails(source),
|
|
||||||
sourceDestroyId: 0,
|
|
||||||
sourceCountChangedId: 0,
|
|
||||||
sourceTitleChangedId: 0,
|
|
||||||
sourceUpdatedId: 0,
|
|
||||||
sourceBox: null,
|
|
||||||
titleLabel: null,
|
|
||||||
countLabel: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
obj.sourceBox = new St.BoxLayout({ style_class: 'screen-shield-notification-source',
|
|
||||||
x_expand: true });
|
|
||||||
this._showSource(source, obj, obj.sourceBox);
|
|
||||||
this._notificationBox.add_child(obj.sourceBox);
|
|
||||||
|
|
||||||
obj.sourceCountChangedId = source.connect('notify::count', () => {
|
|
||||||
this._countChanged(source, obj);
|
|
||||||
});
|
|
||||||
obj.sourceTitleChangedId = source.connect('notify::title', () => {
|
|
||||||
this._titleChanged(source, obj);
|
|
||||||
});
|
|
||||||
obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
|
|
||||||
if (pspec.name == 'show-in-lock-screen')
|
|
||||||
this._visibleChanged(source, obj);
|
|
||||||
else
|
|
||||||
this._detailedChanged(source, obj);
|
|
||||||
});
|
|
||||||
obj.sourceDestroyId = source.connect('destroy', () => {
|
|
||||||
this._onSourceDestroy(source, obj);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._sources.set(source, obj);
|
|
||||||
|
|
||||||
if (!initial) {
|
|
||||||
// block scrollbars while animating, if they're not needed now
|
|
||||||
let boxHeight = this._notificationBox.height;
|
|
||||||
if (this._scrollView.height >= boxHeight)
|
|
||||||
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
|
|
||||||
|
|
||||||
let widget = obj.sourceBox;
|
|
||||||
let [, natHeight] = widget.get_preferred_height(-1);
|
|
||||||
widget.height = 0;
|
|
||||||
widget.ease({
|
|
||||||
height: natHeight,
|
|
||||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
||||||
duration: 250,
|
|
||||||
onComplete: () => {
|
|
||||||
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
|
|
||||||
widget.set_height(-1);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this._updateVisibility();
|
|
||||||
if (obj.sourceBox.visible)
|
|
||||||
this.emit('wake-up-screen');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_titleChanged(source, obj) {
|
|
||||||
obj.titleLabel.text = source.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
_countChanged(source, obj) {
|
|
||||||
// A change in the number of notifications may change whether we show
|
|
||||||
// details.
|
|
||||||
let newDetailed = this._shouldShowDetails(source);
|
|
||||||
let oldDetailed = obj.detailed;
|
|
||||||
|
|
||||||
obj.detailed = newDetailed;
|
|
||||||
|
|
||||||
if (obj.detailed || oldDetailed != newDetailed) {
|
|
||||||
// A new notification was pushed, or a previous notification was destroyed.
|
|
||||||
// Give up, and build the list again.
|
|
||||||
|
|
||||||
obj.sourceBox.destroy_all_children();
|
|
||||||
obj.titleLabel = obj.countLabel = null;
|
|
||||||
this._showSource(source, obj, obj.sourceBox);
|
|
||||||
} else {
|
|
||||||
let count = source.unseenCount;
|
|
||||||
obj.countLabel.text = this._makeNotificationCountText(count, source.isChat);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.sourceBox.visible = obj.visible && (source.unseenCount > 0);
|
|
||||||
|
|
||||||
this._updateVisibility();
|
|
||||||
if (obj.sourceBox.visible)
|
|
||||||
this.emit('wake-up-screen');
|
|
||||||
}
|
|
||||||
|
|
||||||
_visibleChanged(source, obj) {
|
|
||||||
if (obj.visible == source.policy.showInLockScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
obj.visible = source.policy.showInLockScreen;
|
|
||||||
obj.sourceBox.visible = obj.visible && source.unseenCount > 0;
|
|
||||||
|
|
||||||
this._updateVisibility();
|
|
||||||
if (obj.sourceBox.visible)
|
|
||||||
this.emit('wake-up-screen');
|
|
||||||
}
|
|
||||||
|
|
||||||
_detailedChanged(source, obj) {
|
|
||||||
let newDetailed = this._shouldShowDetails(source);
|
|
||||||
if (obj.detailed == newDetailed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
obj.detailed = newDetailed;
|
|
||||||
|
|
||||||
obj.sourceBox.destroy_all_children();
|
|
||||||
obj.titleLabel = obj.countLabel = null;
|
|
||||||
this._showSource(source, obj, obj.sourceBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSourceDestroy(source, obj) {
|
|
||||||
this._removeSource(source, obj);
|
|
||||||
this._updateVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
_removeSource(source, obj) {
|
|
||||||
obj.sourceBox.destroy();
|
|
||||||
obj.sourceBox = obj.titleLabel = obj.countLabel = null;
|
|
||||||
|
|
||||||
source.disconnect(obj.sourceDestroyId);
|
|
||||||
source.disconnect(obj.sourceCountChangedId);
|
|
||||||
source.disconnect(obj.sourceTitleChangedId);
|
|
||||||
source.policy.disconnect(obj.policyChangedId);
|
|
||||||
|
|
||||||
this._sources.delete(source);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var Arrow = GObject.registerClass(
|
|
||||||
class ScreenShieldArrow extends St.Bin {
|
|
||||||
_init(params) {
|
|
||||||
super._init(params);
|
|
||||||
|
|
||||||
this._drawingArea = new St.DrawingArea({
|
|
||||||
x_expand: true,
|
|
||||||
y_expand: true,
|
|
||||||
});
|
|
||||||
this._drawingArea.connect('repaint', this._drawArrow.bind(this));
|
|
||||||
this.child = this._drawingArea;
|
|
||||||
|
|
||||||
this._shadowHelper = null;
|
|
||||||
this._shadowWidth = this._shadowHeight = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_drawArrow(arrow) {
|
|
||||||
let cr = arrow.get_context();
|
|
||||||
let [w, h] = arrow.get_surface_size();
|
|
||||||
let node = this.get_theme_node();
|
|
||||||
let thickness = node.get_length('-arrow-thickness');
|
|
||||||
|
|
||||||
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
|
|
||||||
|
|
||||||
cr.setLineCap(Cairo.LineCap.ROUND);
|
|
||||||
cr.setLineWidth(thickness);
|
|
||||||
|
|
||||||
cr.moveTo(thickness / 2, h - thickness / 2);
|
|
||||||
cr.lineTo(w / 2, thickness);
|
|
||||||
cr.lineTo(w - thickness / 2, h - thickness / 2);
|
|
||||||
cr.stroke();
|
|
||||||
cr.$dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
vfunc_get_paint_volume(volume) {
|
|
||||||
if (!super.vfunc_get_paint_volume(volume))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!this._shadow)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
let shadowBox = new Clutter.ActorBox();
|
|
||||||
this._shadow.get_box(this._drawingArea.get_allocation_box(), shadowBox);
|
|
||||||
|
|
||||||
volume.set_width(Math.max(shadowBox.x2 - shadowBox.x1, volume.get_width()));
|
|
||||||
volume.set_height(Math.max(shadowBox.y2 - shadowBox.y1, volume.get_height()));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
vfunc_style_changed() {
|
|
||||||
let node = this.get_theme_node();
|
|
||||||
this._shadow = node.get_shadow('-arrow-shadow');
|
|
||||||
if (this._shadow)
|
|
||||||
this._shadowHelper = St.ShadowHelper.new(this._shadow);
|
|
||||||
else
|
|
||||||
this._shadowHelper = null;
|
|
||||||
|
|
||||||
super.vfunc_style_changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
vfunc_paint(paintContext) {
|
|
||||||
if (this._shadowHelper) {
|
|
||||||
this._shadowHelper.update(this._drawingArea);
|
|
||||||
|
|
||||||
let allocation = this._drawingArea.get_allocation_box();
|
|
||||||
let paintOpacity = this._drawingArea.get_paint_opacity();
|
|
||||||
let framebuffer = paintContext.get_framebuffer();
|
|
||||||
|
|
||||||
this._shadowHelper.paint(framebuffer, allocation, paintOpacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._drawingArea.paint(paintContext);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function clamp(value, min, max) {
|
|
||||||
return Math.max(min, Math.min(max, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
|
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
|
||||||
* rather than through System Settings, you also need to set
|
* rather than through System Settings, you also need to set
|
||||||
@ -447,59 +53,19 @@ var ScreenShield = class {
|
|||||||
name: 'lockScreenGroup',
|
name: 'lockScreenGroup',
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
this._lockScreenGroup.connect('key-press-event',
|
|
||||||
this._onLockScreenKeyPress.bind(this));
|
|
||||||
this._lockScreenGroup.connect('scroll-event',
|
|
||||||
this._onLockScreenScroll.bind(this));
|
|
||||||
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
|
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
|
||||||
|
|
||||||
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
this._lockDialogGroup = new St.Widget({
|
||||||
name: 'lockScreenContents' });
|
x_expand: true,
|
||||||
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
y_expand: true,
|
||||||
|
reactive: true,
|
||||||
|
can_focus: true,
|
||||||
|
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||||
|
name: 'lockDialogGroup',
|
||||||
|
});
|
||||||
|
|
||||||
this._lockScreenGroup.add_actor(this._lockScreenContents);
|
|
||||||
|
|
||||||
this._backgroundGroup = new Clutter.Actor();
|
|
||||||
|
|
||||||
this._lockScreenGroup.add_actor(this._backgroundGroup);
|
|
||||||
this._lockScreenGroup.set_child_below_sibling(this._backgroundGroup, null);
|
|
||||||
this._bgManagers = [];
|
|
||||||
|
|
||||||
this._updateBackgrounds();
|
|
||||||
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
|
|
||||||
|
|
||||||
this._arrowAnimationId = 0;
|
|
||||||
this._arrowWatchId = 0;
|
|
||||||
this._arrowActiveWatchId = 0;
|
|
||||||
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
|
|
||||||
vertical: true,
|
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
|
||||||
y_align: Clutter.ActorAlign.END,
|
|
||||||
// HACK: without these, ClutterBinLayout
|
|
||||||
// ignores alignment properties on the actor
|
|
||||||
x_expand: true,
|
|
||||||
y_expand: true });
|
|
||||||
|
|
||||||
for (let i = 0; i < N_ARROWS; i++) {
|
|
||||||
let arrow = new Arrow({ opacity: 0 });
|
|
||||||
this._arrowContainer.add_actor(arrow);
|
|
||||||
}
|
|
||||||
this._lockScreenContents.add_actor(this._arrowContainer);
|
|
||||||
|
|
||||||
this._dragAction = new Clutter.GestureAction();
|
|
||||||
this._dragAction.connect('gesture-begin', this._onDragBegin.bind(this));
|
|
||||||
this._dragAction.connect('gesture-progress', this._onDragMotion.bind(this));
|
|
||||||
this._dragAction.connect('gesture-end', this._onDragEnd.bind(this));
|
|
||||||
this._lockScreenGroup.add_action(this._dragAction);
|
|
||||||
|
|
||||||
this._lockDialogGroup = new St.Widget({ x_expand: true,
|
|
||||||
y_expand: true,
|
|
||||||
reactive: true,
|
|
||||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
|
||||||
name: 'lockDialogGroup' });
|
|
||||||
|
|
||||||
this.actor.add_actor(this._lockDialogGroup);
|
|
||||||
this.actor.add_actor(this._lockScreenGroup);
|
this.actor.add_actor(this._lockScreenGroup);
|
||||||
|
this.actor.add_actor(this._lockDialogGroup);
|
||||||
|
|
||||||
this._presence = new GnomeSession.Presence((proxy, error) => {
|
this._presence = new GnomeSession.Presence((proxy, error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -515,20 +81,6 @@ var ScreenShield = class {
|
|||||||
|
|
||||||
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
||||||
|
|
||||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
|
||||||
this._smartcardManager.connect('smartcard-inserted',
|
|
||||||
(manager, token) => {
|
|
||||||
if (this._isLocked && token.UsedToLogin)
|
|
||||||
this._liftShield(true, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
|
||||||
this._oVirtCredentialsManager.connect('user-authenticated',
|
|
||||||
() => {
|
|
||||||
if (this._isLocked)
|
|
||||||
this._liftShield(true, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._loginManager = LoginManager.getLoginManager();
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginManager.connect('prepare-for-sleep',
|
this._loginManager.connect('prepare-for-sleep',
|
||||||
this._prepareForSleep.bind(this));
|
this._prepareForSleep.bind(this));
|
||||||
@ -551,7 +103,6 @@ var ScreenShield = class {
|
|||||||
this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this));
|
this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this));
|
||||||
|
|
||||||
this._isModal = false;
|
this._isModal = false;
|
||||||
this._hasLockScreen = false;
|
|
||||||
this._isGreeter = false;
|
this._isGreeter = false;
|
||||||
this._isActive = false;
|
this._isActive = false;
|
||||||
this._isLocked = false;
|
this._isLocked = false;
|
||||||
@ -591,44 +142,6 @@ var ScreenShield = class {
|
|||||||
this._syncInhibitor();
|
this._syncInhibitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBackground(monitorIndex) {
|
|
||||||
let monitor = Main.layoutManager.monitors[monitorIndex];
|
|
||||||
let widget = new St.Widget({ style_class: 'screen-shield-background',
|
|
||||||
x: monitor.x,
|
|
||||||
y: monitor.y,
|
|
||||||
width: monitor.width,
|
|
||||||
height: monitor.height });
|
|
||||||
|
|
||||||
let bgManager = new Background.BackgroundManager({ container: widget,
|
|
||||||
monitorIndex,
|
|
||||||
controlPosition: false,
|
|
||||||
settingsSchema: SCREENSAVER_SCHEMA });
|
|
||||||
|
|
||||||
this._bgManagers.push(bgManager);
|
|
||||||
|
|
||||||
this._backgroundGroup.add_child(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateBackgrounds() {
|
|
||||||
for (let i = 0; i < this._bgManagers.length; i++)
|
|
||||||
this._bgManagers[i].destroy();
|
|
||||||
|
|
||||||
this._bgManagers = [];
|
|
||||||
this._backgroundGroup.destroy_all_children();
|
|
||||||
|
|
||||||
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
|
|
||||||
this._createBackground(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
_liftShield(onPrimary, velocity) {
|
|
||||||
if (this._isLocked) {
|
|
||||||
if (this._ensureUnlockDialog(onPrimary, true /* allowCancel */))
|
|
||||||
this._hideLockScreen(true /* animate */, velocity);
|
|
||||||
} else {
|
|
||||||
this.deactivate(true /* animate */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_maybeCancelDialog() {
|
_maybeCancelDialog() {
|
||||||
if (!this._dialog)
|
if (!this._dialog)
|
||||||
return;
|
return;
|
||||||
@ -638,9 +151,7 @@ var ScreenShield = class {
|
|||||||
// LoginDialog.cancel() will grab the key focus
|
// LoginDialog.cancel() will grab the key focus
|
||||||
// on its own, so ensure it stays on lock screen
|
// on its own, so ensure it stays on lock screen
|
||||||
// instead
|
// instead
|
||||||
this._lockScreenGroup.grab_key_focus();
|
this._dialog.grab_key_focus();
|
||||||
} else {
|
|
||||||
this._dialog = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,55 +170,6 @@ var ScreenShield = class {
|
|||||||
return this._isModal;
|
return this._isModal;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onLockScreenKeyPress(actor, event) {
|
|
||||||
let symbol = event.get_key_symbol();
|
|
||||||
let unichar = event.get_key_unicode();
|
|
||||||
|
|
||||||
// Do nothing if the lock screen is not fully shown.
|
|
||||||
// This avoids reusing the previous (and stale) unlock
|
|
||||||
// dialog if esc is pressed while the curtain is going
|
|
||||||
// down after cancel.
|
|
||||||
|
|
||||||
if (this._lockScreenState != MessageTray.State.SHOWN)
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
|
||||||
|
|
||||||
let isEnter = symbol == Clutter.KEY_Return ||
|
|
||||||
symbol == Clutter.KEY_KP_Enter ||
|
|
||||||
symbol == Clutter.KEY_ISO_Enter;
|
|
||||||
let isEscape = symbol == Clutter.KEY_Escape;
|
|
||||||
let isLiftChar = GLib.unichar_isprint(unichar) &&
|
|
||||||
(this._isLocked || !GLib.unichar_isgraph(unichar));
|
|
||||||
if (!isEnter && !isEscape && !isLiftChar)
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
|
||||||
|
|
||||||
if (this._isLocked &&
|
|
||||||
this._ensureUnlockDialog(true, true) &&
|
|
||||||
GLib.unichar_isgraph(unichar))
|
|
||||||
this._dialog.addCharacter(unichar);
|
|
||||||
|
|
||||||
this._liftShield(true, 0);
|
|
||||||
return Clutter.EVENT_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onLockScreenScroll(actor, event) {
|
|
||||||
if (this._lockScreenState != MessageTray.State.SHOWN)
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
|
||||||
|
|
||||||
let delta = 0;
|
|
||||||
if (event.get_scroll_direction() == Clutter.ScrollDirection.SMOOTH)
|
|
||||||
delta = Math.abs(event.get_scroll_delta()[0]);
|
|
||||||
else
|
|
||||||
delta = 5;
|
|
||||||
|
|
||||||
this._lockScreenScrollCounter += delta;
|
|
||||||
|
|
||||||
// 7 standard scrolls to lift up
|
|
||||||
if (this._lockScreenScrollCounter > 35)
|
|
||||||
this._liftShield(true, 0);
|
|
||||||
|
|
||||||
return Clutter.EVENT_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
_syncInhibitor() {
|
_syncInhibitor() {
|
||||||
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
||||||
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
||||||
@ -736,79 +198,6 @@ var ScreenShield = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_animateArrows() {
|
|
||||||
let arrows = this._arrowContainer.get_children();
|
|
||||||
let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1);
|
|
||||||
let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY;
|
|
||||||
for (let i = 0; i < arrows.length; i++) {
|
|
||||||
arrows[i].opacity = 0;
|
|
||||||
arrows[i].ease({
|
|
||||||
opacity: maxOpacity,
|
|
||||||
delay: unitaryDelay * (N_ARROWS - (i + 1)),
|
|
||||||
duration: ARROW_ANIMATION_TIME / 2,
|
|
||||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
||||||
onComplete: () => {
|
|
||||||
arrows[i].ease({
|
|
||||||
opacity: 0,
|
|
||||||
duration: ARROW_ANIMATION_TIME / 2,
|
|
||||||
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLib.SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDragBegin() {
|
|
||||||
this._lockScreenGroup.remove_all_transitions();
|
|
||||||
this._lockScreenState = MessageTray.State.HIDING;
|
|
||||||
|
|
||||||
if (this._isLocked)
|
|
||||||
this._ensureUnlockDialog(false, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDragMotion() {
|
|
||||||
let [, origY] = this._dragAction.get_press_coords(0);
|
|
||||||
let [, currentY] = this._dragAction.get_motion_coords(0);
|
|
||||||
|
|
||||||
let newY = currentY - origY;
|
|
||||||
newY = clamp(newY, -global.stage.height, 0);
|
|
||||||
|
|
||||||
this._lockScreenGroup.y = newY;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDragEnd(_action, _actor, _eventX, _eventY, _modifiers) {
|
|
||||||
if (this._lockScreenState != MessageTray.State.HIDING)
|
|
||||||
return;
|
|
||||||
if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
|
|
||||||
// Complete motion automatically
|
|
||||||
let [velocity_, velocityX_, velocityY] = this._dragAction.get_velocity(0);
|
|
||||||
this._liftShield(true, -velocityY);
|
|
||||||
} else {
|
|
||||||
// restore the lock screen to its original place
|
|
||||||
// try to use the same speed as the normal animation
|
|
||||||
let h = global.stage.height;
|
|
||||||
let duration = MANUAL_FADE_TIME * -this._lockScreenGroup.y / h;
|
|
||||||
this._lockScreenGroup.remove_all_transitions();
|
|
||||||
this._lockScreenGroup.ease({
|
|
||||||
y: 0,
|
|
||||||
duration,
|
|
||||||
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
|
||||||
onComplete: () => {
|
|
||||||
this._lockScreenGroup.fixed_position_set = false;
|
|
||||||
this._lockScreenState = MessageTray.State.SHOWN;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this._maybeCancelDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onStatusChanged(status) {
|
_onStatusChanged(status) {
|
||||||
if (status != GnomeSession.PresenceStatus.IDLE)
|
if (status != GnomeSession.PresenceStatus.IDLE)
|
||||||
return;
|
return;
|
||||||
@ -914,14 +303,10 @@ var ScreenShield = class {
|
|||||||
this.actor.show();
|
this.actor.show();
|
||||||
this._isGreeter = Main.sessionMode.isGreeter;
|
this._isGreeter = Main.sessionMode.isGreeter;
|
||||||
this._isLocked = true;
|
this._isLocked = true;
|
||||||
if (this._ensureUnlockDialog(true, true))
|
this._ensureUnlockDialog(true);
|
||||||
this._hideLockScreen(false, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_hideLockScreenComplete() {
|
_hideLockScreenComplete() {
|
||||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
|
||||||
Main.sessionMode.popMode('lock-screen');
|
|
||||||
|
|
||||||
this._lockScreenState = MessageTray.State.HIDDEN;
|
this._lockScreenState = MessageTray.State.HIDDEN;
|
||||||
this._lockScreenGroup.hide();
|
this._lockScreenGroup.hide();
|
||||||
|
|
||||||
@ -931,13 +316,13 @@ var ScreenShield = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_hideLockScreen(animate, velocity) {
|
_hideLockScreen(animate) {
|
||||||
if (this._lockScreenState == MessageTray.State.HIDDEN)
|
if (this._lockScreenState == MessageTray.State.HIDDEN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._lockScreenState = MessageTray.State.HIDING;
|
this._lockScreenState = MessageTray.State.HIDING;
|
||||||
|
|
||||||
this._lockScreenGroup.remove_all_transitions();
|
this._lockDialogGroup.remove_all_transitions();
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
// Tween the lock screen out of screen
|
// Tween the lock screen out of screen
|
||||||
@ -945,16 +330,14 @@ var ScreenShield = class {
|
|||||||
// use the same speed regardless of original position
|
// use the same speed regardless of original position
|
||||||
// if velocity is specified, it's in pixels per milliseconds
|
// if velocity is specified, it's in pixels per milliseconds
|
||||||
let h = global.stage.height;
|
let h = global.stage.height;
|
||||||
let delta = h + this._lockScreenGroup.y;
|
let delta = h + this._lockDialogGroup.translation_y;
|
||||||
let minVelocity = global.stage.height / CURTAIN_SLIDE_TIME;
|
let velocity = global.stage.height / CURTAIN_SLIDE_TIME;
|
||||||
|
|
||||||
velocity = Math.max(minVelocity, velocity);
|
|
||||||
let duration = delta / velocity;
|
let duration = delta / velocity;
|
||||||
|
|
||||||
this._lockScreenGroup.ease({
|
this._lockDialogGroup.ease({
|
||||||
y: -h,
|
translation_y: -h,
|
||||||
duration,
|
duration,
|
||||||
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
onComplete: () => this._hideLockScreenComplete(),
|
onComplete: () => this._hideLockScreenComplete(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -964,7 +347,7 @@ var ScreenShield = class {
|
|||||||
this._cursorTracker.set_pointer_visible(true);
|
this._cursorTracker.set_pointer_visible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ensureUnlockDialog(onPrimary, allowCancel) {
|
_ensureUnlockDialog(allowCancel) {
|
||||||
if (!this._dialog) {
|
if (!this._dialog) {
|
||||||
let constructor = Main.sessionMode.unlockDialog;
|
let constructor = Main.sessionMode.unlockDialog;
|
||||||
if (!constructor) {
|
if (!constructor) {
|
||||||
@ -976,7 +359,7 @@ var ScreenShield = class {
|
|||||||
this._dialog = new constructor(this._lockDialogGroup);
|
this._dialog = new constructor(this._lockDialogGroup);
|
||||||
|
|
||||||
let time = global.get_current_time();
|
let time = global.get_current_time();
|
||||||
if (!this._dialog.open(time, onPrimary)) {
|
if (!this._dialog.open(time)) {
|
||||||
// This is kind of an impossible error: we're already modal
|
// This is kind of an impossible error: we're already modal
|
||||||
// by the time we reach this...
|
// by the time we reach this...
|
||||||
log('Could not open login dialog: failed to acquire grab');
|
log('Could not open login dialog: failed to acquire grab');
|
||||||
@ -985,6 +368,8 @@ var ScreenShield = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._dialog.connect('failed', this._onUnlockFailed.bind(this));
|
this._dialog.connect('failed', this._onUnlockFailed.bind(this));
|
||||||
|
this._wakeUpScreenId = this._dialog.connect(
|
||||||
|
'wake-up-screen', this._wakeUpScreen.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dialog.allowCancel = allowCancel;
|
this._dialog.allowCancel = allowCancel;
|
||||||
@ -1004,94 +389,30 @@ var ScreenShield = class {
|
|||||||
if (this._lockScreenState != MessageTray.State.HIDDEN)
|
if (this._lockScreenState != MessageTray.State.HIDDEN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._ensureLockScreen();
|
|
||||||
this._lockDialogGroup.scale_x = 1;
|
|
||||||
this._lockDialogGroup.scale_y = 1;
|
|
||||||
|
|
||||||
this._lockScreenGroup.show();
|
this._lockScreenGroup.show();
|
||||||
this._lockScreenState = MessageTray.State.SHOWING;
|
this._lockScreenState = MessageTray.State.SHOWING;
|
||||||
|
|
||||||
let fadeToBlack = params.fadeToBlack;
|
let fadeToBlack = params.fadeToBlack;
|
||||||
|
|
||||||
if (params.animateLockScreen) {
|
if (params.animateLockScreen) {
|
||||||
this._lockScreenGroup.y = -global.screen_height;
|
this._lockDialogGroup.translation_y = -global.screen_height;
|
||||||
this._lockScreenGroup.remove_all_transitions();
|
this._lockDialogGroup.remove_all_transitions();
|
||||||
this._lockScreenGroup.ease({
|
this._lockDialogGroup.ease({
|
||||||
y: 0,
|
translation_y: 0,
|
||||||
duration: MANUAL_FADE_TIME,
|
duration: Overview.ANIMATION_TIME,
|
||||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
this._lockScreenShown({ fadeToBlack, animateFade: true });
|
this._lockScreenShown({ fadeToBlack, animateFade: true });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this._lockScreenGroup.fixed_position_set = false;
|
|
||||||
this._lockScreenShown({ fadeToBlack, animateFade: false });
|
this._lockScreenShown({ fadeToBlack, animateFade: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lockScreenGroup.grab_key_focus();
|
this._dialog.grab_key_focus();
|
||||||
|
|
||||||
if (Main.sessionMode.currentMode != 'lock-screen')
|
|
||||||
Main.sessionMode.pushMode('lock-screen');
|
|
||||||
}
|
|
||||||
|
|
||||||
_startArrowAnimation() {
|
|
||||||
this._arrowActiveWatchId = 0;
|
|
||||||
|
|
||||||
if (!this._arrowAnimationId) {
|
|
||||||
this._arrowAnimationId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 6000, this._animateArrows.bind(this));
|
|
||||||
GLib.Source.set_name_by_id(this._arrowAnimationId, '[gnome-shell] this._animateArrows');
|
|
||||||
this._animateArrows();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._arrowWatchId) {
|
|
||||||
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
|
|
||||||
this._pauseArrowAnimation.bind(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_pauseArrowAnimation() {
|
|
||||||
if (this._arrowAnimationId) {
|
|
||||||
GLib.source_remove(this._arrowAnimationId);
|
|
||||||
this._arrowAnimationId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._arrowActiveWatchId)
|
|
||||||
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(this._startArrowAnimation.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
_stopArrowAnimation() {
|
|
||||||
if (this._arrowAnimationId) {
|
|
||||||
GLib.source_remove(this._arrowAnimationId);
|
|
||||||
this._arrowAnimationId = 0;
|
|
||||||
}
|
|
||||||
if (this._arrowActiveWatchId) {
|
|
||||||
this.idleMonitor.remove_watch(this._arrowActiveWatchId);
|
|
||||||
this._arrowActiveWatchId = 0;
|
|
||||||
}
|
|
||||||
if (this._arrowWatchId) {
|
|
||||||
this.idleMonitor.remove_watch(this._arrowWatchId);
|
|
||||||
this._arrowWatchId = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_checkArrowAnimation() {
|
|
||||||
let idleTime = this.idleMonitor.get_idletime();
|
|
||||||
|
|
||||||
if (idleTime < ARROW_IDLE_TIME)
|
|
||||||
this._startArrowAnimation();
|
|
||||||
else
|
|
||||||
this._pauseArrowAnimation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_lockScreenShown(params) {
|
_lockScreenShown(params) {
|
||||||
if (this._dialog && !this._isGreeter) {
|
|
||||||
this._dialog.destroy();
|
|
||||||
this._dialog = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._checkArrowAnimation();
|
|
||||||
|
|
||||||
let motionId = global.stage.connect('captured-event', (stage, event) => {
|
let motionId = global.stage.connect('captured-event', (stage, event) => {
|
||||||
if (event.type() == Clutter.EventType.MOTION) {
|
if (event.type() == Clutter.EventType.MOTION) {
|
||||||
this._cursorTracker.set_pointer_visible(true);
|
this._cursorTracker.set_pointer_visible(true);
|
||||||
@ -1103,8 +424,6 @@ var ScreenShield = class {
|
|||||||
this._cursorTracker.set_pointer_visible(false);
|
this._cursorTracker.set_pointer_visible(false);
|
||||||
|
|
||||||
this._lockScreenState = MessageTray.State.SHOWN;
|
this._lockScreenState = MessageTray.State.SHOWN;
|
||||||
this._lockScreenGroup.fixed_position_set = false;
|
|
||||||
this._lockScreenScrollCounter = 0;
|
|
||||||
|
|
||||||
if (params.fadeToBlack && params.animateFade) {
|
if (params.fadeToBlack && params.animateFade) {
|
||||||
// Take a beat
|
// Take a beat
|
||||||
@ -1127,52 +446,11 @@ var ScreenShield = class {
|
|||||||
this.emit('lock-screen-shown');
|
this.emit('lock-screen-shown');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some of the actors in the lock screen are heavy in
|
|
||||||
// resources, so we only create them when needed
|
|
||||||
_ensureLockScreen() {
|
|
||||||
if (this._hasLockScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._lockScreenContentsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
|
|
||||||
y_align: Clutter.ActorAlign.CENTER,
|
|
||||||
x_expand: true,
|
|
||||||
y_expand: true,
|
|
||||||
vertical: true,
|
|
||||||
style_class: 'screen-shield-contents-box' });
|
|
||||||
this._clock = new Clock();
|
|
||||||
this._lockScreenContentsBox.add_child(this._clock);
|
|
||||||
|
|
||||||
this._lockScreenContents.add_actor(this._lockScreenContentsBox);
|
|
||||||
|
|
||||||
this._notificationsBox = new NotificationsBox();
|
|
||||||
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', this._wakeUpScreen.bind(this));
|
|
||||||
this._lockScreenContentsBox.add_child(this._notificationsBox);
|
|
||||||
|
|
||||||
this._hasLockScreen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_wakeUpScreen() {
|
_wakeUpScreen() {
|
||||||
this._onUserBecameActive();
|
this._onUserBecameActive();
|
||||||
this.emit('wake-up-screen');
|
this.emit('wake-up-screen');
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearLockScreen() {
|
|
||||||
this._clock.destroy();
|
|
||||||
this._clock = null;
|
|
||||||
|
|
||||||
if (this._notificationsBox) {
|
|
||||||
this._notificationsBox.disconnect(this._wakeUpScreenId);
|
|
||||||
this._notificationsBox.destroy();
|
|
||||||
this._notificationsBox = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._stopArrowAnimation();
|
|
||||||
|
|
||||||
this._lockScreenContentsBox.destroy();
|
|
||||||
|
|
||||||
this._hasLockScreen = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
get locked() {
|
get locked() {
|
||||||
return this._isLocked;
|
return this._isLocked;
|
||||||
}
|
}
|
||||||
@ -1193,13 +471,8 @@ var ScreenShield = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_continueDeactivate(animate) {
|
_continueDeactivate(animate) {
|
||||||
this._hideLockScreen(animate, 0);
|
this._hideLockScreen(animate);
|
||||||
|
|
||||||
if (this._hasLockScreen)
|
|
||||||
this._clearLockScreen();
|
|
||||||
|
|
||||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
|
||||||
Main.sessionMode.popMode('lock-screen');
|
|
||||||
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
||||||
Main.sessionMode.popMode('unlock-dialog');
|
Main.sessionMode.popMode('unlock-dialog');
|
||||||
|
|
||||||
@ -1225,9 +498,8 @@ var ScreenShield = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._lockDialogGroup.ease({
|
this._lockDialogGroup.ease({
|
||||||
scale_x: 0,
|
translation_y: -global.screen_height,
|
||||||
scale_y: 0,
|
duration: Overview.ANIMATION_TIME,
|
||||||
duration: animate ? Overview.ANIMATION_TIME : 0,
|
|
||||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
onComplete: () => this._completeDeactivate(),
|
onComplete: () => this._completeDeactivate(),
|
||||||
});
|
});
|
||||||
@ -1264,10 +536,11 @@ var ScreenShield = class {
|
|||||||
if (this._activationTime == 0)
|
if (this._activationTime == 0)
|
||||||
this._activationTime = GLib.get_monotonic_time();
|
this._activationTime = GLib.get_monotonic_time();
|
||||||
|
|
||||||
|
this._ensureUnlockDialog(true);
|
||||||
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
if (Main.sessionMode.currentMode != 'unlock-dialog' &&
|
if (Main.sessionMode.currentMode != 'unlock-dialog') {
|
||||||
Main.sessionMode.currentMode != 'lock-screen') {
|
|
||||||
this._isGreeter = Main.sessionMode.isGreeter;
|
this._isGreeter = Main.sessionMode.isGreeter;
|
||||||
if (!this._isGreeter)
|
if (!this._isGreeter)
|
||||||
Main.sessionMode.pushMode('unlock-dialog');
|
Main.sessionMode.pushMode('unlock-dialog');
|
||||||
|
@ -53,19 +53,6 @@ const _modes = {
|
|||||||
panelStyle: 'login-screen',
|
panelStyle: 'login-screen',
|
||||||
},
|
},
|
||||||
|
|
||||||
'lock-screen': {
|
|
||||||
isLocked: true,
|
|
||||||
isGreeter: undefined,
|
|
||||||
unlockDialog: undefined,
|
|
||||||
components: ['polkitAgent', 'telepathyClient'],
|
|
||||||
panel: {
|
|
||||||
left: [],
|
|
||||||
center: [],
|
|
||||||
right: ['aggregateMenu'],
|
|
||||||
},
|
|
||||||
panelStyle: 'lock-screen',
|
|
||||||
},
|
|
||||||
|
|
||||||
'unlock-dialog': {
|
'unlock-dialog': {
|
||||||
isLocked: true,
|
isLocked: true,
|
||||||
unlockDialog: undefined,
|
unlockDialog: undefined,
|
||||||
|
@ -1,61 +1,558 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
/* exported UnlockDialog */
|
/* exported UnlockDialog */
|
||||||
|
|
||||||
const { AccountsService, Atk, Clutter,
|
const { AccountsService, Atk, Clutter, Gdm, Gio,
|
||||||
Gdm, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
GnomeDesktop, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||||
|
|
||||||
|
const Background = imports.ui.background;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
|
||||||
const AuthPrompt = imports.gdm.authPrompt;
|
const AuthPrompt = imports.gdm.authPrompt;
|
||||||
|
|
||||||
// The timeout before going back automatically to the lock screen (in seconds)
|
// The timeout before going back automatically to the lock screen (in seconds)
|
||||||
const IDLE_TIMEOUT = 2 * 60;
|
const IDLE_TIMEOUT = 2 * 60;
|
||||||
|
|
||||||
|
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
||||||
|
|
||||||
|
const BLUR_BRIGHTNESS = 0.55;
|
||||||
|
const BLUR_RADIUS = 200;
|
||||||
|
|
||||||
|
const SUMMARY_ICON_SIZE = 32;
|
||||||
|
|
||||||
|
var NotificationsBox = GObject.registerClass({
|
||||||
|
Signals: { 'wake-up-screen': {} },
|
||||||
|
}, class NotificationsBox extends St.BoxLayout {
|
||||||
|
_init() {
|
||||||
|
super._init({
|
||||||
|
vertical: true,
|
||||||
|
name: 'unlockDialogNotifications',
|
||||||
|
style_class: 'unlock-dialog-notifications-container',
|
||||||
|
});
|
||||||
|
|
||||||
|
this._scrollView = new St.ScrollView({ hscrollbar_policy: St.PolicyType.NEVER });
|
||||||
|
this._notificationBox = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'unlock-dialog-notifications-container' });
|
||||||
|
this._scrollView.add_actor(this._notificationBox);
|
||||||
|
|
||||||
|
this.add_child(this._scrollView);
|
||||||
|
|
||||||
|
this._sources = new Map();
|
||||||
|
Main.messageTray.getSources().forEach(source => {
|
||||||
|
this._sourceAdded(Main.messageTray, source, true);
|
||||||
|
});
|
||||||
|
this._updateVisibility();
|
||||||
|
|
||||||
|
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
|
||||||
|
|
||||||
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDestroy() {
|
||||||
|
if (this._sourceAddedId) {
|
||||||
|
Main.messageTray.disconnect(this._sourceAddedId);
|
||||||
|
this._sourceAddedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let items = this._sources.entries();
|
||||||
|
for (let [source, obj] of items)
|
||||||
|
this._removeSource(source, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateVisibility() {
|
||||||
|
this._notificationBox.visible =
|
||||||
|
this._notificationBox.get_children().some(a => a.visible);
|
||||||
|
|
||||||
|
this.visible = this._notificationBox.visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
_makeNotificationCountText(count) {
|
||||||
|
return "%d".format(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
_makeNotificationSource(source, box) {
|
||||||
|
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||||
|
box.add_child(sourceActor);
|
||||||
|
|
||||||
|
let textBox = new St.BoxLayout({
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
y_align: Clutter.ActorAlign.CENTER,
|
||||||
|
});
|
||||||
|
box.add_child(textBox);
|
||||||
|
|
||||||
|
let title = new St.Label({
|
||||||
|
text: source.title,
|
||||||
|
style_class: 'unlock-dialog-notification-label',
|
||||||
|
x_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.START,
|
||||||
|
});
|
||||||
|
textBox.add(title);
|
||||||
|
|
||||||
|
let count = source.unseenCount;
|
||||||
|
let countLabel = new St.Label({
|
||||||
|
text: this._makeNotificationCountText(count),
|
||||||
|
style_class: 'unlock-dialog-notification-count-text',
|
||||||
|
});
|
||||||
|
textBox.add(countLabel);
|
||||||
|
|
||||||
|
box.visible = count != 0;
|
||||||
|
return [title, countLabel];
|
||||||
|
}
|
||||||
|
|
||||||
|
_makeNotificationDetailedSource(source, box) {
|
||||||
|
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||||
|
let sourceBin = new St.Bin({ child: sourceActor });
|
||||||
|
box.add(sourceBin);
|
||||||
|
|
||||||
|
let textBox = new St.BoxLayout({ vertical: true });
|
||||||
|
box.add_child(textBox);
|
||||||
|
|
||||||
|
let title = new St.Label({ text: source.title,
|
||||||
|
style_class: 'unlock-dialog-notification-label' });
|
||||||
|
textBox.add(title);
|
||||||
|
|
||||||
|
let visible = false;
|
||||||
|
for (let i = 0; i < source.notifications.length; i++) {
|
||||||
|
let n = source.notifications[i];
|
||||||
|
|
||||||
|
if (n.acknowledged)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let body = '';
|
||||||
|
if (n.bannerBodyText) {
|
||||||
|
body = n.bannerBodyMarkup
|
||||||
|
? n.bannerBodyText
|
||||||
|
: GLib.markup_escape_text(n.bannerBodyText, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let label = new St.Label({ style_class: 'unlock-dialog-notification-count-text' });
|
||||||
|
label.clutter_text.set_markup(`<b>${n.title}</b> ${body}`);
|
||||||
|
textBox.add(label);
|
||||||
|
|
||||||
|
visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
box.visible = visible;
|
||||||
|
return [title, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
_shouldShowDetails(source) {
|
||||||
|
return source.policy.detailsInLockScreen ||
|
||||||
|
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
_showSource(source, obj, box) {
|
||||||
|
if (obj.detailed)
|
||||||
|
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
|
||||||
|
else
|
||||||
|
[obj.titleLabel, obj.countLabel] = this._makeNotificationSource(source, box);
|
||||||
|
|
||||||
|
box.visible = obj.visible && (source.unseenCount > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_sourceAdded(tray, source, initial) {
|
||||||
|
let obj = {
|
||||||
|
visible: source.policy.showInLockScreen,
|
||||||
|
detailed: this._shouldShowDetails(source),
|
||||||
|
sourceDestroyId: 0,
|
||||||
|
sourceCountChangedId: 0,
|
||||||
|
sourceTitleChangedId: 0,
|
||||||
|
sourceUpdatedId: 0,
|
||||||
|
sourceBox: null,
|
||||||
|
titleLabel: null,
|
||||||
|
countLabel: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.sourceBox = new St.BoxLayout({ style_class: 'unlock-dialog-notification-source',
|
||||||
|
x_expand: true });
|
||||||
|
this._showSource(source, obj, obj.sourceBox);
|
||||||
|
this._notificationBox.add_child(obj.sourceBox);
|
||||||
|
|
||||||
|
obj.sourceCountChangedId = source.connect('notify::count', () => {
|
||||||
|
this._countChanged(source, obj);
|
||||||
|
});
|
||||||
|
obj.sourceTitleChangedId = source.connect('notify::title', () => {
|
||||||
|
this._titleChanged(source, obj);
|
||||||
|
});
|
||||||
|
obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
|
||||||
|
if (pspec.name == 'show-in-lock-screen')
|
||||||
|
this._visibleChanged(source, obj);
|
||||||
|
else
|
||||||
|
this._detailedChanged(source, obj);
|
||||||
|
});
|
||||||
|
obj.sourceDestroyId = source.connect('destroy', () => {
|
||||||
|
this._onSourceDestroy(source, obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._sources.set(source, obj);
|
||||||
|
|
||||||
|
if (!initial) {
|
||||||
|
// block scrollbars while animating, if they're not needed now
|
||||||
|
let boxHeight = this._notificationBox.height;
|
||||||
|
if (this._scrollView.height >= boxHeight)
|
||||||
|
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
|
||||||
|
|
||||||
|
let widget = obj.sourceBox;
|
||||||
|
let [, natHeight] = widget.get_preferred_height(-1);
|
||||||
|
widget.height = 0;
|
||||||
|
widget.ease({
|
||||||
|
height: natHeight,
|
||||||
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
|
duration: 250,
|
||||||
|
onComplete: () => {
|
||||||
|
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
|
||||||
|
widget.set_height(-1);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
if (obj.sourceBox.visible)
|
||||||
|
this.emit('wake-up-screen');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_titleChanged(source, obj) {
|
||||||
|
obj.titleLabel.text = source.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
_countChanged(source, obj) {
|
||||||
|
// A change in the number of notifications may change whether we show
|
||||||
|
// details.
|
||||||
|
let newDetailed = this._shouldShowDetails(source);
|
||||||
|
let oldDetailed = obj.detailed;
|
||||||
|
|
||||||
|
obj.detailed = newDetailed;
|
||||||
|
|
||||||
|
if (obj.detailed || oldDetailed != newDetailed) {
|
||||||
|
// A new notification was pushed, or a previous notification was destroyed.
|
||||||
|
// Give up, and build the list again.
|
||||||
|
|
||||||
|
obj.sourceBox.destroy_all_children();
|
||||||
|
obj.titleLabel = obj.countLabel = null;
|
||||||
|
this._showSource(source, obj, obj.sourceBox);
|
||||||
|
} else {
|
||||||
|
let count = source.unseenCount;
|
||||||
|
obj.countLabel.text = this._makeNotificationCountText(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.sourceBox.visible = obj.visible && (source.unseenCount > 0);
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
if (obj.sourceBox.visible)
|
||||||
|
this.emit('wake-up-screen');
|
||||||
|
}
|
||||||
|
|
||||||
|
_visibleChanged(source, obj) {
|
||||||
|
if (obj.visible == source.policy.showInLockScreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
obj.visible = source.policy.showInLockScreen;
|
||||||
|
obj.sourceBox.visible = obj.visible && source.unseenCount > 0;
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
if (obj.sourceBox.visible)
|
||||||
|
this.emit('wake-up-screen');
|
||||||
|
}
|
||||||
|
|
||||||
|
_detailedChanged(source, obj) {
|
||||||
|
let newDetailed = this._shouldShowDetails(source);
|
||||||
|
if (obj.detailed == newDetailed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
obj.detailed = newDetailed;
|
||||||
|
|
||||||
|
obj.sourceBox.destroy_all_children();
|
||||||
|
obj.titleLabel = obj.countLabel = null;
|
||||||
|
this._showSource(source, obj, obj.sourceBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSourceDestroy(source, obj) {
|
||||||
|
this._removeSource(source, obj);
|
||||||
|
this._updateVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
_removeSource(source, obj) {
|
||||||
|
obj.sourceBox.destroy();
|
||||||
|
obj.sourceBox = obj.titleLabel = obj.countLabel = null;
|
||||||
|
|
||||||
|
source.disconnect(obj.sourceDestroyId);
|
||||||
|
source.disconnect(obj.sourceCountChangedId);
|
||||||
|
source.disconnect(obj.sourceTitleChangedId);
|
||||||
|
source.policy.disconnect(obj.policyChangedId);
|
||||||
|
|
||||||
|
this._sources.delete(source);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Clock = GObject.registerClass(
|
||||||
|
class UnlockDialogClock extends St.BoxLayout {
|
||||||
|
_init() {
|
||||||
|
super._init({ style_class: 'unlock-dialog-clock', vertical: true });
|
||||||
|
|
||||||
|
this._time = new St.Label({
|
||||||
|
style_class: 'unlock-dialog-clock-time',
|
||||||
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
});
|
||||||
|
this._date = new St.Label({
|
||||||
|
style_class: 'unlock-dialog-clock-date',
|
||||||
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.add_child(this._time);
|
||||||
|
this.add_child(this._date);
|
||||||
|
|
||||||
|
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
|
||||||
|
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
|
||||||
|
|
||||||
|
this._updateClock();
|
||||||
|
|
||||||
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateClock() {
|
||||||
|
this._time.text = this._wallClock.clock;
|
||||||
|
|
||||||
|
let date = new Date();
|
||||||
|
/* Translators: This is a time format for a date in
|
||||||
|
long format */
|
||||||
|
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d"));
|
||||||
|
this._date.text = date.toLocaleFormat(dateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDestroy() {
|
||||||
|
this._wallClock.run_dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var UnlockDialogLayout = GObject.registerClass(
|
||||||
|
class UnlockDialogLayout extends Clutter.LayoutManager {
|
||||||
|
_init(stack, notifications) {
|
||||||
|
super._init();
|
||||||
|
|
||||||
|
this._stack = stack;
|
||||||
|
this._notifications = notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfunc_get_preferred_width(container, forHeight) {
|
||||||
|
return this._stack.get_preferred_width(forHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
vfunc_get_preferred_height(container, forWidth) {
|
||||||
|
return this._stack.get_preferred_height(forWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
vfunc_allocate(container, box, flags) {
|
||||||
|
let [width, height] = box.get_size();
|
||||||
|
|
||||||
|
let tenthOfHeight = height / 10.0;
|
||||||
|
let thirdOfHeight = height / 3.0;
|
||||||
|
|
||||||
|
let [, , stackWidth, stackHeight] =
|
||||||
|
this._stack.get_preferred_size();
|
||||||
|
|
||||||
|
let [, , notificationsWidth, notificationsHeight] =
|
||||||
|
this._notifications.get_preferred_size();
|
||||||
|
|
||||||
|
let columnWidth = Math.max(stackWidth, notificationsWidth);
|
||||||
|
|
||||||
|
let columnX1 = Math.floor(width / 2.0 - columnWidth / 2.0);
|
||||||
|
let actorBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
let maxNotificationsHeight = Math.min(
|
||||||
|
notificationsHeight,
|
||||||
|
height - tenthOfHeight - stackHeight);
|
||||||
|
|
||||||
|
actorBox.x1 = columnX1;
|
||||||
|
actorBox.y1 = height - maxNotificationsHeight;
|
||||||
|
actorBox.x2 = columnX1 + columnWidth;
|
||||||
|
actorBox.y2 = actorBox.y1 + maxNotificationsHeight;
|
||||||
|
|
||||||
|
this._notifications.allocate(actorBox, flags);
|
||||||
|
|
||||||
|
// Authentication Box
|
||||||
|
let stackY = Math.min(
|
||||||
|
thirdOfHeight,
|
||||||
|
height - stackHeight - maxNotificationsHeight);
|
||||||
|
|
||||||
|
actorBox.x1 = columnX1;
|
||||||
|
actorBox.y1 = stackY;
|
||||||
|
actorBox.x2 = columnX1 + columnWidth;
|
||||||
|
actorBox.y2 = stackY + stackHeight;
|
||||||
|
|
||||||
|
this._stack.allocate(actorBox, flags);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var UnlockDialog = GObject.registerClass({
|
var UnlockDialog = GObject.registerClass({
|
||||||
Signals: { 'failed': {} },
|
Signals: {
|
||||||
|
'failed': {},
|
||||||
|
'wake-up-screen': {},
|
||||||
|
},
|
||||||
}, class UnlockDialog extends St.Widget {
|
}, class UnlockDialog extends St.Widget {
|
||||||
_init(parentActor) {
|
_init(parentActor) {
|
||||||
super._init({
|
super._init({
|
||||||
accessible_role: Atk.Role.WINDOW,
|
accessible_role: Atk.Role.WINDOW,
|
||||||
style_class: 'login-dialog',
|
style_class: 'login-dialog',
|
||||||
layout_manager: new Clutter.BoxLayout(),
|
|
||||||
visible: false,
|
visible: false,
|
||||||
|
can_focus: true,
|
||||||
|
reactive: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
|
||||||
parentActor.add_child(this);
|
parentActor.add_child(this);
|
||||||
|
|
||||||
|
this._activePage = null;
|
||||||
|
|
||||||
|
let tapAction = new Clutter.TapAction();
|
||||||
|
tapAction.connect('tap', this._showPrompt.bind(this));
|
||||||
|
this.add_action(tapAction);
|
||||||
|
|
||||||
|
// Background
|
||||||
|
this._backgroundGroup = new Clutter.Actor();
|
||||||
|
|
||||||
|
this.add_child(this._backgroundGroup);
|
||||||
|
this.set_child_below_sibling(this._backgroundGroup, null);
|
||||||
|
this._bgManagers = [];
|
||||||
|
|
||||||
|
this._updateBackgrounds();
|
||||||
|
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
|
||||||
|
|
||||||
this._userManager = AccountsService.UserManager.get_default();
|
this._userManager = AccountsService.UserManager.get_default();
|
||||||
this._userName = GLib.get_user_name();
|
this._userName = GLib.get_user_name();
|
||||||
this._user = this._userManager.get_user(this._userName);
|
this._user = this._userManager.get_user(this._userName);
|
||||||
|
|
||||||
this._promptBox = new St.BoxLayout({ vertical: true,
|
// Authentication & Clock stack
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
let stack = new Shell.Stack();
|
||||||
y_align: Clutter.ActorAlign.CENTER,
|
|
||||||
x_expand: true,
|
this._promptBox = new St.BoxLayout({ vertical: true });
|
||||||
y_expand: true });
|
stack.add_child(this._promptBox);
|
||||||
this.add_child(this._promptBox);
|
|
||||||
|
// Clock
|
||||||
|
this._clock = new St.BoxLayout({ vertical: true });
|
||||||
|
|
||||||
|
let clock = new Clock();
|
||||||
|
this._clock.add_child(clock);
|
||||||
|
|
||||||
|
let nameLabel = new St.Label({
|
||||||
|
style_class: 'unlock-dialog-user-name',
|
||||||
|
text: this._user.get_real_name(),
|
||||||
|
x_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
});
|
||||||
|
this._clock.add_child(nameLabel);
|
||||||
|
|
||||||
|
stack.add_child(this._clock);
|
||||||
|
this._showClock();
|
||||||
|
|
||||||
|
this.allowCancel = false;
|
||||||
|
|
||||||
|
Main.ctrlAltTabManager.addGroup(this, _("Unlock Window"), 'dialog-password-symbolic');
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
this._notificationsBox = new NotificationsBox();
|
||||||
|
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', () => {
|
||||||
|
this.emit('wake-up-screen');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Main Box
|
||||||
|
let mainBox = new Clutter.Actor();
|
||||||
|
mainBox.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||||
|
mainBox.add_child(stack);
|
||||||
|
mainBox.add_child(this._notificationsBox);
|
||||||
|
mainBox.layout_manager = new UnlockDialogLayout(
|
||||||
|
stack,
|
||||||
|
this._notificationsBox);
|
||||||
|
this.add_child(mainBox);
|
||||||
|
|
||||||
|
this._idleMonitor = Meta.IdleMonitor.get_core();
|
||||||
|
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, this._escape.bind(this));
|
||||||
|
|
||||||
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
vfunc_key_press_event(keyEvent) {
|
||||||
|
if (this._activePage == this._promptBox)
|
||||||
|
return Clutter.EVENT_PROPAGATE;
|
||||||
|
|
||||||
|
let symbol = keyEvent.keyval;
|
||||||
|
let unichar = keyEvent.unicode_value;
|
||||||
|
|
||||||
|
let isLiftChar = GLib.unichar_isprint(unichar);
|
||||||
|
let isEnter = symbol == Clutter.KEY_Return ||
|
||||||
|
symbol == Clutter.KEY_KP_Enter ||
|
||||||
|
symbol == Clutter.KEY_ISO_Enter;
|
||||||
|
|
||||||
|
if (!isEnter && !isLiftChar)
|
||||||
|
return Clutter.EVENT_PROPAGATE;
|
||||||
|
|
||||||
|
this._showPrompt();
|
||||||
|
|
||||||
|
if (GLib.unichar_isgraph(unichar))
|
||||||
|
this.addCharacter(unichar);
|
||||||
|
|
||||||
|
return Clutter.EVENT_PROPAGATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createBackground(monitorIndex) {
|
||||||
|
let monitor = Main.layoutManager.monitors[monitorIndex];
|
||||||
|
let widget = new St.Widget({ style_class: 'screen-shield-background',
|
||||||
|
x: monitor.x,
|
||||||
|
y: monitor.y,
|
||||||
|
width: monitor.width,
|
||||||
|
height: monitor.height });
|
||||||
|
|
||||||
|
let bgManager = new Background.BackgroundManager({ container: widget,
|
||||||
|
monitorIndex,
|
||||||
|
controlPosition: false,
|
||||||
|
settingsSchema: SCREENSAVER_SCHEMA });
|
||||||
|
|
||||||
|
this._bgManagers.push(bgManager);
|
||||||
|
|
||||||
|
this._backgroundGroup.add_child(widget);
|
||||||
|
|
||||||
|
widget.add_effect(new Shell.BlurEffect({
|
||||||
|
brightness: BLUR_BRIGHTNESS,
|
||||||
|
blur_radius: BLUR_RADIUS,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateBackgrounds() {
|
||||||
|
for (let i = 0; i < this._bgManagers.length; i++)
|
||||||
|
this._bgManagers[i].destroy();
|
||||||
|
|
||||||
|
this._bgManagers = [];
|
||||||
|
this._backgroundGroup.destroy_all_children();
|
||||||
|
|
||||||
|
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
|
||||||
|
this._createBackground(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ensureAuthPrompt() {
|
||||||
|
if (this._authPrompt)
|
||||||
|
return;
|
||||||
|
|
||||||
this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
||||||
this._authPrompt.connect('failed', this._fail.bind(this));
|
this._authPrompt.connect('failed', this._fail.bind(this));
|
||||||
this._authPrompt.connect('cancelled', this._fail.bind(this));
|
this._authPrompt.connect('cancelled', this._fail.bind(this));
|
||||||
this._authPrompt.connect('reset', this._onReset.bind(this));
|
this._authPrompt.connect('reset', this._onReset.bind(this));
|
||||||
this._authPrompt.setPasswordChar('\u25cf');
|
this._authPrompt.setPasswordChar('\u25cf');
|
||||||
this._authPrompt.nextButton.label = _("Unlock");
|
|
||||||
|
|
||||||
this._promptBox.add_child(this._authPrompt);
|
this._promptBox.add_child(this._authPrompt);
|
||||||
|
|
||||||
this.allowCancel = false;
|
|
||||||
|
|
||||||
let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
|
let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
|
||||||
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
|
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
|
||||||
let otherUserLabel = new St.Label({ text: _("Log in as another user"),
|
let otherUserLabel = new St.Label({
|
||||||
style_class: 'login-dialog-not-listed-label' });
|
text: _("Log in as another user"),
|
||||||
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
style_class: 'login-dialog-not-listed-label',
|
||||||
can_focus: true,
|
});
|
||||||
child: otherUserLabel,
|
this._otherUserButton = new St.Button({
|
||||||
reactive: true });
|
style_class: 'login-dialog-not-listed-button',
|
||||||
|
can_focus: true,
|
||||||
|
child: otherUserLabel,
|
||||||
|
reactive: true,
|
||||||
|
});
|
||||||
this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
|
this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
|
||||||
this._promptBox.add_child(this._otherUserButton);
|
this._promptBox.add_child(this._otherUserButton);
|
||||||
} else {
|
} else {
|
||||||
@ -64,13 +561,18 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
|
|
||||||
this._authPrompt.reset();
|
this._authPrompt.reset();
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
|
}
|
||||||
|
|
||||||
Main.ctrlAltTabManager.addGroup(this, _("Unlock Window"), 'dialog-password-symbolic');
|
_maybeDestroyAuthPrompt() {
|
||||||
|
this.grab_key_focus();
|
||||||
|
|
||||||
this._idleMonitor = Meta.IdleMonitor.get_core();
|
if (this._authPrompt) {
|
||||||
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, this._escape.bind(this));
|
this._authPrompt.destroy();
|
||||||
|
this._authPrompt = null;
|
||||||
|
|
||||||
this.connect('destroy', this._onDestroy.bind(this));
|
this._otherUserButton.destroy();
|
||||||
|
this._otherUserButton = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateSensitivity(sensitive) {
|
_updateSensitivity(sensitive) {
|
||||||
@ -82,7 +584,55 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_showClock() {
|
||||||
|
if (this._activePage == this._clock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._activePage = this._clock;
|
||||||
|
this._clock.show();
|
||||||
|
|
||||||
|
this._promptBox.ease({
|
||||||
|
opacity: 0,
|
||||||
|
duration: 300,
|
||||||
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
|
onComplete: () => {
|
||||||
|
this._promptBox.hide();
|
||||||
|
this._maybeDestroyAuthPrompt();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this._clock.ease({
|
||||||
|
opacity: 255,
|
||||||
|
duration: 300,
|
||||||
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_showPrompt() {
|
||||||
|
this._ensureAuthPrompt();
|
||||||
|
|
||||||
|
if (this._activePage == this._promptBox)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._activePage = this._promptBox;
|
||||||
|
this._promptBox.show();
|
||||||
|
|
||||||
|
this._clock.ease({
|
||||||
|
opacity: 0,
|
||||||
|
duration: 300,
|
||||||
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
|
onComplete: () => this._clock.hide(),
|
||||||
|
});
|
||||||
|
|
||||||
|
this._promptBox.ease({
|
||||||
|
opacity: 255,
|
||||||
|
duration: 300,
|
||||||
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_fail() {
|
_fail() {
|
||||||
|
this._showClock();
|
||||||
this.emit('failed');
|
this.emit('failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +660,17 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
|
if (this._clock) {
|
||||||
|
this._clock.destroy();
|
||||||
|
this._clock = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._notificationsBox) {
|
||||||
|
this._notificationsBox.disconnect(this._wakeUpScreenId);
|
||||||
|
this._notificationsBox.destroy();
|
||||||
|
this._notificationsBox = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.popModal();
|
this.popModal();
|
||||||
|
|
||||||
if (this._idleWatchId) {
|
if (this._idleWatchId) {
|
||||||
@ -119,16 +680,17 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
|
this._ensureAuthPrompt();
|
||||||
this._authPrompt.cancel();
|
this._authPrompt.cancel();
|
||||||
|
|
||||||
this.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addCharacter(unichar) {
|
addCharacter(unichar) {
|
||||||
|
this._showPrompt();
|
||||||
this._authPrompt.addCharacter(unichar);
|
this._authPrompt.addCharacter(unichar);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish(onComplete) {
|
finish(onComplete) {
|
||||||
|
this._ensureAuthPrompt();
|
||||||
this._authPrompt.finish(onComplete);
|
this._authPrompt.finish(onComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ const { Clutter, GLib, GObject, St } = imports.gi;
|
|||||||
|
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
var AVATAR_ICON_SIZE = 64;
|
var AVATAR_ICON_SIZE = 128;
|
||||||
|
|
||||||
// Adapted from gdm/gui/user-switch-applet/applet.c
|
// Adapted from gdm/gui/user-switch-applet/applet.c
|
||||||
//
|
//
|
||||||
@ -20,7 +20,8 @@ class Avatar extends St.Bin {
|
|||||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||||
params = Params.parse(params, { reactive: false,
|
params = Params.parse(params, { reactive: false,
|
||||||
iconSize: AVATAR_ICON_SIZE,
|
iconSize: AVATAR_ICON_SIZE,
|
||||||
styleClass: 'user-icon' });
|
styleClass: 'user-icon',
|
||||||
|
x_align: St.Align.MIDDLE, });
|
||||||
|
|
||||||
super._init({
|
super._init({
|
||||||
style_class: params.styleClass,
|
style_class: params.styleClass,
|
||||||
@ -73,7 +74,9 @@ class Avatar extends St.Bin {
|
|||||||
} else {
|
} else {
|
||||||
this.style = null;
|
this.style = null;
|
||||||
this.child = new St.Icon({ icon_name: 'avatar-default-symbolic',
|
this.child = new St.Icon({ icon_name: 'avatar-default-symbolic',
|
||||||
icon_size: this._iconSize });
|
icon_size: this._iconSize,
|
||||||
|
x_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -86,11 +89,13 @@ class UserWidgetLabel extends St.Widget {
|
|||||||
this._user = user;
|
this._user = user;
|
||||||
|
|
||||||
this._realNameLabel = new St.Label({ style_class: 'user-widget-label',
|
this._realNameLabel = new St.Label({ style_class: 'user-widget-label',
|
||||||
y_align: Clutter.ActorAlign.CENTER });
|
x_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER });
|
||||||
this.add_child(this._realNameLabel);
|
this.add_child(this._realNameLabel);
|
||||||
|
|
||||||
this._userNameLabel = new St.Label({ style_class: 'user-widget-label',
|
this._userNameLabel = new St.Label({ style_class: 'user-widget-label',
|
||||||
y_align: Clutter.ActorAlign.CENTER });
|
x_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER });
|
||||||
this.add_child(this._userNameLabel);
|
this.add_child(this._userNameLabel);
|
||||||
|
|
||||||
this._currentLabel = null;
|
this._currentLabel = null;
|
||||||
@ -160,7 +165,7 @@ class UserWidgetLabel extends St.Widget {
|
|||||||
var UserWidget = GObject.registerClass(
|
var UserWidget = GObject.registerClass(
|
||||||
class UserWidget extends St.BoxLayout {
|
class UserWidget extends St.BoxLayout {
|
||||||
_init(user) {
|
_init(user) {
|
||||||
super._init({ style_class: 'user-widget', vertical: false });
|
super._init({ style_class: 'user-widget', vertical: true });
|
||||||
|
|
||||||
this._user = user;
|
this._user = user;
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ libshell_public_headers = [
|
|||||||
'shell-app.h',
|
'shell-app.h',
|
||||||
'shell-app-system.h',
|
'shell-app-system.h',
|
||||||
'shell-app-usage.h',
|
'shell-app-usage.h',
|
||||||
|
'shell-blur-effect.h',
|
||||||
'shell-embedded-window.h',
|
'shell-embedded-window.h',
|
||||||
'shell-glsl-effect.h',
|
'shell-glsl-effect.h',
|
||||||
'shell-gtk-embed.h',
|
'shell-gtk-embed.h',
|
||||||
@ -129,6 +130,7 @@ libshell_sources = [
|
|||||||
'shell-app.c',
|
'shell-app.c',
|
||||||
'shell-app-system.c',
|
'shell-app-system.c',
|
||||||
'shell-app-usage.c',
|
'shell-app-usage.c',
|
||||||
|
'shell-blur-effect.c',
|
||||||
'shell-embedded-window.c',
|
'shell-embedded-window.c',
|
||||||
'shell-embedded-window-private.h',
|
'shell-embedded-window-private.h',
|
||||||
'shell-global.c',
|
'shell-global.c',
|
||||||
|
1079
src/shell-blur-effect.c
Normal file
1079
src/shell-blur-effect.c
Normal file
File diff suppressed because it is too large
Load Diff
57
src/shell-blur-effect.h
Normal file
57
src/shell-blur-effect.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* shell-blur-effect.h
|
||||||
|
*
|
||||||
|
* Copyright 2019 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShellBlurMode:
|
||||||
|
* @SHELL_BLUR_MODE_ACTOR: blur the actor contents, and its children
|
||||||
|
* @SHELL_BLUR_MODE_BELOW: blur what's beneath the actor
|
||||||
|
*
|
||||||
|
* The mode of blurring of the effect.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SHELL_BLUR_MODE_ACTOR,
|
||||||
|
SHELL_BLUR_MODE_BELOW,
|
||||||
|
} ShellBlurMode;
|
||||||
|
|
||||||
|
#define SHELL_TYPE_BLUR_EFFECT (shell_blur_effect_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE (ShellBlurEffect, shell_blur_effect, SHELL, BLUR_EFFECT, ClutterEffect)
|
||||||
|
|
||||||
|
ShellBlurEffect *shell_blur_effect_new (void);
|
||||||
|
|
||||||
|
int shell_blur_effect_get_blur_radius (ShellBlurEffect *self);
|
||||||
|
void shell_blur_effect_set_blur_radius (ShellBlurEffect *self,
|
||||||
|
int radius);
|
||||||
|
|
||||||
|
float shell_blur_effect_get_brightness (ShellBlurEffect *self);
|
||||||
|
void shell_blur_effect_set_brightness (ShellBlurEffect *self,
|
||||||
|
float brightness);
|
||||||
|
|
||||||
|
ShellBlurMode shell_blur_effect_get_mode (ShellBlurEffect *self);
|
||||||
|
void shell_blur_effect_set_mode (ShellBlurEffect *self,
|
||||||
|
ShellBlurMode mode);
|
||||||
|
|
||||||
|
G_END_DECLS
|
Loading…
Reference in New Issue
Block a user