Compare commits
	
		
			40 Commits
		
	
	
		
			wip/carlos
			...
			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 | ||||||
		Reference in New Issue
	
	Block a user