Compare commits

..

1 Commits

Author SHA1 Message Date
Carlos Garnacho
cdd513aef4 shellEntry: Look up keymap from the ClutterSeat
The get_keymap() method no longer exists on the ClutterBackend, but was
moved to the ClutterSeat.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/969
2020-01-31 11:18:54 +01:00
159 changed files with 16471 additions and 20882 deletions

View File

@@ -19,7 +19,7 @@ fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}

68
NEWS
View File

@@ -1,71 +1,3 @@
3.35.91
=======
* Improve magnifier [Carlos; !984]
* Only enable OSK automatically if touch-mode is enabled [Carlos; #872]
* Merge screen shield and unlock dialog to new lock screen [Georges; !872]
* Improve ShellBlur effect [Jonas; !991]
* Adapt user avatar for new lock screen [Umang, Georges; !922]
* Animate prompt transition on lock screen [Florian; !972]
* Reduce font-size in dialog titles if text doesn't fit [Jonas; !1012]
* Various lock screen improvements and bug fixes [Jakub, Florian, Georges;
!996, !997, !999, #2212, !998, !1006, #2215, #2213]
* Misc. bug fixes and cleanups [Daniel, Florian, Jakub, nana-4, Jonas; #2170,
#2167, !936, !988, #2187, !994, !995, !938, #2194, #2203, !1004, !977, !1014]
Contributors:
Jonas Dreßler, Carlos Garnacho, Umang Jain, Daniel Mustieles, Florian Müllner,
Georges Basile Stavracas Neto, Jakub Steiner, Daniel van Vugt, nana-4
Translators:
Daniel Mustieles [es, pt_BR], Rafael Fontenelle [pt_BR], Danial Behzadi [fa],
Anders Jonsson [sv], Asier Sarasua Garmendia [eu], Aurimas Černius [lt],
Bruce Cowan [en_GB], sicklylife [ja], Fran Dieguez [gl], Kukuh Syafaat [id],
Emin Tufan Çetin [tr], Jiri Grönroos [fi], Jordi Mas [ca], Claude Paroz [fr],
Ask Hjorth Larsen [da], Марко Костић [sr], Piotr Drąg [pl],
Charles Monzat [fr], Balázs Úr [hu]
3.35.90
=======
* Update default favorite apps [Michael; !907]
* Add Shell.Blur effect [Georges; !864, !924]
* Overhaul scroll/swipe gestures [Alexander; !821, !825, !826]
* Fix VPN connections when delaying request [Florian; #2008]
* Overhaul theme [Sam, Jakub, nana-4; !904, !931, !957]
* Improve visual appearance of Weather integration [Florian; #1143]
* Implement new system dialog designs [Jonas; #1343]
* Animate position changes of app icons [Georges; !882]
* Add St.Viewport [Georges; !929]
* Make app folders behave as dialogs [Georges; !896]
* Add do-not-disturb functionality to calendar popup [Florian; #239]
* Show hint actor in focused entries [Jonas; !944]
* Switch screen-recorder back to VP8 [Björn; #256]
* Allow to run perf-tool as wayland compositor [Olivier; !941]
* Handle extension updates [Florian; !945]
* Animate showing and hiding caps-lock warning [Jonas; !952]
* Support "auto" lengths in CSS [Florian; !971]
* Turn extension-prefs into the offical Extensions app [Florian; #1968]
* Sandbox the portal helper [Michael; !983]
* Misc. bug fixes and cleanups [Florian, Björn, Jakub, Alexander, Daniel V.,
Jonas, nana-4, Carlos, Sebastian, Daniel G., Georges, Piotr; !918, !917,
!919, !920, #763, #791659, !927, #2091, !930, !926, !888, !934, !168, #2133,
#682, #2142, #2131, !943, #2132, #1958, #2146, !951, #1779, #2130, !964,
!965, !948, #2151, #1746, !967, !760, !968, !970, !973, #2169, #2176, !978,
!980, !979, #2177, !981, #2180, !974]
Contributors:
Michael Catanzaro, Björn Daase, Jonas Dreßler, Piotr Drąg, Olivier Fourdan,
Carlos Garnacho, Sam Hewitt, Sebastian Keller, Andre Klapper,
Alexander Mikhaylenko, Daniel García Moreno, Florian Müllner,
Georges Basile Stavracas Neto, Jakub Steiner, Daniel van Vugt, nana-4
Translators:
Asier Sarasua Garmendia [eu], Daniel Mustieles [es], Andrej Shadura [sk],
Carmen Bianca BAKKER [eo], Sucipto [id], Dušan Kazik [sk], Goran Vidović [hr],
sicklylife [ja], Kukuh Syafaat [id], Yi-Jyun Pan [zh_TW],
Rafael Fontenelle [pt_BR], Jordi Mas [ca], Jiri Grönroos [fi],
Fabio Tomat [fur], Umarzuki Bin Mochlis Moktar [ms], Daniel Korostil [uk],
Jor Teron [mjw], Anders Jonsson [sv], Aurimas Černius [lt]
3.35.3
======
* Add discrete GPU support for NVidia drivers [Bastien; #1810]

View File

@@ -57,19 +57,5 @@
<method name="GetWindows">
<arg name="windows" direction="out" type="a{ta{sv}}" />
</method>
<!--
AnimationsEnabled:
@short_description: Whether the shell animations are enabled
By default determined by the org.gnome.desktop.interface enable-animations
gsetting, but may be overridden, e.g. if there is an active screen cast or
remote desktop session that asked for animations to be disabled.
Since: 2
-->
<property name="AnimationsEnabled" type="b" access="read"/>
<property name="version" type="u" access="read"/>
</interface>
</node>

View File

@@ -1,9 +1,8 @@
[Desktop Entry]
Type=Application
Name=Extensions
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=org.gnome.Extensions
Name=Shell Extensions
Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
Categories=GNOME;GTK;
OnlyShowIn=GNOME;
NoDisplay=true

View File

@@ -9,9 +9,16 @@
<file>dash-placeholder.svg</file>
<file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file>
<file>key-enter.svg</file>
<file>key-hide.svg</file>
<file>key-layout.svg</file>
<file>key-shift.svg</file>
<file>key-shift-uppercase.svg</file>
<file>key-shift-latched-uppercase.svg</file>
<file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file>no-events.svg</file>
<file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>pad-osd.css</file>
<file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
<file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
@@ -19,11 +26,6 @@
<file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
<file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
<file alias="icons/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
<file alias="icons/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
<file alias="icons/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
<file alias="icons/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
<file alias="icons/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
<file alias="icons/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file>
<file>process-working.svg</file>
<file>toggle-off.svg</file>
<file>toggle-off-dark.svg</file>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6.5 1.031c-.371 0-.742-.035-1.11.016-.367.05-.73.203-.972.476-.125.141-.215.309-.266.485-.047.18-.054.367-.02.55.032.184.102.356.192.516.09.164.203.309.317.457L5 4H2a1.8 1.8 0 00-.41.035.791.791 0 00-.36.195.791.791 0 00-.195.36C1 4.723 1 4.863 1 5v2.75l.77-.344c.265-.117.542-.23.832-.242.289-.016.586.074.812.254.227.18.383.441.465.723.082.277.101.57.121.859.02.316.04.637-.016.95-.058.312-.199.616-.43.831a1.264 1.264 0 01-.874.32c-.317-.007-.618-.128-.91-.257L1 10.5V14c0 .137.004.277.035.41a.791.791 0 00.195.36c.098.097.227.16.36.195.133.035.273.035.41.035h3l-.328-.68c-.14-.293-.274-.597-.29-.922-.015-.32.095-.652.31-.894.214-.242.523-.39.84-.453.316-.067.644-.059.968-.059.324 0 .652-.008.969.059.316.062.625.21.84.453.214.242.324.574.308.894-.015.325-.148.63-.289.922L8 15h3a1.8 1.8 0 00.41-.035.791.791 0 00.36-.195.791.791 0 00.195-.36C12 14.277 12 14.137 12 14v-3.563l.703.297c.29.125.59.239.902.246.313.004.63-.101.864-.308.238-.203.386-.496.46-.8C15 9.565 15 9.25 15 8.937c0-.313 0-.63-.07-.934-.075-.305-.223-.598-.461-.8a1.288 1.288 0 00-.864-.31c-.312.008-.613.122-.902.247L12 7.437V5a1.8 1.8 0 00-.035-.41.791.791 0 00-.195-.36.791.791 0 00-.36-.195C11.277 4 11.137 4 11 4H8l.36-.469c.113-.148.226-.293.316-.457.09-.16.16-.332.191-.515a1.248 1.248 0 00-.02-.551 1.256 1.256 0 00-.265-.485c-.242-.273-.605-.425-.973-.476-.367-.05-.738-.016-1.109-.016zm0 0" fill="#474747"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1 +0,0 @@
install_subdir('hicolor', install_dir: icondir)

View File

@@ -1,6 +1,6 @@
desktop_files = [
'org.gnome.Shell.desktop',
'org.gnome.Extensions.desktop',
'gnome-shell-extension-prefs.desktop'
]
service_files = []
@@ -43,7 +43,6 @@ endforeach
subdir('dbus-interfaces')
subdir('icons')
subdir('theme')
data_resources = [

View File

@@ -19,13 +19,13 @@ $error_color: #ff8080;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$osd_fg_color: #eeeeec;
$osd_text_color: white;
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04);
$osd_fg_color: $fg_color;
$osd_text_color: if($variant == 'light', #000, #fff);
$osd_bg_color: if($variant == 'light', rgba(255,255,255,0.9), transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04));
$osd_insensitive_bg_color: transparentize(mix($osd_fg_color, opacify($osd_bg_color, 1), 10%), 0.5);
$osd_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
$osd_borders_color: transparentize(black, 0.3);
$osd_outer_borders_color: transparentize(white, 0.84);
$osd_borders_color: if($variant == 'light', rgba(255,255,255,0.1), rgba(0,0,0,0.7));
$osd_outer_borders_color: if($variant == 'light', rgba(0,0,0,0.1), lighten($osd_bg_color, 7%));
$shadow_color: if($variant == 'light', rgba(0,0,0,0.1), rgba(0,0,0,0.2));
@@ -40,4 +40,4 @@ $backdrop_bg_color: $bg_color;
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
$backdrop_insensitive_color: if($variant =='light', darken($backdrop_bg_color,15%), lighten($backdrop_bg_color,15%));
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);

View File

@@ -54,8 +54,8 @@ $base_font_size: 11;
$text_shadow_color: if($variant == 'light', rgba(255,255,255,0.3), rgba(0,0,0,0.2));
// icons
$base_icon_size: 1.09em;
// $base_icon_size: 16px;
// $base_icon_size: 1.09em;
$base_icon_size: 16px;
// Stage
stage {
@@ -91,9 +91,13 @@ stage {
// icon tiles
%icon_tile {
background-color: transparent; // no background
color: $osd_fg_color;
border-radius: $base_border_radius + 4px;
padding: $base_padding;
border: 2px solid transparent;
border-width: 2px;
border-style: solid;
border-color: transparent;
transition-duration: 100ms;
text-align: center;
}
@@ -151,17 +155,14 @@ stage {
// notification styling
@mixin notification_bubble($flat: false) {
%notification_bubble {
border-width: 1px;
border-style: solid;
border-radius: $base_border_radius + 2px;
border-radius:$base_border_radius + 2px;
padding: 0;
margin: $base_margin;
@if $flat {
@include button(undecorated);
} @else {
@include button(normal);
}
@include button(normal);
&:focus {
@include button(focus);

View File

@@ -137,7 +137,7 @@
// normal button
@if $t==normal {
color: $tc;
background-color: lighten($c, 3%);
background-color: lighten($c, 3%) !important;
border-color: draw_border_color($c);
@include draw_shadows($button_shadow);
// box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
@@ -150,14 +150,14 @@
color: $tc;
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
box-shadow: inset 0 0 0 2px transparentize($selected_bg_color, 0.4);
box-shadow: inset 0 0 0 2px transparentize($selected_bg_color, 0.7);
//border-color: $selected_bg_color;
}
// hover button
@else if $t==hover {
color: $tc;
background-color: lighten($c, if($variant == 'light', 8%, 5%));
background-color: lighten($c, if($variant == 'light', 8%, 5%)) !important;
border-color: if($variant == 'light', draw_border_color(lighten($c, 7%)), draw_border_color($c));
@include draw_shadows($button_shadow);
text-shadow: 0 1px $text_shadow_color;
@@ -167,7 +167,7 @@
// active button
@else if $t==active {
color: $tc;
background-color: darken($c,3%);
background-color: darken($c,3%) !important;
border-color: draw_border_color(if($variant == 'light', $c, darken($c,7%)));
text-shadow: none;
icon-shadow: none;
@@ -178,7 +178,7 @@
@else if $t==insensitive {
color: $insensitive_fg_color;
border-color: $insensitive_borders_color;
background-color: $insensitive_bg_color;
background-color: $insensitive_bg_color !important;
box-shadow: none;
text-shadow: none;
icon-shadow: none;
@@ -194,38 +194,3 @@
icon-shadow: none;
}
}
// overview icons
@mixin overview-icon($color) {
.overview-icon {
@extend %icon_tile;
color: $color;
}
&:hover,
&:selected {
.overview-icon {
background-color: transparentize($color, .9);
}
}
&:focus {
.overview-icon {
background-color: transparentize($color, .7);
// border-color: $selected_bg_color;
}
}
&:drop {
.overview-icon {
background-color: transparentize($selected_bg_color, .15);
}
}
&:active,
&:checked {
.overview-icon {
background-color: transparentize(darken($osd_bg_color, 10%), .5);
}
}
}

View File

@@ -5,47 +5,34 @@
//
/* WIDGETS */
// Primary widgets
@import 'widgets/base';
@import 'widgets/entries';
@import 'widgets/app-grid';
@import 'widgets/app-switcher';
@import 'widgets/buttons';
@import 'widgets/check-box';
@import 'widgets/switches';
@import 'widgets/slider';
@import 'widgets/scrollbars';
// Popovers
@import 'widgets/popovers';
@import 'widgets/calendar';
@import 'widgets/message-list';
@import 'widgets/ibus-popup';
// Notifications
@import 'widgets/notifications';
@import 'widgets/hotplug';
// Dialogs
@import 'widgets/dialogs';
@import 'widgets/network-dialog';
// OSDs
@import 'widgets/osd';
@import 'widgets/switcher-popup';
@import 'widgets/workspace-switcher';
// Panel
@import 'widgets/panel';
@import 'widgets/check-box';
@import 'widgets/corner-ripple';
// Overview
@import 'widgets/dash';
@import 'widgets/dialogs';
@import 'widgets/entries';
@import 'widgets/hotplug';
@import 'widgets/ibus-popup';
@import 'widgets/keyboard';
@import 'widgets/login-dialog';
@import 'widgets/looking-glass';
@import 'widgets/message-list';
@import 'widgets/notifications';
@import 'widgets/misc';
@import 'widgets/network-dialog';
@import 'widgets/osd';
@import 'widgets/overview';
@import 'widgets/window-picker';
@import 'widgets/panel';
@import 'widgets/popovers';
@import 'widgets/screen-shield';
@import 'widgets/scrollbars';
@import 'widgets/search-entry';
@import 'widgets/search-results';
@import 'widgets/app-grid';
@import 'widgets/dash';
@import 'widgets/workspace-thumbnails';
// A11y / misc
@import 'widgets/a11y';
@import 'widgets/misc';
@import 'widgets/slider';
@import 'widgets/switches';
@import 'widgets/tiled-previews';
@import 'widgets/keyboard';
@import 'widgets/looking-glass';
// Lock / login screens
@import 'widgets/login-dialog';
@import 'widgets/screen-shield';
@import 'widgets/window-picker';
@import 'widgets/workspace-switcher';

View File

@@ -1,24 +0,0 @@
// Pointer location
.ripple-pointer-location {
width: $ripple_size;
height: $ripple_size;
border-radius: $ripple_size * 0.5; // radius equals the size of the box to give us the curve
background-color: lighten(transparentize($selected_bg_color, 0.7), 30%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
}
// Pointer accessibility notifications
.pie-timer {
width: 60px;
height: 60px;
-pie-border-width: 3px;
-pie-border-color: $selected_bg_color;
-pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
}
// Screen zoom/Magnifier
.magnifier-zoom-region {
border: 2px solid $selected_bg_color;
&.full-screen { border-width: 0; }
}

View File

@@ -11,6 +11,7 @@ $app_icon_padding: 24px;
.overview-icon {
icon-size: $app_icon_size;
StIcon { margin-bottom: $base_margin; } // margin on icon so label isn't close
}
}
@@ -20,16 +21,59 @@ $app_icon_padding: 24px;
$app_grid_fg_color: #fff;
// Outline for low res icons
.lowres-icon {
icon-shadow: 0 1px 2px rgba(0,0,0,0.3);
}
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 2px rgba(0,0,0,0.4);
}
// Icon tiles in the app grid
.app-well-app,
%app-well-app {
@include overview-icon($app_grid_fg_color);
.app-folder {
.overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
.overview-icon {
@extend %icon_tile;
color: $app_grid_fg_color !important;
}
> StBoxLayout {
spacing: $base_spacing;
&:selected {
.overview-icon {
background-color: transparentize($osd_bg_color,0.7);
color: $app_grid_fg_color;
}
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_fg_color,0.9);
color: $osd_fg_color;
}
}
&:focus {
.overview-icon {
background-color: transparentize($osd_fg_color,0.7 );
// border-color: $selected_bg_color;
color: $app_grid_fg_color;
}
}
&:drop {
.overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
}
&:active,
&:checked {
.overview-icon {
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
}
}
}
@@ -37,18 +81,18 @@ $app_grid_fg_color: #fff;
/* App Folders */
.app-folder {
.overview-icon {
@extend %icon_tile;
}
}
// expanded folder
.app-folder-dialog {
border-radius: $modal_radius * 1.5;
border: 1px solid $osd_outer_borders_color;
spacing: 12px;
border-radius: 8px;
spacing: 24px;
background-color: transparentize(darken($osd_bg_color,10%), 0.05);
& .folder-name-container {
padding: 24px 36px 0;
padding: 12px 18px;
spacing: 12px;
& .folder-name-label,
@@ -73,10 +117,6 @@ $app_grid_fg_color: #fff;
& > StIcon { icon-size: 16px }
}
}
& StButton#vhandle,
& StButton#vhandle:hover,
& StButton#vhandle:active { background-color: transparent; }
}
.app-folder-dialog-container {
padding: 12px;
@@ -133,6 +173,11 @@ $app_grid_fg_color: #fff;
padding: 0px 88px 10px 88px;
}
.app-well-app > .overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
spacing: $base_spacing;
}
// Label when no frequent apps
.no-frequent-applications-label { @extend %status_text; }
@@ -152,35 +197,41 @@ $app_grid_fg_color: #fff;
}
// buttons
.app-view-control {
padding: 4px 32px;
margin: 0 4px;
.app-view-control {
padding: $base_padding $base_padding*5;
margin: 0;
background-color: transparentize($osd_bg_color, 0.5);
border-width: 1px;
color: darken($osd_fg_color, 25%);
&, &:hover, &:checked {
@include button(undecorated);
&:hover {
background-color: transparentize($osd_bg_color, 0.5) !important;
box-shadow:none !important;
color: darken($osd_fg_color, 25%);
}
&:hover {
color: $osd_fg_color;
box-shadow: inset 0 -2px darken($osd_fg_color, 25%);
}
&:active {
box-shadow: inset 0 -2px $osd_fg_color;
box-shadow: none;
background-color: $selected_bg_color !important;
&:hover {
background-color: lighten($selected_bg_color, 11%) !important;
}
}
&:checked {
color: $osd_fg_color;
box-shadow: inset 0 -2px $selected_bg_color;
background-color: $selected_bg_color !important;
color: $selected_fg_color;
box-shadow: none;
&:active { background-color: darken($selected_bg_color, 4%) !important; }
&:hover { background-color: lighten($selected_bg_color, 7%) !important; }
}
&:first-child {
border-right-width: 0;
border-radius: 0;
border-right-width: 0 !important;
border-radius: $base_border_radius 0 0 $base_border_radius;
}
&:last-child {
border-radius: 0;
border-radius: 0 $base_border_radius $base_border_radius 0;
}
}

View File

@@ -52,16 +52,4 @@
&:highlighted {
color: $fg_color;
}
}
// Input Source Switcher
.input-source-switcher-symbol {
font-size: 34pt;
width: 96px;
height: 96px;
}
// Window cycler highlight
.cycler-highlight {
border: 5px solid $selected_bg_color;
}
}

View File

@@ -1,18 +0,0 @@
// Links
.shell-link {
color: $link_color;
&:hover {
color: lighten($link_color, 10%);
}
}
// Outline for low res icons
.lowres-icon {
icon-shadow: 0 1px 2px rgba(black, 0.3);
}
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 2px rgba(black, 0.4);
}

View File

@@ -1,65 +1,87 @@
/* Date/Time Menu */
.clock-display-box {
spacing: $base_spacing / 2;
.clock {
padding-left: $base_padding;
padding-right: $base_padding;
}
}
.clock-display-box { spacing: $base_spacing; }
// overall menu
#calendarArea {
padding:0;
margin:0;
}
// Calendar menu side column
.datemenu-calendar-column {
spacing: $base_spacing;
spacing: 0;
border: 0 solid $bubble_borders_color;
padding: 0 $base_padding * 2;
padding: $base_padding * 2;
padding-bottom: 3em; // account for the notifications clear button
padding-top:0;
&:ltr {margin-right: $base_margin * 2; border-left-width: 1px; }
&:rtl {margin-left: $base_margin * 2; border-right-width: 1px; }
// today button (the date)
.datemenu-today-button {
padding: $base_padding * 1.5;
margin: $base_margin;
border: 1px solid transparent;
border-radius: $base_border_radius + 2px;
&:hover { @include button(hover);}
&:focus { @include button(focus);}
&:active {
@include button(active);
}
// weekday label
.day-label {
@include fontsize($base_font_size+1);
font-weight: bold;
}
// date label
.date-label {
@include fontsize($base_font_size+7);
font-weight: 1000;
}
}
// calendar
.calendar {
@extend %notification_bubble;
margin:$base_margin !important;
margin-bottom: $base_padding + $base_margin !important;
padding:$base_padding !important;
// more below for sub-elements
}
.datemenu-displays-section {
margin:0;
}
.datemenu-displays-box {
spacing: $base_spacing;
margin:0;
// world clocks and weather
.world-clocks-button,
.weather-button {
@extend %notification_bubble;
padding:$base_padding !important;
}
}
}
.events-section-title {
@include notification_bubble($flat: true);
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
border-radius: 4px;
padding: .4em;
}
/* today button (the date) */
.datemenu-today-button {
@include notification_bubble($flat: true);
padding: $base_padding * 1.5;
// weekday label
.day-label {
@include fontsize($base_font_size+1);
font-weight: bold;
}
// date label
.date-label {
@include fontsize($base_font_size+7);
font-weight: 1000;
}
}
/* Calendar */
.calendar {
@include notification_bubble;
padding: $base_padding;
// month
.calendar-month-label {
@@ -110,7 +132,6 @@
@include fontsize($base_font_size - 4);
}
}
.calendar-day { //border collapse hack - see calendar.js
border-width: 0;
}
@@ -119,12 +140,8 @@
border-top-width: 1px;
}
.calendar-day-left {
border-left-width: 1px;
}
.calendar-day-left { border-left-width: 1px; }
.calendar-work-day {}
.calendar-nonwork-day {
color: $insensitive_fg_color;
}
@@ -144,14 +161,13 @@
&:active,&:selected {
background-color: $selected_bg_color;
color: $selected_fg_color;
&:hover,&:focus {
background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color;
}
}
}
}
.calendar-day-with-events {
color: lighten($fg_color,10%);
font-weight: bold;
@@ -160,6 +176,7 @@
.calendar-other-month-day {
color: transparentize($fg_color ,0.5);
opacity: 0.5;
}
.calendar-week-number {
@@ -175,16 +192,51 @@
}
}
/* World clocks */
.world-clocks-button {
@include notification_bubble;
padding: $base_padding * 2;
.world-clocks-grid {
/* Weather */
.weather-box {
spacing: $base_spacing;
padding:$base_padding;
.weather-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
&.location {
font-weight: normal;
@include fontsize($base_font_size - 1);
}
}
.weather-grid {
margin-top: $base_margin;
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
.weather-forecast-time {
color: darken($fg_color,30%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 2);
font-weight: normal;
padding-top: 0.2em;
padding-bottom: 0.4em;
}
.weather-forecast-icon {
icon-size: $base_icon_size * 2;
}
.weather-forecast-temp {
font-weight: bold;
}
}
/* World clocks */
.world-clocks-grid {
padding:$base_padding;
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
// title
.world-clocks-header {
color: desaturate(darken($fg_color,40%), 10%);
@@ -214,49 +266,3 @@
@include fontsize($base_font_size - 1);
}
}
/* Weather */
.weather-button {
@include notification_bubble;
padding: $base_padding * 2;
.weather-box {
spacing: $base_spacing + $base_margin;
}
.weather-header-box {
spacing: $base_spacing;
}
.weather-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
&.location {
font-weight: normal;
@include fontsize($base_font_size - 1);
}
}
.weather-grid {
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
.weather-forecast-time {
color: darken($fg_color,30%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 2);
font-weight: normal;
padding-top: 0.2em;
padding-bottom: 0.4em;
}
.weather-forecast-icon {
icon-size: $base_icon_size * 2;
}
.weather-forecast-temp {
font-weight: bold;
}
}

View File

@@ -13,3 +13,12 @@ $ripple_size: 50px;
// just a simple change to the border radius position
&:rtl { border-radius: 0 0 0 $ripple_size + 2px; }
}
// Pointer location
.ripple-pointer-location {
width: $ripple_size;
height: $ripple_size;
border-radius: $ripple_size * 0.5; // radius equals the size of the box to give us the curve
background-color: lighten(transparentize($selected_bg_color, 0.7), 30%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
}

View File

@@ -9,11 +9,12 @@ $dash_border_radius: $modal_radius * 1.5;
@include fontsize($base_font_size - 2);
padding: ($dash_spacing / 2) 0;
//fixme: can't have non uniform borders :(
border-radius: 0 $dash_border_radius $dash_border_radius 0;
border-left-width: 0;
&:rtl {
border-left-width: 0 !important;
&:rtl {
border-radius: $dash_border_radius 0 0 $dash_border_radius;
border-right-width: 0;
border-right-width: 0 !important;
}
.placeholder {
@@ -48,13 +49,36 @@ $dash_border_radius: $modal_radius * 1.5;
// Show apps button
.show-apps {
@include overview-icon($osd_fg_color);
color: $osd_fg_color;
& .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
&:hover,
&:focus,
&:checked {
&:selected {
.overview-icon {
background-color: transparentize($osd_fg_color,0.9);
color: $osd_fg_color;
}
}
&:drop .overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
&:active, &:checked {
.overview-icon {
background-color: darken($osd_bg_color,10%);
}
}
&:checked, &:focus {
.show-apps-icon {
color: $fg_color;
transition-duration: 100ms;
}
}
}

View File

@@ -1,9 +1,5 @@
/* Modal Dialogs */
.headline {
@include fontsize($base_font_size + 1);
}
.modal-dialog {
border-radius: $modal_radius;
@extend %bubble_panel;
@@ -19,7 +15,12 @@
}
}
.mount-dialog-subject {
@include fontsize($base_font_size + 3);
}
/* End Session Dialog */
.end-session-dialog {
width: 30em;
@@ -37,11 +38,6 @@
text-align: center;
font-size: 18pt;
font-weight: 800;
&.leightweight {
font-size: 13pt;
font-weight: 800;
}
}
.message-dialog-description { text-align: center; }
}
@@ -88,58 +84,76 @@
/* Password or Authentication Dialog */
.prompt-dialog {
width: 28em;
//this is the width of the entire modal popup
width: 34em;
.modal-dialog-content-box {
margin-bottom: 24px;
}
.message-dialog-content { spacing: $base_spacing * 4; }
.message-dialog-title { color: lighten($fg_color,15%); }
}
.prompt-dialog-password-grid {
spacing-rows: 8px;
spacing-columns: 4px;
.prompt-dialog-password-entry {
width: auto;
// 4px (spacing) + 16px (spinner-width)
&:ltr { margin-left: 20px; }
&:rtl { margin-right: 20px; }
}
.prompt-dialog-description:rtl {
text-align: right;
}
.prompt-dialog-password-layout {
spacing: 8px;
}
.prompt-dialog-password-entry {
width: 20em;
}
.prompt-dialog-error-label,
.prompt-dialog-info-label,
.prompt-dialog-null-label {
text-align: center;
@include fontsize($base_font_size - 1);
.prompt-dialog-password-box {
spacing: 1em;
padding-bottom: 1em;
}
.prompt-dialog-error-label {
@include fontsize($base_font_size - 1);
color: $warning_color;
padding-bottom: 8px;
}
.prompt-dialog-info-label {
@include fontsize($base_font_size - 1);
padding-bottom: 8px;
}
.prompt-dialog-null-label {
@include fontsize($base_font_size - 1);
padding-bottom: 8px;
}
.prompt-dialog-pim-box {
spacing: 1em;
}
.prompt-dialog-grid {
spacing-rows: 15px;
spacing-columns: 1em;
}
.prompt-dialog-keyfiles-box {
spacing: 1em;
}
.prompt-dialog-button.button {
padding: 8px;
}
/* Polkit Dialog */
.polkit-dialog-user-layout {
text-align: center;
spacing: 8px;
margin-bottom: 6px;
.polkit-dialog-user-icon {
border-radius: 99px;
background-size: contain;
padding-left: 10px;
spacing: 10px;
&:rtl {
padding-left: 0px;
padding-right: 10px;
}
.polkit-dialog-user-root-label { color: $warning_color; }
}
.polkit-dialog-user-root-label {
color: $warning_color;
}
.polkit-dialog-user-icon {
border-radius: 99px;
background-size: contain;
width: 48px;
height: 48px;
}
/* Audio selection dialog */
@@ -166,3 +180,20 @@
.audio-selection-device-icon {
icon-size: $base_icon_size * 4;
}
/* Access Dialog */
.access-dialog {
spacing: 30px;
}
/* Network Agent Dialog */
.network-dialog-secret-table {
spacing-rows: 15px;
spacing-columns: 1em;
}
.keyring-dialog-control-table {
spacing-rows: 15px;
spacing-columns: 1em;
}

View File

@@ -1,9 +1,4 @@
// IBus Candidate Popup
.candidate-popup-boxpointer {
@extend .popup-menu-boxpointer;
}
.candidate-popup-content {
padding: 0.5em;
spacing: 0.3em;

View File

@@ -10,7 +10,7 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// draw keys using button function
#keyboard {
background-color: transparentize(if($variant=='light', darken($bg_color, 5%), darken($bg_color, 8%)), 0.1);
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color;
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color !important;
.page-indicator {
padding: $base_padding;
@@ -52,6 +52,10 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// non-character keys
&.default-key {
// size of the icon asset
background-size: 24px;
@include button(normal, $c:$default_key_bg_color);
&:hover, &:checked {@include button(hover, $c: $default_key_bg_color);}
&:active { @include button(active, $c: $default_key_bg_color);}
@@ -59,14 +63,19 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// enter key is suggested-action
&.enter-key {
background-image: url("resource:///org/gnome/shell/theme/key-enter.svg");
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
&:hover, &:checked { @include button(hover, $c: lighten($selected_bg_color, 3%));}
&:active {@include button(active, $c: darken($selected_bg_color, 2%));}
}
&.shift-key-uppercase { color: $selected_bg_color }
StIcon { icon-size: 1.125em; }
// key assets
&.shift-key-lowercase {background-image: url("resource:///org/gnome/shell/theme/key-shift.svg");}
&.shift-key-uppercase {background-image: url("resource:///org/gnome/shell/theme/key-shift-uppercase.svg");}
&.shift-key-uppercase:latched {background-image: url("resource:///org/gnome/shell/theme/key-shift-latched-uppercase.svg");}
&.hide-key {background-image: url("resource:///org/gnome/shell/theme/key-hide.svg");}
&.layout-key {background-image: url("resource:///org/gnome/shell/theme/key-layout.svg");}
}
// long press on a key popup
@@ -112,4 +121,4 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
@include fontsize($base_font_size + 3);
spacing: 12px;
min-height: 20pt;
}
}

View File

@@ -68,30 +68,12 @@
}
}
}
.cancel-button,
.switch-user-button,
.login-dialog-session-list-button {
padding: 0;
border-radius: 99px;
width: $base_icon_size * 2;
height: $base_icon_size * 2;
border-color: transparentize($bg_color,0.7);
background-color: transparentize($bg_color,0.7);
StIcon { icon-size: $base_icon_size; }
}
.caps-lock-warning-label,
.login-dialog-message-warning {
color: $osd_fg_color;
}
}
.login-dialog-logo-bin { padding: 24px 0px; }
.login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { width: 23em; spacing: 5px; }
.login-dialog-message { text-align: center; }
.login-dialog-button-box { spacing: 5px; }
.login-dialog-message-warning { color: $warning_color; }
.login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
.login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label {
@@ -118,7 +100,7 @@
}
.login-dialog-user-list-item {
border-radius: $base_border_radius + 4px;
border-radius: 5px;
padding: 6px;
color: darken($osd_fg_color,30%);
&:ltr .user-widget { padding-right: 1em; }
@@ -131,25 +113,18 @@
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
}
.login-dialog-username,
.user-widget-label {
color: $osd_fg_color;
}
.user-widget.horizontal .user-widget-label {
@include fontsize($base_font_size + 2);
font-weight: bold;
text-align: left;
padding-left: 15px;
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.user-widget.vertical .user-widget-label {
@include fontsize($base_font_size + 5);
text-align: center;
font-weight: normal;
padding-top: 16px;
.user-widget-label {
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.login-dialog-prompt-layout {
@@ -159,12 +134,18 @@
width: 23em;
}
.login-dialog-prompt-entry {
height: 1.5em;
}
.login-dialog-prompt-label {
color: darken($osd_fg_color, 20%);
@include fontsize($base_font_size + 1);
padding-top: 1em;
}
.login-dialog-session-list-button StIcon {
icon-size: 1.25em;
}
.login-dialog-session-list-button {
color: darken($osd_fg_color,30%);
&:hover,&:focus { color: $osd_fg_color; }
&:active { color: darken($osd_fg_color, 50%); }
}

View File

@@ -5,14 +5,14 @@
background-color: $osd_bg_color;
spacing: $base_spacing;
padding: 4px;
border: 1px solid transparentize($osd_fg_color, 0.8);
border-radius: $base_border_radius;
color: $osd_fg_color;
border: 2px solid transparentize($osd_fg_color, 0.8);
border-top-width:0;
border-radius: 0 0 $base_border_radius $base_border_radius;
& > #Toolbar {
border: none;
border-radius: $base_border_radius;
background-color: $osd_bg_color;
background-color: darken($osd_bg_color, 10%);
}
.labels { spacing: $base_spacing; }
@@ -20,18 +20,19 @@
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: 6px;
font-weight: bold;
color: darken($osd_fg_color, 15%);
color: $fg_color;
transition-duration: 100ms;
padding-left: .3em;
padding-right: .3em;
border-bottom-width: 2px;
&:hover {
color: $osd_fg_color;
color: white;
text-shadow: black 0px 2px 2px;
}
&:selected {
border-bottom-width: 2px;
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color, 5%);
color: $osd_fg_color;
border-color: lighten($selected_bg_color,5%);
color: white;
text-shadow: black 0px 2px 2px;
}
}
StBoxLayout#EvalBox { padding: 4px; spacing: $base_spacing; }
@@ -40,17 +41,12 @@
.lg-dialog {
StEntry {
background-color: transparentize(lighten($osd_bg_color, 5%), 0.4);
color: $osd_fg_color;
border-color: transparentize($osd_fg_color, 0.8);
min-height: 22px;
selection-background-color: $selected_bg_color;
selected-color: $selected_fg_color;
selection-background-color: #bbbbbb;
selected-color: $osd_bg_color;
}
.shell-link {
color: $link_color;
&:hover { color: lighten($link_color, 10%); }
&:active { color: darken($link_color, 10%); }
color: #999999;
&:hover { color: #dddddd; }
}
}
@@ -64,7 +60,7 @@
}
.lg-obj-inspector-button {
border: 1px solid $osd_borders_color;
border: 1px solid gray;
padding: 4px;
border-radius: $base_border_radius;
&:hover { border: 1px solid #ffffff; }
@@ -79,8 +75,7 @@
}
.lg-extension {
border: 1px solid lighten($osd_borders_color, 5%);
background-color: lighten($osd_bg_color, 5%);
border: 1px solid $osd_borders_color;
border-radius: $base_border_radius;
padding: 4px;
}

View File

@@ -11,7 +11,7 @@
.message-list-sections {
spacing: $base_spacing;
margin: 0 $base_margin * 4; // to account for scrollbar
margin: $base_margin * 4; // to account for scrollbar
}
.message-list-section,
@@ -19,61 +19,40 @@
spacing: $base_spacing;
}
.message-list-section-list {
&:ltr {padding:0;}
&:rtl {padding:0;}
}
// do-not-disturb + clear button
.message-list-controls {
margin: ($base_margin * 2) ($base_margin * 4) 0;
// NOTE: remove the padding if notification_bubble could remove margin for drop shadow
padding: $base_margin;
spacing: $base_spacing * 2;
margin: $base_margin $base_margin*2;
spacing: $base_spacing;
}
// message bubbles
.message {
@include notification_bubble;
@extend %notification_bubble;
// icon container
.message-icon-bin {
padding: ($base_padding * 3) 0 ($base_padding * 3) ($base_padding * 2);
&:rtl {
padding: ($base_padding * 3) ($base_padding * 2) ($base_padding * 3) 0;
}
// icon size and color
> StIcon {
icon-size: $base_icon_size*2; // 32px
-st-icon-style: symbolic;
}
// fallback
> .fallback-app-icon {
width: $base_icon_size;
height: $base_icon_size;
}
// title
.message-title {
color: $fg_color;
font-weight: bold;
margin-bottom:4px;
}
// content
.message-content {
padding: $base_padding + $base_margin * 2;
spacing: 4px;
}
// title
.message-title {
font-weight: bold;
}
// secondary container in title box
.message-secondary-bin {
padding: 0 $base_margin * 2;
// notification time stamp
> .event-time {
color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2);
text-align: right;
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: 0.13em;
color: darken($fg_color, 10%);
padding: $base_padding 0;
margin:$base_margin * 2;
&:ltr {
margin-left: $base_margin;
padding-right:$base_padding;
}
&:rtl {
margin-right: $base_margin;
padding-left:$base_padding;
}
}
@@ -84,15 +63,48 @@
&:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); }
}
// body
.message-body {
color: darken($fg_color, 10%);
}
}
// URLs in messages
.url-highlighter {
link-color: $link_color;
// icon container
.message-icon-bin {
padding: $base_padding;
margin:$base_padding 0;
&:rtl {
// padding: $base_padding;
}
// icon size and color
> StIcon {
color: $fg_color;
icon-size: $base_icon_size*2; // 32px
-st-icon-style: symbolic;
padding:0;
margin:$base_padding;
}
// fallback
> .fallback-app-icon {
width: $base_icon_size;
height: $base_icon_size;
}
}
// secondary container in title box
.message-secondary-bin {
padding: 0;
// notification time stamp
> .event-time {
color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2);
text-align: right;
margin: 0 $base_margin * 2;
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: $base_padding;
}
}
}
/* Media Controls */
@@ -113,9 +125,9 @@
&:insensitive { color: darken($fg_color,40%); }
// fix border-radius for last button
&:last-child:ltr { border-radius: 0 $base_border_radius+2 $base_border_radius+2 0; }
&:last-child:rtl { border-radius: $base_border_radius+2 0 0 $base_border_radius+2; }
// fix border-radius for last button on hover
&:last-child:ltr { &:hover {border-radius: 0 $base_border_radius+2 $base_border_radius+2 0;} }
&:last-child:rtl { &:hover {border-radius: $base_border_radius+2 0 0 $base_border_radius+2;} }
}
// album-art
@@ -130,5 +142,6 @@
border: 1px solid transparent;
border-radius: $base_border_radius;
icon-size: $base_icon_size * 2 !important;
padding: $base_padding * 2;
}
}

View File

@@ -1,9 +1,32 @@
// Links/URLs
.shell-link {
color: $link_color;
&:hover { color: lighten($link_color,10%); }
}
.url-highlighter { link-color: $link_color; }
// Rubberband for select-area screenshots
.select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color;
}
// Pointer accessibility notifications
.pie-timer {
width: 60px;
height: 60px;
-pie-border-width: 3px;
-pie-border-color: $selected_bg_color;
-pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
}
// Screen zoom/Magnifier
.magnifier-zoom-region {
border: 2px solid $selected_bg_color;
&.full-screen { border-width: 0; }
}
// User icon
.user-icon {
background-size: contain;
@@ -12,33 +35,22 @@
&:hover {
color: lighten($osd_fg_color,30%);
}
& StIcon {
background-color: transparentize($osd_fg_color,0.95);
border-radius: 99px;
}
}
.user-widget.vertical .user-icon {
icon-size: $base_icon_size * 6; // 128px
& StIcon {
padding: $base_padding * 3 + 2px; // 20px
padding-top: $base_padding * 3; // 18 px
padding-bottom: $base_padding * 3 + 4px; // 22px
width: $base_icon_size * 5.5; height: $base_icon_size * 5.5; // 88px;
}
// Input Source Switcher
.input-source-switcher-symbol {
font-size: 34pt;
width: 96px;
height: 96px;
}
.user-widget.horizontal .user-icon {
icon-size: $base_icon_size * 4; // 64px
& StIcon {
padding: $base_padding * 2 ; // 12px
width: $base_icon_size * 2.5; height: $base_icon_size * 2.5; // 40px;
}
// Window cycler highlight
.cycler-highlight {
border: 5px solid $selected_bg_color;
}
// Text
.headline { @include fontsize($base_font_size + 1); }
.lightbox { background-color: black; }
.flashspot { background-color: white; }
@@ -48,8 +60,8 @@
// Caps-lock warning
.caps-lock-warning-label {
text-align: center;
padding-bottom: 8px;
padding-left: 6.2em;
@include fontsize($base_font_size - 1);
color: $warning_color;
}

View File

@@ -7,8 +7,39 @@ $notification_banner_width: 34em;
.notification-banner {
min-height: $notification_banner_height;
width: $notification_banner_width;
@include fontsize($base_font_size);
margin: $base_margin;
border-radius: $modal_radius;
.message-title { color: $fg_color }
.message-content { color: $fg_color; }
&:hover { background: $bg_color; }
&, &:focus, &:active {
background-color: $bg_color;
.message-title { color: $fg_color }
.message-content { color: $fg_color; }
}
// icon
.message-icon-bin > StIcon {
icon-size: $base_icon_size * 2;
color: $fg_color;
}
.notification-icon {
padding: 5px;
}
.notification-content {
padding: 5px;
spacing: 5px;
}
.secondary-icon { icon-size: $base_icon_size; }
.notification-actions {
padding-top: 0;
spacing: 0;
}
@@ -32,6 +63,8 @@ $notification_banner_width: 34em;
border-radius: 0.9em; // should be 0.8 but whatever; wish I could do 50%;
}
.secondary-icon { icon-size: $base_icon_size; }
// chat bubbles
.chat-body { spacing: 5px; }
.chat-response { margin: 5px; }
@@ -54,4 +87,4 @@ $notification_banner_width: 34em;
font-weight: bold;
color: lighten($fg_color,18%);
&:rtl { padding-left: 0; padding-right: 4px; }
}
}

View File

@@ -2,8 +2,8 @@
// a.k.a. the panel
$panel_corner_radius: $base_border_radius+1;
$panel_bg_color: #000;
$panel_fg_color: #ccc;
$panel_bg_color: if($variant == 'light', rgba(0,0,0,0.9), #000);
$panel_fg_color: if($variant == 'light', darken($fg_color, 15%), darken($fg_color, 10%));
$panel_height: 1.86em;
@@ -15,7 +15,8 @@ $panel_height: 1.86em;
// transparent panel on lock & login screens
&.unlock-screen,
&.login-screen {
&.login-screen,
&.lock-screen {
background-color: transparent;
.panel-corner {
@@ -54,6 +55,9 @@ $panel_height: 1.86em;
}
&:active, &:overview, &:focus, &:checked {
background-color: $panel_bg_color; // Trick due to St limitations. It needs a background to draw a box-shadow
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
color: lighten($panel_fg_color, 20%);
}
@@ -73,32 +77,13 @@ $panel_height: 1.86em;
// lock & login screen styles
.unlock-screen &,
.login-screen & {
.login-screen &,
.lock-screen & {
color: lighten($fg_color, 10%);
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
}
}
.panel-button {
&:active, &:overview, &:focus, &:checked {
// Trick due to St limitations. It needs a background to draw a box-shadow
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
}
}
.panel-button.clock-display {
// Move highlight from .panel-button to .clock
&:active, &:overview, &:focus, &:checked {
box-shadow: none;
.clock {
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
}
}
}
.panel-status-indicators-box,
.panel-status-menu-box {
spacing: 2px;

View File

@@ -3,7 +3,8 @@
$popover_arrow_height: 12px;
//.the popover itself
.popup-menu-boxpointer {
.popup-menu-boxpointer,
.candidate-popup-boxpointer {
-arrow-border-radius: $base_border_radius+4;
-arrow-background-color: $bg_color;
-arrow-border-width: 1px;
@@ -82,20 +83,11 @@ $popover_arrow_height: 12px;
// separator
.popup-separator-menu-item {
padding: 0;
.popup-separator-menu-item-separator {
//-margin-horizontal: 24px;
height: 1px; //not really the whole box
margin: 6px 64px;
background-color: lighten($borders_color, 2%);
.popup-sub-menu & { //submenu separators
margin: 0 64px 0 32px;
@if $variant == 'dark' {
background-color: lighten($bg_color,10%);
}
}
}
//-margin-horizontal: 24px;
height: 1px; //not really the whole box
margin: 6px 64px;
background-color: lighten($borders_color, 2%);
border: none !important;
}
// desktop background menu
@@ -126,4 +118,4 @@ $popover_arrow_height: 12px;
margin-right: $base_icon_size;
}
}
}
}

View File

@@ -1,64 +1,68 @@
/* Screen Shield */
.unlock-dialog-clock {
color: white;
font-weight: 300;
text-align: center;
spacing: 24px;
padding-bottom: 2.5em;
$_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
.screen-shield-arrows {
padding-bottom: 3em;
}
.unlock-dialog-clock-time {
font-size: 64pt;
padding-top: 42px;
.screen-shield-arrows Gjs_Arrow {
color: white;
width: 80px;
height: 48px;
-arrow-thickness: 12px;
-arrow-shadow: $_screenshield_shadow;
}
.screen-shield-clock {
color: white;
text-shadow: $_screenshield_shadow;
font-weight: bold;
text-align: center;
padding-bottom: 1.5em;
}
.screen-shield-clock-time {
font-size: 72pt;
text-shadow: $_screenshield_shadow;
font-feature-settings: "tnum";
}
.unlock-dialog-clock-date {
font-size: 16pt;
.screen-shield-clock-date {
font-size: 28pt;
font-weight: normal;
}
.unlock-dialog-clock-hint {
font-weight: normal;
padding-top: 48px;
}
.unlock-dialog-notifications-container {
margin: 12px 0;
.screen-shield-notifications-container {
spacing: 6px;
width: 23em;
width: 30em;
background-color: transparent;
max-height: 500px;
.summary-notification-stack-scrollview {
padding-top: 0;
padding-bottom: 0;
}
.notification,
.unlock-dialog-notification-source {
.screen-shield-notification-source {
padding: 12px 6px;
border: none;
background-color: transparentize($osd_bg_color,0.7);
border: 1px solid $osd_outer_borders_color;
background-color: transparentize($osd_bg_color,0.5);
color: $osd_fg_color;
border-radius: $modal_radius;
&.critical { background-color: transparentize($osd_bg_color,0.1) }
border-radius: 4px;
}
.notification { margin-right: 15px; } //compensate for space allocated to the scrollbar
}
.unlock-dialog-notification-label {
.screen-shield-notification-label {
font-weight: bold;
padding: 0px 0px 0px 12px;
}
.unlock-dialog-notification-count-text {
weight: bold;
padding: 0 6px;
color: $osd_bg_color;
background-color: transparentize($osd_fg_color, 0.7);
border-radius: 99px;
margin-right: 12px;
.screen-shield-notification-count-text { padding: 0px 0px 0px 12px; }
}
#panel.lock-screen { background-color: transparentize($osd_bg_color, 0.5); }
.screen-shield-background { //just the shadow, really
background: black;
@@ -66,13 +70,14 @@
}
#lockDialogGroup {
background-color: lighten(#2e3436, 8%);
background: lighten(#2e3436, 8%) url(resource:///org/gnome/shell/theme/noise-texture.png);
background-repeat: repeat;
}
#unlockDialogNotifications {
#screenShieldNotifications {
StButton#vhandle, StButton#hhandle {
background-color: transparentize($bg_color,0.7);
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
&:active { background-color: transparentize($selected_bg_color,0.5); }
}
}
}

View File

@@ -3,16 +3,19 @@
// search overview container
#searchResultsContent {
max-width: 1024px;
spacing: $base_margin * 2;
}
// search results sections "the boxes"
.search-section {
// This should be equal to #searchResultsContent spacing
spacing: $base_margin * 2;
padding:0 !important;
margin:0 !important;
background-color:transparent;
box-shadow:none;
border:none;
// separator
.search-section-separator {
// margin-top: $base_padding * 2;
// height: 1px;
// background-color: $osd_outer_borders_color;
height: 0;
@@ -29,24 +32,8 @@
text-shadow: 0 1px if($variant == 'light', rgba(255,255,255,0.2), rgba(0,0,0,0.2));
color: $osd_fg_color;
padding: $base_padding * 3;
// This is the space between the provider icon and the results container
spacing: $base_margin * 2;
}
%search-section-content-item {
@extend %icon_tile;
&:focus,
&:hover,
&:selected {
background-color: transparentize($osd_fg_color, .9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color, 10%), .1);
}
margin: $base_margin 0;
spacing: 0;
}
// "no results" text
@@ -56,12 +43,54 @@
// Search results with icons
.grid-search-result {
@extend %app-well-app;
> .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
> .overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
spacing: $base_spacing;
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_bg_color,0.8);
color: $osd_fg_color;
}
}
&:drop .overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
&:active .overview-icon,
&:checked .overview-icon {
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
}
}
// search result provider
.search-provider-icon {
@extend %search-section-content-item;
@extend %icon_tile;
padding: $base_padding;
spacing: 0;
margin-right: $base_margin * 2;
&:focus,
&:selected,
&:hover {
background-color: transparentize($osd_fg_color,.9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color,10%),.1);
}
// content
.list-search-provider-content {
@@ -84,16 +113,34 @@
// search result listitem
.list-search-result {
@extend %search-section-content-item;
@extend %icon_tile;
spacing: 0;
padding: $base_padding;
color: $osd_fg_color;
border-radius: $base_border_radius + 2px !important;
&:focus,
&:selected,
&:hover {
background-color: transparentize($osd_fg_color,.9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color,10%),.1);
}
// content
.list-search-result-content {
spacing: $base_padding;
spacing: 0;
}
// list item title (with leading icon)
// list item title
.list-search-result-title {
color: $osd_fg_color;
spacing: $base_spacing * 2;
padding-right: $base_padding;
// font-weight: bold;
}

View File

@@ -1,7 +1,7 @@
/* Window Picker */
$window_picker_spacing: $base_spacing * 2; // 16px
$window_picker_padding: $base_padding * 2; // 16px
$window_picker_spacing: $base_spacing * 8; // 48px
$window_picker_padding: $base_padding * 10; // 60px
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
@@ -63,4 +63,4 @@ $window_close_button_padding: 3px;
&:active {
background-color: darken($selected_bg_color, 5%);
}
}
}

View File

@@ -16,6 +16,7 @@
}
.ws-switcher-box {
// background: transparent;
background: transparent;
height: 50px;
background-size: 32px;
@@ -28,9 +29,44 @@
.ws-switcher-active-down,
.ws-switcher-active-left,
.ws-switcher-active-right {
height: 52px;
background-color: $selected_bg_color;
border: 1px solid if($variant=='light', darken($selected_bg_color, 8%), lighten($selected_bg_color, 5%));
border-radius: $base_border_radius + 3px;
color: $selected_fg_color;
}
/* Workspace pager */
// thumbnails in overview
.workspace-thumbnails {
@extend %overview_panel;
visible-width: 32px; //amount visible before hover
spacing: $base_spacing;
padding: $base_padding;
border-radius: $modal_radius 0 0 $modal_radius;
border-right-width: 0 !important;
//fixme: can't have non uniform borders :(
border-top-left-radius:0 !important;
border-bottom-left-radius:0 !important;
&:rtl {
border-radius: 0 $modal_radius $modal_radius 0;
border-left-width: 0 !important;
}
// drag and drop indicator
.placeholder {
background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
background-size: contain;
height: 24px;
}
}
// selected indicator
.workspace-thumbnail-indicator {
border: 3px solid $selected_bg_color;
border-radius: 3px;
padding: 0px;
// background-color: transparentize($selected_bg_color, 0.9);
}

View File

@@ -1,32 +0,0 @@
/* Workspace pager */
// thumbnails in overview
.workspace-thumbnails {
@extend %overview_panel;
visible-width: 32px; //amount visible before hover
spacing: $base_spacing;
padding: $base_padding;
border-radius: $modal_radius 0 0 $modal_radius;
border-right-width: 0;
&:rtl {
border-radius: 0 $modal_radius $modal_radius 0;
border-left-width: 0;
}
// drag and drop indicator
.placeholder {
background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
background-size: contain;
height: 24px;
}
}
// selected indicator
.workspace-thumbnail-indicator {
border: 3px solid $selected_bg_color;
border-radius: 3px;
padding: 0px;
// background-color: transparentize($selected_bg_color, 0.9);
}

4
data/theme/key-enter.svg Normal file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" class="keyboard-key" width="24" height="24">
<path overflow="visible" font-weight="400" style="line-height:normal;-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration-line:none;text-transform:none;marker:none" d="M10 23H8.5c-.398 0-.796-.14-1.079-.422L.345 15.5l7.078-7.078C7.704 8.14 8.102 8 8.5 8H10v1.5c0 .398-.14.796-.422 1.079L4.657 15.5l4.921 4.922c.282.282.422.68.422 1.078z" color="#000" font-family="Bitstream Vera Sans" fill="#fff"/>
<path overflow="visible" d="M22 1.5v9a5 5 0 01-5 5H4" style="marker:none" color="#000" fill="none" stroke="#fff" stroke-width="3"/>
</svg>

After

Width:  |  Height:  |  Size: 676 B

3
data/theme/key-hide.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M12 20.875L.562 9.438C.171 9.046 0 8.51 0 8V6h2c.511 0 1.046.17 1.438.563L12 15.125l8.563-8.562C20.953 6.17 21.488 6 22 6h2v2c0 .511-.17 1.046-.563 1.438z" fill="#e5e5e5"/>
</svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" class="keyboard-key" width="24" height="24">
<path d="M4.5 2v21" fill="#e5e5e5" fill-rule="evenodd" stroke="#e5e5e5" stroke-width="3"/>
<path d="M4 12h6l2 4h8V6h-6l-2-4H4z" fill="none" stroke="#e5e5e5" stroke-width="2" stroke-linejoin="round"/>
<path d="M4 12h6l2 4h8V6h-6l-2-4H4z" fill="#e5e5e5" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 378 B

View File

@@ -0,0 +1,3 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path style="marker:none" d="M12 0L2 12h6v6h8v-6h6zM8 21v3h8v-3z" color="#000" overflow="visible" fill="#3584e4"/>
</svg>

After

Width:  |  Height:  |  Size: 211 B

View File

@@ -0,0 +1,3 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M8 22v-8H2L12 2l10 12h-6v8z" style="marker:none" color="#000" overflow="visible" fill="#3584e4"/>
</svg>

After

Width:  |  Height:  |  Size: 203 B

3
data/theme/key-shift.svg Normal file
View File

@@ -0,0 +1,3 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M8 22v-8H2L12 2l10 12h-6v8z" style="marker:none" color="#000" overflow="visible" fill="#bebebe"/>
</svg>

After

Width:  |  Height:  |  Size: 203 B

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g fill="#2e3436">
<path d="M6 8H2.937l5.126-5.781L13.186 8H10v2H6z" style="marker:none" color="#000" overflow="visible"/>
<path d="M6 11h4v2H6z" style="marker:none"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 268 B

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g font-weight="400" fill="#2e3436">
<path d="M11.994 3v4.004c.002.666-.183.72-.445.852-.262.13-.555.144-.555.144H4v2h6.994s.71.014 1.45-.355c.738-.37 1.552-1.313 1.55-2.645V3z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none" color="#000" font-family="sans-serif" overflow="visible"/>
<path d="M6 12v-1c0-.257-.13-.528-.313-.719l-1.28-1.303 1.28-1.26C5.87 7.529 6 7.258 6 7V6H5c-.31 0-.552.09-.75.281L1.594 8.978l2.656 2.74c.198.192.44.282.75.282z" style="line-height:normal;-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration-line:none;text-transform:none;marker:none" color="#bebebe" font-family="Bitstream Vera Sans" overflow="visible"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g color="#000" fill="#2e3436">
<path d="M4.707 5.293L3.293 6.707 8 11.414l4.707-4.707-1.414-1.414L8 8.586z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none" font-weight="400" font-family="sans-serif" overflow="visible"/>
<path d="M12 6V5h1v1zM3 6V5h1v1z" style="marker:none" overflow="visible"/>
<path d="M3 6c0-.554.446-1 1-1s1 .446 1 1-.446 1-1 1-1-.446-1-1zM11 6c0-.554.446-1 1-1s1 .446 1 1-.446 1-1 1-1-.446-1-1z" style="marker:none" overflow="visible"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 990 B

View File

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g fill="#2e3436" fill-rule="evenodd">
<path d="M2 1v14h2V1z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" color="#000" font-weight="400" font-family="sans-serif" overflow="visible"/>
<path d="M3 1a1 1 0 00-1 1v6a1 1 0 001 1h3.383l.722 1.447A1 1 0 008 11h5a1 1 0 001-1V4a1 1 0 00-1-1H9.617l-.722-1.447A1 1 0 008 1zm1 2h3.383l.722 1.447A1 1 0 009 5h3v4H8.617l-.722-1.447A1 1 0 007 7H4z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" color="#000" font-weight="400" font-family="sans-serif" overflow="visible"/>
<path d="M3 8h4l1 2h5V4H9L8 2H3z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<path d="M6 13V9H2.937l5.126-5.781L13.186 9H10v4z" style="marker:none" color="#000" overflow="visible" fill="#2e3436"/>
</svg>

Before

Width:  |  Height:  |  Size: 195 B

View File

@@ -6,9 +6,8 @@ theme_sources = files([
'gnome-shell-sass/_drawing.scss',
'gnome-shell-sass/_high-contrast-colors.scss',
'gnome-shell-sass/_widgets.scss',
'gnome-shell-sass/widgets/_a11y.scss',
'gnome-shell-sass/widgets/_app-grid.scss',
'gnome-shell-sass/widgets/_base.scss',
'gnome-shell-sass/widgets/_app-switcher.scss',
'gnome-shell-sass/widgets/_buttons.scss',
'gnome-shell-sass/widgets/_calendar.scss',
'gnome-shell-sass/widgets/_check-box.scss',
@@ -34,12 +33,10 @@ theme_sources = files([
'gnome-shell-sass/widgets/_search-entry.scss',
'gnome-shell-sass/widgets/_search-results.scss',
'gnome-shell-sass/widgets/_slider.scss',
'gnome-shell-sass/widgets/_switcher-popup.scss',
'gnome-shell-sass/widgets/_switches.scss',
'gnome-shell-sass/widgets/_tiled-previews.scss',
'gnome-shell-sass/widgets/_window-picker.scss',
'gnome-shell-sass/widgets/_workspace-switcher.scss',
'gnome-shell-sass/widgets/_workspace-thumbnails.scss'
'gnome-shell-sass/widgets/_workspace-switcher.scss'
])
styles = [

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="22"><defs><linearGradient id="a"><stop offset="0" stop-color="#39393a"/><stop offset="1" stop-color="#302f30"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="53" y1="294.429" x2="53" y2="309.804" gradientUnits="userSpaceOnUse" gradientTransform="translate(-42.76)"/></defs><g transform="translate(0 -291.18)" stroke-width="1.085" stroke="#151515"><rect style="marker:none" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#282828"/><rect ry="10.455" rx="10.455" y="291.715" x=".543" height="20.911" width="21.143" style="marker:none" fill="url(#b)"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="22"><defs><linearGradient id="a"><stop offset="0" stop-color="#39393a"/><stop offset="1" stop-color="#302f30"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="53" y1="294.429" x2="53" y2="309.804" gradientUnits="userSpaceOnUse" gradientTransform="translate(-42.76)"/></defs><g transform="translate(0 -291.18)" stroke-width="1.085"><rect style="marker:none" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#323233" stroke="#272728"/><rect ry="10.455" rx="10.455" y="291.715" x=".543" height="20.911" width="21.143" style="marker:none" fill="url(#b)" stroke="#151515"/></g></svg>

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 725 B

View File

@@ -1,11 +0,0 @@
.details-button image {
transition: 250ms;
}
.details-button.expanded:dir(ltr) image {
-gtk-icon-transform: rotate(0.25turn);
}
.details-button.expanded:dir(rtl) image {
-gtk-icon-transform: rotate(-0.25turn);
}
image.warning { color: @warning_color; }

View File

@@ -3,16 +3,15 @@ imports.gi.versions.Gdk = '3.0';
imports.gi.versions.Gtk = '3.0';
const Gettext = imports.gettext;
const { Gdk, GLib, Gio, GObject, Gtk } = imports.gi;
const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
const Format = imports.format;
const _ = Gettext.gettext;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils;
const { ExtensionState, ExtensionType } = ExtensionUtils;
const { ExtensionState } = ExtensionUtils;
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions');
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
@@ -28,144 +27,26 @@ class Application extends Gtk.Application {
_init() {
GLib.set_prgname('gnome-shell-extension-prefs');
super._init({
application_id: 'org.gnome.Extensions',
application_id: 'org.gnome.shell.ExtensionPrefs',
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
});
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
this._shellProxy = null;
}
get shellProxy() {
return this._shellProxy;
}
vfunc_activate() {
this._shellProxy.CheckForUpdatesRemote();
this._window.present();
}
vfunc_startup() {
super.vfunc_startup();
let provider = new Gtk.CssProvider();
let uri = 'resource:///org/gnome/shell/css/application.css';
try {
provider.load_from_file(Gio.File.new_for_uri(uri));
} catch (e) {
logError(e, 'Failed to add application style');
}
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._window = new ExtensionsWindow({ application: this });
}
vfunc_command_line(commandLine) {
let args = commandLine.get_arguments();
if (args.length) {
let uuid = args[0];
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, 'extension:///');
this._window.openPrefs(uuid);
} else {
this.activate();
}
return 0;
}
});
var ExtensionsWindow = GObject.registerClass({
GTypeName: 'ExtensionsWindow',
Template: 'resource:///org/gnome/shell/ui/extensions-window.ui',
InternalChildren: [
'userList',
'systemList',
'killSwitch',
'mainBox',
'mainStack',
'scrolledWindow',
'updatesBar',
'updatesLabel',
],
}, class ExtensionsWindow extends Gtk.ApplicationWindow {
_init(params) {
super._init(params);
this._startupUuid = null;
this._loaded = false;
this._prefsDialog = null;
this._updatesCheckId = 0;
this._mainBox.set_focus_vadjustment(this._scrolledWindow.vadjustment);
let action;
action = new Gio.SimpleAction({ name: 'show-about' });
action.connect('activate', this._showAbout.bind(this));
this.add_action(action);
action = new Gio.SimpleAction({ name: 'logout' });
action.connect('activate', this._logout.bind(this));
this.add_action(action);
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
this._settings.bind('disable-user-extensions',
this._killSwitch, 'active',
Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._userList.set_sort_func(this._sortList.bind(this));
this._userList.set_header_func(this._updateHeader.bind(this));
this._systemList.set_sort_func(this._sortList.bind(this));
this._systemList.set_header_func(this._updateHeader.bind(this));
this._shellProxy.connectSignal('ExtensionStateChanged',
this._onExtensionStateChanged.bind(this));
this._scanExtensions();
}
get _shellProxy() {
return this.application.shellProxy;
}
uninstall(uuid) {
let row = this._findExtensionRow(uuid);
let dialog = new Gtk.MessageDialog({
transient_for: this,
modal: true,
text: _('Remove “%s”?').format(row.name),
secondary_text: _('If you remove the extension, you need to return to download it if you want to enable it again'),
});
dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL);
dialog.add_button(_('Remove'), Gtk.ResponseType.ACCEPT)
.get_style_context().add_class('destructive-action');
dialog.connect('response', (dlg, response) => {
if (response === Gtk.ResponseType.ACCEPT)
this._shellProxy.UninstallExtensionRemote(uuid);
dialog.destroy();
});
dialog.present();
}
openPrefs(uuid) {
if (!this._loaded)
this._startupUuid = uuid;
else if (!this._showPrefs(uuid))
this.present();
}
_showPrefs(uuid) {
if (this._prefsDialog)
return false;
let row = this._extensionSelector.get_children().find(c => {
return c.uuid === uuid && c.hasPrefs;
});
let row = this._findExtensionRow(uuid);
if (!row || !row.hasPrefs)
if (!row)
return false;
let widget;
@@ -176,73 +57,33 @@ var ExtensionsWindow = GObject.registerClass({
widget = this._buildErrorUI(row, e);
}
this._prefsDialog = new Gtk.Window({
application: this.application,
default_width: 600,
default_height: 400,
modal: this.visible,
let dialog = new Gtk.Window({
modal: !this._skipMainWindow,
type_hint: Gdk.WindowTypeHint.DIALOG,
window_position: Gtk.WindowPosition.CENTER,
});
this._prefsDialog.set_titlebar(new Gtk.HeaderBar({
dialog.set_titlebar(new Gtk.HeaderBar({
show_close_button: true,
title: row.name,
visible: true,
}));
if (this.visible)
this._prefsDialog.transient_for = this;
if (this._skipMainWindow) {
this.add_window(dialog);
if (this._window)
this._window.destroy();
this._window = dialog;
this._window.window_position = Gtk.WindowPosition.CENTER;
} else {
dialog.transient_for = this._window;
}
this._prefsDialog.connect('destroy', () => {
this._prefsDialog = null;
if (!this.visible)
this.destroy();
});
this._prefsDialog.add(widget);
this._prefsDialog.show();
dialog.set_default_size(600, 400);
dialog.add(widget);
dialog.show();
return true;
}
_showAbout() {
let aboutDialog = new Gtk.AboutDialog({
authors: [
'Florian Müllner <fmuellner@gnome.org>',
'Jasper St. Pierre <jstpierre@mecheye.net>',
'Didier Roche <didrocks@ubuntu.com>',
],
translator_credits: _('translator-credits'),
program_name: _('Extensions'),
comments: _('Manage your GNOME Extensions'),
license_type: Gtk.License.GPL_2_0,
logo_icon_name: 'org.gnome.Extensions',
version: Config.PACKAGE_VERSION,
transient_for: this,
modal: true,
});
aboutDialog.present();
}
_logout() {
this.application.get_dbus_connection().call(
'org.gnome.SessionManager',
'/org/gnome/SessionManager',
'org.gnome.SessionManager',
'Logout',
new GLib.Variant('(u)', [0]),
null,
Gio.DBusCallFlags.NONE,
-1,
null,
(o, res) => {
o.call_finish(res);
});
}
_buildErrorUI(row, exc) {
let scroll = new Gtk.ScrolledWindow({
hscrollbar_policy: Gtk.PolicyType.NEVER,
@@ -277,10 +118,10 @@ var ExtensionsWindow = GObject.registerClass({
});
box.add(expander);
let errortext = '%s\n\nStack trace:\n'.format(exc);
// Indent stack trace.
errortext +=
exc.stack.split('\n').map(line => ' %s'.format(line)).join('\n');
let errortext = `${exc}\n\nStack trace:\n${
// Indent stack trace.
exc.stack.split('\n').map(line => ` ${line}`).join('\n')
}`;
let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({
@@ -315,9 +156,9 @@ var ExtensionsWindow = GObject.registerClass({
let clipboard = Gtk.Clipboard.get_default(w.get_display());
// markdown for pasting in gitlab issues
let lines = [
'The settings of extension %s had an error:'.format(row.uuid),
`The settings of extension ${row.uuid} had an error:`,
'```', // '`' (xgettext throws up on odd number of backticks)
exc.toString(),
`${exc}`,
'```', // '`'
'',
'Stack trace:',
@@ -337,7 +178,7 @@ var ExtensionsWindow = GObject.registerClass({
label: _("Homepage"),
tooltip_text: _("Visit extension homepage"),
no_show_all: true,
visible: row.url !== '',
visible: row.url != null,
});
toolbar.add(urlButton);
@@ -358,6 +199,47 @@ var ExtensionsWindow = GObject.registerClass({
return scroll;
}
_buildUI() {
this._window = new Gtk.ApplicationWindow({ application: this,
window_position: Gtk.WindowPosition.CENTER });
this._window.set_default_size(800, 500);
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
title: _("Shell Extensions") });
this._window.set_titlebar(this._titlebar);
let killSwitch = new Gtk.Switch({ valign: Gtk.Align.CENTER });
this._titlebar.pack_end(killSwitch);
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
this._settings.bind('disable-user-extensions', killSwitch, 'active',
Gio.SettingsBindFlags.DEFAULT |
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._mainStack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE,
});
this._window.add(this._mainStack);
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
this._extensionSelector.set_sort_func(this._sortList.bind(this));
this._extensionSelector.set_header_func(this._updateHeader.bind(this));
scroll.add(this._extensionSelector);
this._mainStack.add_named(scroll, 'listing');
this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder');
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._shellProxy.connectSignal('ExtensionStateChanged',
this._onExtensionStateChanged.bind(this));
this._window.show_all();
}
_sortList(row1, row2) {
return row1.name.localeCompare(row2.name);
}
@@ -371,26 +253,13 @@ var ExtensionsWindow = GObject.registerClass({
}
_findExtensionRow(uuid) {
return [
...this._userList.get_children(),
...this._systemList.get_children(),
].find(c => c.uuid === uuid);
return this._extensionSelector.get_children().find(c => c.uuid === uuid);
}
_onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
let extension = ExtensionUtils.deserializeExtension(newState);
let row = this._findExtensionRow(uuid);
this._queueUpdatesCheck();
// the extension's type changed; remove the corresponding row
// and reset the variable to null so that we create a new row
// below and add it to the appropriate list
if (row && row.type !== extension.type) {
row.destroy();
row = null;
}
if (row) {
if (extension.state === ExtensionState.UNINSTALLED)
row.destroy();
@@ -403,7 +272,8 @@ var ExtensionsWindow = GObject.registerClass({
this._shellProxy.ListExtensionsRemote(([extensionsMap], e) => {
if (e) {
if (e instanceof Gio.DBusError) {
log('Failed to connect to shell proxy: %s'.format(e.toString()));
log(`Failed to connect to shell proxy: ${e}`);
this._mainStack.add_named(new NoShellPlaceholder(), 'noshell');
this._mainStack.visible_child_name = 'noshell';
} else {
throw e;
@@ -421,53 +291,58 @@ var ExtensionsWindow = GObject.registerClass({
_addExtensionRow(extension) {
let row = new ExtensionRow(extension);
row.prefsButton.connect('clicked', () => {
this._showPrefs(row.uuid);
});
row.show_all();
if (row.type === ExtensionType.PER_USER)
this._userList.add(row);
else
this._systemList.add(row);
}
_queueUpdatesCheck() {
if (this._updatesCheckId)
return;
this._updatesCheckId = GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT, 1, () => {
this._checkUpdates();
this._updatesCheckId = 0;
return GLib.SOURCE_REMOVE;
});
}
_checkUpdates() {
let nUpdates = this._userList.get_children().filter(c => c.hasUpdate).length;
this._updatesLabel.label = Gettext.ngettext(
'%d extension will be updated on next login.',
'%d extensions will be updated on next login.',
nUpdates).format(nUpdates);
this._updatesBar.visible = nUpdates > 0;
this._extensionSelector.add(row);
}
_extensionsLoaded() {
this._userList.visible = this._userList.get_children().length > 0;
this._systemList.visible = this._systemList.get_children().length > 0;
if (this._userList.visible || this._systemList.visible)
this._mainStack.visible_child_name = 'main';
if (this._extensionSelector.get_children().length > 0)
this._mainStack.visible_child_name = 'listing';
else
this._mainStack.visible_child_name = 'placeholder';
this._checkUpdates();
if (this._startupUuid)
this._showPrefs(this._startupUuid);
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
}
vfunc_activate() {
this._window.present();
}
vfunc_startup() {
super.vfunc_startup();
this._buildUI();
this._scanExtensions();
}
vfunc_command_line(commandLine) {
this.activate();
let args = commandLine.get_arguments();
if (args.length) {
let uuid = args[0];
this._skipMainWindow = true;
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, "extension:///");
if (!this._loaded)
this._startupUuid = uuid;
else if (!this._showPrefs(uuid))
this._skipMainWindow = false;
}
return 0;
}
});
var Expander = GObject.registerClass({
@@ -569,19 +444,113 @@ var Expander = GObject.registerClass({
}
});
var ExtensionRow = GObject.registerClass({
GTypeName: 'ExtensionRow',
Template: 'resource:///org/gnome/shell/ui/extension-row.ui',
InternalChildren: [
'nameLabel',
'descriptionLabel',
'versionLabel',
'authorLabel',
'updatesIcon',
'revealButton',
'revealer',
],
}, class ExtensionRow extends Gtk.ListBoxRow {
var EmptyPlaceholder = GObject.registerClass(
class EmptyPlaceholder extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 6,
margin: 32,
});
let image = new Gtk.Image({
icon_name: 'application-x-addon-symbolic',
pixel_size: 96,
visible: true,
vexpand: true,
valign: Gtk.Align.END,
});
image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(image);
let label = new Gtk.Label({
label: `<b><span size="x-large">${_("No Extensions Installed")}</span></b>`,
use_markup: true,
visible: true,
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop');
let desc = new Gtk.Label({
label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."),
use_markup: true,
wrap: true,
justify: Gtk.Justification.CENTER,
visible: true,
max_width_chars: 50,
hexpand: true,
vexpand: appInfo == null,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
});
this.add(desc);
if (appInfo) {
let button = new Gtk.Button({
label: _("Browse in Software"),
image: new Gtk.Image({
icon_name: "org.gnome.Software-symbolic",
}),
always_show_image: true,
margin_top: 12,
visible: true,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
vexpand: true,
});
this.add(button);
button.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
appInfo.launch([], context);
});
}
}
});
var NoShellPlaceholder = GObject.registerClass(
class NoShellPlaceholder extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 12,
margin: 100,
margin_bottom: 60,
});
let label = new Gtk.Label({
label: '<span size="x-large">%s</span>'.format(
_("Somethings gone wrong")),
use_markup: true,
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
label = new Gtk.Label({
label: _("Were very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again."),
justify: Gtk.Justification.CENTER,
wrap: true,
});
this.add(label);
this.show_all();
}
});
var DescriptionLabel = GObject.registerClass(
class DescriptionLabel extends Gtk.Label {
vfunc_get_preferred_height_for_width(width) {
// Hack: Request the maximum height allowed by the line limit
if (this.lines > 0)
return super.vfunc_get_preferred_height_for_width(0);
return super.vfunc_get_preferred_height_for_width(width);
}
});
var ExtensionRow = GObject.registerClass(
class ExtensionRow extends Gtk.ListBoxRow {
_init(extension) {
super._init();
@@ -589,77 +558,24 @@ var ExtensionRow = GObject.registerClass({
this._extension = extension;
this._prefsModule = null;
this._actionGroup = new Gio.SimpleActionGroup();
this.insert_action_group('row', this._actionGroup);
let action;
action = new Gio.SimpleAction({
name: 'show-prefs',
enabled: this.hasPrefs,
});
action.connect('activate', () => this.get_toplevel().openPrefs(this.uuid));
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'show-url',
enabled: this.url !== '',
});
action.connect('activate', () => {
Gio.AppInfo.launch_default_for_uri(
this.url, this.get_display().get_app_launch_context());
});
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'uninstall',
enabled: this.type === ExtensionType.PER_USER,
});
action.connect('activate', () => this.get_toplevel().uninstall(this.uuid));
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'enabled',
state: new GLib.Variant('b', false),
});
action.connect('activate', () => {
let state = action.get_state();
action.change_state(new GLib.Variant('b', !state.get_boolean()));
});
action.connect('change-state', (a, state) => {
if (state.get_boolean())
this._app.shellProxy.EnableExtensionRemote(this.uuid);
else
this._app.shellProxy.DisableExtensionRemote(this.uuid);
});
this._actionGroup.add_action(action);
let name = GLib.markup_escape_text(this.name, -1);
this._nameLabel.label = name;
let desc = this._extension.metadata.description.split('\n')[0];
this._descriptionLabel.label = desc;
this._revealButton.connect('clicked', () => {
this._revealer.reveal_child = !this._revealer.reveal_child;
});
this._revealer.connect('notify::reveal-child', () => {
if (this._revealer.reveal_child)
this._revealButton.get_style_context().add_class('expanded');
else
this._revealButton.get_style_context().remove_class('expanded');
});
this.connect('destroy', this._onDestroy.bind(this));
this._buildUI();
this._extensionStateChangedId = this._app.shellProxy.connectSignal(
'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
if (this.uuid !== uuid)
return;
this._extension = ExtensionUtils.deserializeExtension(newState);
this._updateState();
let state = this._extension.state == ExtensionState.ENABLED;
this._switch.block_signal_handler(this._notifyActiveId);
this._switch.state = state;
this._switch.unblock_signal_handler(this._notifyActiveId);
this._switch.sensitive = this._canToggle();
});
this._updateState();
}
get uuid() {
@@ -674,40 +590,8 @@ var ExtensionRow = GObject.registerClass({
return this._extension.hasPrefs;
}
get hasUpdate() {
return this._extension.hasUpdate || false;
}
get type() {
return this._extension.type;
}
get creator() {
return this._extension.metadata.creator || '';
}
get url() {
return this._extension.metadata.url || '';
}
get version() {
return this._extension.metadata.version || '';
}
_updateState() {
let state = this._extension.state === ExtensionState.ENABLED;
let action = this._actionGroup.lookup('enabled');
action.set_state(new GLib.Variant('b', state));
action.enabled = this._canToggle();
this._updatesIcon.visible = this.hasUpdate;
this._versionLabel.label = this.version.toString();
this._versionLabel.visible = this.version !== '';
this._authorLabel.label = this.creator.toString();
this._authorLabel.visible = this.creator !== '';
return this._extension.metadata.url;
}
_onDestroy() {
@@ -719,6 +603,54 @@ var ExtensionRow = GObject.registerClass({
this._extensionStateChangedId = 0;
}
_buildUI() {
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
hexpand: true, margin_end: 24, spacing: 24,
margin: 12 });
this.add(hbox);
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
spacing: 6, hexpand: true });
hbox.add(vbox);
let name = GLib.markup_escape_text(this.name, -1);
let label = new Gtk.Label({ label: '<b>' + name + '</b>',
use_markup: true,
halign: Gtk.Align.START });
vbox.add(label);
let desc = this._extension.metadata.description.split('\n')[0];
label = new DescriptionLabel({ label: desc, wrap: true, lines: 2,
ellipsize: Pango.EllipsizeMode.END,
xalign: 0, yalign: 0 });
vbox.add(label);
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
visible: this.hasPrefs,
no_show_all: true });
button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.get_style_context().add_class('circular');
hbox.add(button);
this.prefsButton = button;
this._switch = new Gtk.Switch({
valign: Gtk.Align.CENTER,
sensitive: this._canToggle(),
state: this._extension.state === ExtensionState.ENABLED,
});
this._notifyActiveId = this._switch.connect('notify::active', () => {
if (this._switch.active)
this._app.shellProxy.EnableExtensionRemote(this.uuid);
else
this._app.shellProxy.DisableExtensionRemote(this.uuid);
});
this._switch.connect('state-set', () => true);
hbox.add(this._switch);
}
_canToggle() {
return this._extension.canChange;
}
@@ -747,7 +679,7 @@ function initEnvironment() {
},
logError(s) {
log('ERROR: %s'.format(s));
log(`ERROR: ${s}`);
},
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell']),

View File

@@ -1,218 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ExtensionRow" parent="GtkListBoxRow">
<property name="visible">True</property>
<property name="activatable">False</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="nameLabel">
<property name="visible">True</property>
</object>
</child>
<child>
<object class="GtkImage" id="updatesIcon">
<property name="no_show_all">True</property>
<property name="icon_name">software-update-available-symbolic</property>
<style>
<class name="warning"/>>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="prefsButton">
<property name="no_show_all">True</property>
<property name="visible"
bind-source="prefsButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<property name="action-name">row.show-prefs</property>
<style>
<class name="circular"/>>
<class name="image-button"/>>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSwitch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
<property name="action-name">row.enabled</property>
</object>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="revealButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<style>
<class name="details-button"/>
<class name="image-button"/>
<class name="flat"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">pan-end-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="margin_top">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Description</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="descriptionLabel">
<property name="visible">True</property>
<property name="ellipsize">end</property>
<property name="max_width_chars">60</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="versionLabel"
bind-property="visible"
bind-flags="sync-create"/>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Version</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="versionLabel">
<property name="no_show_all">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="authorLabel"
bind-property="visible"
bind-flags="sync-create"/>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Author</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="authorLabel">
<property name="no_show_all">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="label" translatable="yes">Website</property>
<property name="action_name">row.show-url</property>
<property name="valign">end</property>
<property name="margin-top">12</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="removeButton">
<property name="visible"
bind-source="removeButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Remove…</property>
<property name="action_name">row.uninstall</property>
<property name="hexpand">True</property>
<property name="halign">end</property>
<property name="valign">end</property>
<style>
<class name="destructive-action"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">7</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,305 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<menu id="primary-menu">
<section>
<item>
<attribute name="label" translatable="yes">Help</attribute>
<attribute name="action">win.show-help</attribute>
</item>
<item>
<attribute name="label" translatable="yes">About Extensions</attribute>
<attribute name="action">win.show-about</attribute>
</item>
</section>
</menu>
<object class="GtkPopover" id="infoPopover">
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">To find and add extensions, visit &lt;a href="https://extensions.gnome.org"&gt;extensions.gnome.org&lt;/a&gt;.</property>
<property name="use_markup">True</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Warning</property>
<property name="xalign">0</property>
<property name="margin_top">6</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Extensions can cause system issues, including performance problems. If you encounter problems with your system, it is recommended to disable all extensions.</property>
<property name="wrap">True</property>
<property name="max_width_chars">40</property>
<property name="xalign">0</property>
</object>
</child>
</object>
</child>
</object>
<template class="ExtensionsWindow" parent="GtkApplicationWindow">
<property name="default_width">800</property>
<property name="default_height">500</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="title" translatable="yes">Extensions</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkMenuButton">
<property name="visible">True</property>
<property name="popover">infoPopover</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">dialog-information-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton" id="menuButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="menu_model">primary-menu</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">open-menu-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="killSwitch">
<property name="visible">True</property>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="mainStack">
<property name="visible">True</property>
<property name="transition_type">crossfade</property>
<property name="vexpand">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledWindow">
<property name="visible">True</property>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<child>
<object class="GtkBox" id="mainBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="halign">center</property>
<property name="margin">36</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="userList"
bind-property="visible"
bind-flags="sync-create"/>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Manually Installed</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkListBox" id="userList">
<property name="visible">True</property>
<property name="selection_mode">none</property>
<property name="margin_bottom">24</property>
<style>
<class name="frame"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="systemList"
bind-property="visible"
bind-flags="sync-create"/>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Built-In</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkListBox" id="systemList">
<property name="visible">True</property>
<property name="selection_mode">none</property>
<style>
<class name="frame"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="name">main</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin">32</property>
<property name="spacing">6</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="pixel_size">96</property>
<property name="icon_name">org.gnome.Extensions-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">No Installed Extensions</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.44"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="name">placeholder</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin_left">100</property>
<property name="margin_right">100</property>
<property name="margin_top">100</property>
<property name="margin_bottom">60</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Somethings gone wrong</property>
<attributes>
<attribute name="scale" value="1.44"/>
</attributes>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Were very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
<packing>
<property name="name">noshell</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkActionBar" id="updatesBar">
<property name="no_show_all">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="pixel-size">24</property>
<property name="margin">6</property>
<property name="icon_name">software-update-available-symbolic</property>
<style>
<class name="warning"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="halign">start</property>
<property name="label">Extension Updates Ready</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="updatesLabel">
<property name="visible">True</property>
<property name="halign">start</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Log Out…</property>
<property name="visible">True</property>
<property name="valign">center</property>
<property name="action-name">win.logout</property>
<property name="receives_default">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -17,6 +17,10 @@ var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
const WIGGLE_OFFSET = 6;
const WIGGLE_DURATION = 65;
const N_WIGGLES = 3;
var AuthPromptMode = {
UNLOCK_ONLY: 0,
UNLOCK_OR_LOG_IN: 1,
@@ -47,15 +51,12 @@ var AuthPrompt = GObject.registerClass({
super._init({
style_class: 'login-dialog-prompt-layout',
vertical: true,
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
});
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient;
this._mode = mode;
this._defaultButtonWellActor = null;
let reauthenticationOnly;
if (this._mode == AuthPromptMode.UNLOCK_ONLY)
@@ -74,6 +75,15 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
this.smartcardDetected = this._userVerifier.smartcardDetected;
this.connect('next', () => {
this.updateSensitivity(false);
this.startSpinning();
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
else
this._preemptiveAnswer = this._entry.text;
});
this.connect('destroy', this._onDestroy.bind(this));
this._userWell = new St.Bin({
@@ -81,35 +91,67 @@ var AuthPrompt = GObject.registerClass({
y_expand: true,
});
this.add_child(this._userWell);
this._hasCancelButton = this._mode === AuthPromptMode.UNLOCK_OR_LOG_IN;
this._initEntryRow();
let capsLockPlaceholder = new St.Label();
this.add_child(capsLockPlaceholder);
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning({
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
this._label = new St.Label({
style_class: 'login-dialog-prompt-label',
x_expand: false,
y_expand: true,
});
this.add_child(this._capsLockWarningLabel);
this._capsLockWarningLabel.bind_property('visible',
capsLockPlaceholder, 'visible',
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN);
this.add_child(this._label);
let entryParams = {
style_class: 'login-dialog-prompt-entry',
can_focus: true,
x_expand: false,
y_expand: true,
};
this._entry = null;
this._textEntry = new St.Entry(entryParams);
ShellEntry.addContextMenu(this._textEntry, { actionMode: Shell.ActionMode.NONE });
this._passwordEntry = new St.PasswordEntry(entryParams);
ShellEntry.addContextMenu(this._passwordEntry, { actionMode: Shell.ActionMode.NONE });
this._entry = this._passwordEntry;
this.add_child(this._entry);
this._entry.grab_key_focus();
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
this.add_child(this._capsLockWarningLabel);
this._message = new St.Label({
opacity: 0,
styleClass: 'login-dialog-message',
x_expand: false,
y_expand: true,
x_expand: true,
y_align: Clutter.ActorAlign.START,
x_align: Clutter.ActorAlign.CENTER,
});
this._message.clutter_text.line_wrap = true;
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.add_child(this._message);
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() {
@@ -123,95 +165,54 @@ var AuthPrompt = GObject.registerClass({
return Clutter.EVENT_PROPAGATE;
}
_initEntryRow() {
this._mainBox = new St.BoxLayout({
style_class: 'login-dialog-button-box',
vertical: false,
});
this.add_child(this._mainBox);
_initButtons() {
this.cancelButton = new St.Button({
style_class: 'modal-dialog-button button cancel-button',
accessible_name: _('Cancel'),
style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: this._hasCancelButton,
can_focus: this._hasCancelButton,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER,
child: new St.Icon({ icon_name: 'go-previous-symbolic' }),
});
if (this._hasCancelButton)
this.cancelButton.connect('clicked', () => this.cancel());
else
this.cancelButton.opacity = 0;
this._mainBox.add_child(this.cancelButton);
let entryParams = {
style_class: 'login-dialog-prompt-entry',
reactive: true,
can_focus: true,
label: _("Cancel"),
x_expand: true,
};
this._entry = null;
this._textEntry = new St.Entry(entryParams);
ShellEntry.addContextMenu(this._textEntry, { actionMode: Shell.ActionMode.NONE });
this._passwordEntry = new St.PasswordEntry(entryParams);
ShellEntry.addContextMenu(this._passwordEntry, { actionMode: Shell.ActionMode.NONE });
this._entry = this._passwordEntry;
this._mainBox.add_child(this._entry);
this._entry.grab_key_focus();
[this._textEntry, this._passwordEntry].forEach(entry => {
entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages)
this._fadeOutMessage();
});
entry.clutter_text.connect('activate', () => {
let shouldSpin = entry === this._passwordEntry;
if (entry.reactive)
this._activateNext(shouldSpin);
});
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END,
});
this.cancelButton.connect('clicked', () => this.cancel());
this._buttonBox.add_child(this.cancelButton);
this._defaultButtonWell = new St.Widget({
layout_manager: new Clutter.BinLayout(),
this._buttonBox.add_child(this._defaultButtonWell);
this.nextButton = new St.Button({
style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Next"),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END,
});
this._defaultButtonWell.add_constraint(new Clutter.BindConstraint({
source: this.cancelButton,
coordinate: Clutter.BindCoordinate.SIZE,
}));
this._mainBox.add_child(this._defaultButtonWell);
this.nextButton.connect('clicked', () => this.emit('next'));
this.nextButton.add_style_pseudo_class('default');
this._buttonBox.add_child(this.nextButton);
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
this._defaultButtonWell.add_child(this._spinner);
}
this._updateNextButtonSensitivity(this._entry.text.length > 0);
_activateNext(shouldSpin) {
this.updateSensitivity(false);
this._entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages)
this._fadeOutMessage();
if (shouldSpin)
this.startSpinning();
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
else
this._preemptiveAnswer = this._entry.text;
this.emit('next');
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
});
this._entry.clutter_text.connect('activate', () => {
if (this.nextButton.reactive)
this.emit('next');
});
}
_updateEntry(secret) {
if (secret && this._entry !== this._passwordEntry) {
this._mainBox.replace_child(this._entry, this._passwordEntry);
if (secret && (this._entry != this._passwordEntry)) {
this.replace_child(this._entry, this._passwordEntry);
this._entry = this._passwordEntry;
} else if (!secret && this._entry !== this._textEntry) {
this._mainBox.replace_child(this._entry, this._textEntry);
} else if (!secret && (this._entry != this._textEntry)) {
this.replace_child(this._entry, this._textEntry);
this._entry = this._textEntry;
}
this._capsLockWarningLabel.visible = secret;
@@ -229,14 +230,16 @@ var AuthPrompt = GObject.registerClass({
}
this._updateEntry(secret);
this.setQuestion(question);
// Hack: The question string comes directly from PAM, if it's "Password:"
// we replace it with our own to allow localization, if it's something
// else we remove the last colon and any trailing or leading spaces.
if (question === 'Password:' || question === 'Password: ')
this.setQuestion(_('Password'));
else
this.setQuestion(question.replace(/: *$/, '').trim());
if (secret) {
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.emit('prompted');
@@ -279,14 +282,17 @@ var AuthPrompt = GObject.registerClass({
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
Util.wiggle(this._entry);
Util.wiggle(this._entry, {
offset: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES,
});
}
_onVerificationComplete() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
this.cancelButton.can_focus = false;
}
_onReset() {
@@ -294,6 +300,10 @@ var AuthPrompt = GObject.registerClass({
this.reset();
}
addActorToDefaultButtonWell(actor) {
this._defaultButtonWell.add_child(actor);
}
setActorInDefaultButtonWell(actor, animate) {
if (!this._defaultButtonWellActor &&
!actor)
@@ -373,9 +383,11 @@ var AuthPrompt = GObject.registerClass({
}
setQuestion(question) {
this._entry.hint_text = question;
this._label.set_text(question);
this._label.show();
this._entry.show();
this._entry.grab_key_focus();
}
@@ -423,7 +435,13 @@ var AuthPrompt = GObject.registerClass({
}
}
_updateNextButtonSensitivity(sensitive) {
this.nextButton.reactive = sensitive;
this.nextButton.can_focus = sensitive;
}
updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
}
@@ -444,18 +462,18 @@ var AuthPrompt = GObject.registerClass({
if (oldChild)
oldChild.destroy();
let userWidget = new UserWidget.UserWidget(user, Clutter.Orientation.VERTICAL);
this._userWell.set_child(userWidget);
if (!user)
this._updateEntry(false);
if (user) {
let userWidget = new UserWidget.UserWidget(user);
userWidget.x_align = Clutter.ActorAlign.START;
this._userWell.set_child(userWidget);
}
}
reset() {
let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = this._hasCancelButton;
this.cancelButton.can_focus = this._hasCancelButton;
this.cancelButton.reactive = true;
this.nextButton.label = _("Next");
this._preemptiveAnswer = null;
if (this._userVerifier)
@@ -465,7 +483,6 @@ var AuthPrompt = GObject.registerClass({
this.clear();
this._message.opacity = 0;
this.setUser(null);
this._updateEntry(true);
this.stopSpinning();
if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED)

View File

@@ -36,6 +36,7 @@ const _FADE_ANIMATION_TIME = 250;
const _SCROLL_ANIMATION_TIME = 500;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = GObject.registerClass({
Signals: { 'activate': {} },
@@ -311,21 +312,28 @@ var SessionMenuButton = GObject.registerClass({
_init() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
let button = new St.Button({
style_class: 'modal-dialog-button button login-dialog-session-list-button',
style_class: 'login-dialog-session-list-button',
reactive: true,
track_hover: true,
can_focus: true,
accessible_name: _("Choose Session"),
accessible_role: Atk.Role.MENU,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
child: gearIcon,
});
super._init({ child: button });
this._button = button;
this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.BOTTOM);
let side = St.Side.TOP;
let align = 0;
if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
if (this.text_direction == Clutter.TextDirection.RTL)
side = St.Side.RIGHT;
else
side = St.Side.LEFT;
align = 0.5;
}
this._menu = new PopupMenu.PopupMenu(this._button, align, side);
Main.uiGroup.add_actor(this._menu.actor);
this._menu.actor.hide();
@@ -350,7 +358,6 @@ var SessionMenuButton = GObject.registerClass({
updateSensitivity(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
this.opacity = sensitive ? 255 : 0;
this._menu.close(BoxPointer.PopupAnimation.NONE);
}
@@ -402,10 +409,7 @@ var SessionMenuButton = GObject.registerClass({
});
var LoginDialog = GObject.registerClass({
Signals: {
'failed': {},
'wake-up-screen': {},
},
Signals: { 'failed': {} },
}, class LoginDialog extends St.Widget {
_init(parentActor) {
super._init({ style_class: 'login-dialog', visible: false });
@@ -421,13 +425,13 @@ var LoginDialog = GObject.registerClass({
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::%s'.format(GdmUtil.BANNER_MESSAGE_KEY),
this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_KEY}`,
this._updateBanner.bind(this));
this._settings.connect('changed::%s'.format(GdmUtil.BANNER_MESSAGE_TEXT_KEY),
this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_TEXT_KEY}`,
this._updateBanner.bind(this));
this._settings.connect('changed::%s'.format(GdmUtil.DISABLE_USER_LIST_KEY),
this._settings.connect(`changed::${GdmUtil.DISABLE_USER_LIST_KEY}`,
this._updateDisableUserList.bind(this));
this._settings.connect('changed::%s'.format(GdmUtil.LOGO_KEY),
this._settings.connect(`changed::${GdmUtil.LOGO_KEY}`,
this._updateLogo.bind(this));
this._textureCache = St.TextureCache.get_default();
@@ -488,15 +492,6 @@ var LoginDialog = GObject.registerClass({
bannerBox.add_child(this._bannerLabel);
this._updateBanner();
this._sessionMenuButton = new SessionMenuButton();
this._sessionMenuButton.connect('session-activated',
(list, sessionId) => {
this._greeter.call_select_session_sync(sessionId, null);
});
this._sessionMenuButton.opacity = 0;
this._sessionMenuButton.show();
this.add_child(this._sessionMenuButton);
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END });
@@ -510,6 +505,16 @@ var LoginDialog = GObject.registerClass({
this._onUserListActivated(item);
});
this._sessionMenuButton = new SessionMenuButton();
this._sessionMenuButton.connect('session-activated',
(list, sessionId) => {
this._greeter.call_select_session_sync(sessionId, null);
});
this._sessionMenuButton.opacity = 0;
this._sessionMenuButton.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton);
this._disableUserList = undefined;
this._userListLoaded = false;
@@ -554,23 +559,6 @@ var LoginDialog = GObject.registerClass({
return actorBox;
}
_getSessionMenuButtonAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
let [, , natWidth, natHeight] = this._sessionMenuButton.get_preferred_size();
if (this.get_text_direction() === Clutter.TextDirection.RTL)
actorBox.x1 = dialogBox.x1 + natWidth;
else
actorBox.x1 = dialogBox.x2 - (natWidth * 2);
actorBox.y1 = dialogBox.y2 - (natHeight * 2);
actorBox.x2 = actorBox.x1 + natWidth;
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
_getCenterActorAllocation(dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
@@ -627,10 +615,6 @@ var LoginDialog = GObject.registerClass({
logoHeight = logoAllocation.y2 - logoAllocation.y1;
}
let sessionMenuButtonAllocation = null;
if (this._sessionMenuButton.visible)
sessionMenuButtonAllocation = this._getSessionMenuButtonAllocation(dialogBox);
// Then figure out if we're overly constrained and need to
// try a different layout, or if we have what extra space we
// can hand out
@@ -729,9 +713,6 @@ var LoginDialog = GObject.registerClass({
if (logoAllocation)
this._logoBin.allocate(logoAllocation, flags);
if (sessionMenuButtonAllocation)
this._sessionMenuButton.allocate(sessionMenuButtonAllocation, flags);
}
_ensureUserListLoaded() {
@@ -827,10 +808,12 @@ var LoginDialog = GObject.registerClass({
}
_onPrompted() {
const showSessionMenu = this._shouldShowSessionMenuButton();
this._sessionMenuButton.updateSensitivity(showSessionMenu);
this._sessionMenuButton.visible = showSessionMenu;
if (this._shouldShowSessionMenuButton()) {
this._sessionMenuButton.updateSensitivity(true);
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton);
} else {
this._sessionMenuButton.updateSensitivity(false);
}
this._showPrompt();
}
@@ -913,8 +896,7 @@ var LoginDialog = GObject.registerClass({
}
_askForUsernameAndBeginVerification() {
this._authPrompt.setUser(null);
this._authPrompt.setQuestion(_('Username'));
this._authPrompt.setQuestion(_("Username: "));
this._showRealmLoginHint(this._realmManager.loginFormat);
@@ -928,6 +910,7 @@ var LoginDialog = GObject.registerClass({
let answer = this._authPrompt.getAnswer();
this._user = this._userManager.get_user(answer);
this._authPrompt.clear();
this._authPrompt.startSpinning();
this._authPrompt.begin({ userName: answer });
this._updateCancelButton();
});
@@ -1139,7 +1122,6 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.hide();
this._hideBannerView();
this._sessionMenuButton.close();
this._sessionMenuButton.hide();
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.grab_key_focus();
@@ -1243,18 +1225,13 @@ var LoginDialog = GObject.registerClass({
return GLib.SOURCE_REMOVE;
}
activate() {
this._userList.grab_key_focus();
this.show();
}
open() {
Main.ctrlAltTabManager.addGroup(this,
_("Login Window"),
'dialog-password-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
this.activate();
this._userList.grab_key_focus();
this.show();
this.opacity = 0;
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });

View File

@@ -109,7 +109,6 @@
<file>ui/windowMenu.js</file>
<file>ui/windowManager.js</file>
<file>ui/workspace.js</file>
<file>ui/workspaceAnimation.js</file>
<file>ui/workspaceSwitcherPopup.js</file>
<file>ui/workspaceThumbnail.js</file>
<file>ui/workspacesView.js</file>

View File

@@ -1,12 +1,10 @@
/* exported IntrospectService */
const { Gio, GLib, Meta, Shell, St } = imports.gi;
const { Gio, GLib, Meta, Shell } = imports.gi;
const INTROSPECT_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect';
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const INTROSPECT_DBUS_API_VERSION = 2;
const { loadInterfaceXML } = imports.misc.fileUtils;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
@@ -24,7 +22,6 @@ var IntrospectService = class {
this._runningApplicationsDirty = true;
this._activeApplication = null;
this._activeApplicationDirty = true;
this._animationsEnabled = true;
this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('app-state-changed',
@@ -33,9 +30,7 @@ var IntrospectService = class {
this._syncRunningApplications();
});
this._introspectSettings = new Gio.Settings({
schema_id: INTROSPECT_SCHEMA,
});
this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app',
@@ -54,11 +49,6 @@ var IntrospectService = class {
(conn, name, owner) => this._whitelistMap.set(name, owner),
(conn, name) => this._whitelistMap.delete(name));
});
this._settings = St.Settings.get();
this._settings.connect('notify::enable-animations',
this._syncAnimationsEnabled.bind(this));
this._syncAnimationsEnabled();
}
_isStandaloneApp(app) {
@@ -66,7 +56,7 @@ var IntrospectService = class {
}
_isIntrospectEnabled() {
return this._introspectSettings.get_boolean(INTROSPECT_KEY);
return this._settings.get_boolean(INTROSPECT_KEY);
}
_isSenderWhitelisted(sender) {
@@ -129,18 +119,9 @@ var IntrospectService = class {
type == Meta.WindowType.UTILITY;
}
_isInvocationAllowed(invocation) {
if (this._isIntrospectEnabled())
return true;
if (this._isSenderWhitelisted(invocation.get_sender()))
return true;
return false;
}
GetRunningApplicationsAsync(params, invocation) {
if (!this._isInvocationAllowed(invocation)) {
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
@@ -155,7 +136,8 @@ var IntrospectService = class {
let apps = this._appSystem.get_running();
let windowsList = {};
if (!this._isInvocationAllowed(invocation)) {
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
@@ -199,21 +181,4 @@ var IntrospectService = class {
}
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
}
_syncAnimationsEnabled() {
let wasAnimationsEnabled = this._animationsEnabled;
this._animationsEnabled = this._settings.enable_animations;
if (wasAnimationsEnabled !== this._animationsEnabled) {
let variant = new GLib.Variant('b', this._animationsEnabled);
this._dbusImpl.emit_property_changed('AnimationsEnabled', variant);
}
}
get AnimationsEnabled() {
return this._animationsEnabled;
}
get version() {
return INTROSPECT_DBUS_API_VERSION;
}
};

View File

@@ -151,17 +151,17 @@ const SystemActions = GObject.registerClass({
this._userManager.connect('user-removed',
() => this._updateMultiUser());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_USER_SWITCH_KEY),
this._lockdownSettings.connect(`changed::${DISABLE_USER_SWITCH_KEY}`,
() => this._updateSwitchUser());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOG_OUT_KEY),
this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
() => this._updateLogout());
global.settings.connect('changed::%s'.format(ALWAYS_SHOW_LOG_OUT_KEY),
global.settings.connect(`changed::${ALWAYS_SHOW_LOG_OUT_KEY}`,
() => this._updateLogout());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOCK_SCREEN_KEY),
this._lockdownSettings.connect(`changed::${DISABLE_LOCK_SCREEN_KEY}`,
() => this._updateLockScreen());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOG_OUT_KEY),
this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
() => this._updateHaveShutdown());
this.forceUpdate();

View File

@@ -11,17 +11,13 @@ const Params = imports.misc.params;
var SCROLL_TIME = 100;
const WIGGLE_OFFSET = 6;
const WIGGLE_DURATION = 65;
const N_WIGGLES = 3;
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
const _balancedParens = '\\([^\\s()<>]+\\)';
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u200E\u200F\u201C\u201D\u2018\u2019\u202A\u202C]';
const _urlRegexp = new RegExp(
'(^|%s)'.format(_leadingJunk) +
`(^|${_leadingJunk})` +
'(' +
'(?:' +
'(?:http|https|ftp)://' + // scheme://
@@ -33,12 +29,12 @@ const _urlRegexp = new RegExp(
'(?:' + // one or more:
'[^\\s()<>]+' + // run of non-space non-()
'|' + // or
'%s'.format(_balancedParens) + // balanced parens
`${_balancedParens}` + // balanced parens
')+' +
'(?:' + // end with:
'%s'.format(_balancedParens) + // balanced parens
`${_balancedParens}` + // balanced parens
'|' + // or
'%s'.format(_notTrailingJunk) + // last non-junk char
`${_notTrailingJunk}` + // last non-junk char
')' +
')', 'gi');
@@ -153,7 +149,7 @@ function trySpawnCommandLine(commandLine) {
} catch (err) {
// Replace "Error invoking GLib.shell_parse_argv: " with
// something nicer
err.message = err.message.replace(/[^:]*: /, '%s\n'.format(_('Could not parse command:')));
err.message = err.message.replace(/[^:]*: /, `${_("Could not parse command:")}\n`);
throw err;
}
@@ -445,13 +441,10 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
}
function wiggle(actor, params) {
if (!St.Settings.get().enable_animations)
return;
params = Params.parse(params, {
offset: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES,
offset: 0,
duration: 0,
wiggleCount: 0,
});
actor.translation_x = 0;

View File

@@ -1,6 +1,4 @@
/* exported main */
imports.gi.versions.Gtk = '3.0';
const Format = imports.format;
const Gettext = imports.gettext;
const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi;
@@ -23,6 +21,7 @@ const PortalHelperSecurityLevel = {
};
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
const CONNECTIVITY_CHECK_URI = `http://${CONNECTIVITY_CHECK_HOST}`;
const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
@@ -102,7 +101,7 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._headerBar.show();
if (!url) {
url = 'http://%s'.format(CONNECTIVITY_CHECK_HOST);
url = CONNECTIVITY_CHECK_URI;
this._originalUrlWasGnome = true;
} else {
this._originalUrlWasGnome = false;
@@ -117,10 +116,6 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._webContext = WebKit.WebContext.new_ephemeral();
this._webContext.set_cache_model(WebKit.CacheModel.DOCUMENT_VIEWER);
this._webContext.set_network_proxy_settings(WebKit.NetworkProxyMode.NO_PROXY, null);
if (this._webContext.set_sandbox_enabled) {
// We have WebKitGTK 2.26 or newer.
this._webContext.set_sandbox_enabled(true);
}
this._webView = WebKit.WebView.new_with_context(this._webContext);
this._webView.connect('decide-policy', this._onDecidePolicy.bind(this));

View File

@@ -7,10 +7,5 @@
<file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file>
<file>misc/params.js</file>
<file alias="css/application.css">extensionPrefs/css/application.css</file>
<file alias="ui/extension-row.ui">extensionPrefs/ui/extension-row.ui</file>
<file alias="ui/extensions-window.ui">extensionPrefs/ui/extensions-window.ui</file>
</gresource>
</gresources>

View File

@@ -138,7 +138,7 @@ var AccessDialogDBus = class {
let [handle, appId, parentWindow_, title, description, body, options] = params;
// We probably want to use parentWindow and global.display.focus_window
// for this check in the future
if (appId && '%s.desktop'.format(appId) != this._windowTracker.focus_app.id) {
if (appId && `${appId}.desktop` != this._windowTracker.focus_app.id) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'Only the focused app is allowed to show a system access dialog');

View File

@@ -72,7 +72,7 @@ function _getFolderName(folder) {
if (folder.get_boolean('translate')) {
let keyfile = new GLib.KeyFile();
let path = 'desktop-directories/%s'.format(name);
let path = `desktop-directories/${name}`;
try {
keyfile.load_from_data_dirs(path, GLib.KeyFileFlags.NONE);
@@ -219,7 +219,7 @@ var BaseAppView = GObject.registerClass({
if (this._items.has(id))
this._items.get(id).navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
else
log('No such application %s'.format(id));
log(`No such application ${id}`);
}
selectApp(id) {
@@ -293,7 +293,7 @@ var BaseAppView = GObject.registerClass({
}
adaptToSize(_width, _height) {
throw new GObject.NotImplementedError('adaptToSize in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`adaptToSize in ${this.constructor.name}`);
}
});
@@ -492,7 +492,7 @@ var AllView = GObject.registerClass({
let folders = this._folderSettings.get_strv('folder-children');
folders.forEach(id => {
let path = '%sfolders/%s/'.format(this._folderSettings.path, id);
let path = `${this._folderSettings.path}folders/${id}/`;
let icon = this._items.get(id);
if (!icon) {
icon = new FolderIcon(id, path, this);
@@ -530,10 +530,8 @@ var AllView = GObject.registerClass({
// Overridden from BaseAppView
animate(animationDirection, onComplete) {
this._scrollView.reactive = false;
this._swipeTracker.enabled = false;
let completionFunc = () => {
this._scrollView.reactive = true;
this._swipeTracker.enabled = this.mapped;
if (onComplete)
onComplete();
};
@@ -1525,10 +1523,10 @@ var FolderIcon = GObject.registerClass({
}
vfunc_unmap() {
super.vfunc_unmap();
if (this._dialog)
this._dialog.popdown();
super.vfunc_unmap();
}
open() {
@@ -1657,6 +1655,10 @@ var AppFolderDialog = GObject.registerClass({
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
});
this.add_constraint(new Clutter.BindConstraint({
source: Main.overview.viewSelector,
coordinate: Clutter.BindCoordinate.ALL,
}));
this._source = source;
this._folder = folder;
@@ -2274,7 +2276,7 @@ var AppIcon = GObject.registerClass({
shellWorkspaceLaunch(params) {
let { stack } = new Error();
log('shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n%s'.format(stack));
log(`shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n${stack}`);
params = Params.parse(params, { workspace: -1,
timestamp: 0 });

View File

@@ -66,7 +66,7 @@ class AppFavorites {
constructor() {
this.FAVORITE_APPS_KEY = 'favorite-apps';
this._favorites = {};
global.settings.connect('changed::%s'.format(this.FAVORITE_APPS_KEY), this._onFavsChanged.bind(this));
global.settings.connect(`changed::${this.FAVORITE_APPS_KEY}`, this._onFavsChanged.bind(this));
this.reload();
}

View File

@@ -120,7 +120,7 @@ var AudioDeviceSelectionDialog = GObject.registerClass({
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log('Settings panel for desktop file %s could not be loaded!'.format(desktopFile));
log(`Settings panel for desktop file ${desktopFile} could not be loaded!`);
return;
}

View File

@@ -504,9 +504,12 @@ var SystemBackground = GObject.registerClass({
Signals: { 'loaded': {} },
}, class SystemBackground extends Meta.BackgroundActor {
_init() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
_systemBackground = new Meta.Background({ meta_display: global.display });
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
}
super._init({
@@ -515,11 +518,22 @@ var SystemBackground = GObject.registerClass({
background: _systemBackground,
});
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.emit('loaded');
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
let cache = Meta.BackgroundImageCache.get_default();
let image = cache.load(file);
if (image.is_loaded()) {
image = null;
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.emit('loaded');
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
} else {
let id = image.connect('loaded', () => {
this.emit('loaded');
image.disconnect(id);
image = null;
});
}
}
});

View File

@@ -18,7 +18,7 @@ var ELLIPSIS_CHAR = '\u2026';
var MESSAGE_ICON_SIZE = -1; // pick up from CSS
var NC_ = (context, str) => '%s\u0004%s'.format(context, str);
var NC_ = (context, str) => `${context}\u0004${str}`;
function sameYear(dateA, dateB) {
return dateA.getYear() == dateB.getYear();
@@ -114,26 +114,26 @@ var EventSourceBase = GObject.registerClass({
Signals: { 'changed': {} },
}, class EventSourceBase extends GObject.Object {
get isLoading() {
throw new GObject.NotImplementedError('isLoading in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`isLoading in ${this.constructor.name}`);
}
get hasCalendars() {
throw new GObject.NotImplementedError('hasCalendars in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`hasCalendars in ${this.constructor.name}`);
}
destroy() {
}
requestRange(_begin, _end) {
throw new GObject.NotImplementedError('requestRange in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`requestRange in ${this.constructor.name}`);
}
getEvents(_begin, _end) {
throw new GObject.NotImplementedError('getEvents in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`getEvents in ${this.constructor.name}`);
}
hasEvents(_day) {
throw new GObject.NotImplementedError('hasEvents in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`hasEvents in ${this.constructor.name}`);
}
});
@@ -215,7 +215,7 @@ class DBusEventSource extends EventSourceBase {
// about the HasCalendars property and would cause an exception trying
// to read it)
} else {
log('Error loading calendars: %s'.format(e.message));
log(`Error loading calendars: ${e.message}`);
return;
}
}
@@ -359,7 +359,7 @@ var Calendar = GObject.registerClass({
this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
this._settings.connect('changed::%s'.format(SHOW_WEEKDATE_KEY), this._onSettingsChange.bind(this));
this._settings.connect(`changed::${SHOW_WEEKDATE_KEY}`, this._onSettingsChange.bind(this));
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
/**
@@ -626,13 +626,13 @@ var Calendar = GObject.registerClass({
// Hack used in lieu of border-collapse - see gnome-shell.css
if (row == 2)
styleClass = 'calendar-day-top %s'.format(styleClass);
styleClass = `calendar-day-top ${styleClass}`;
let leftMost = rtl
? iter.getDay() == (this._weekStart + 6) % 7
: iter.getDay() == this._weekStart;
if (leftMost)
styleClass = 'calendar-day-left %s'.format(styleClass);
styleClass = `calendar-day-left ${styleClass}`;
if (sameDay(now, iter))
styleClass += ' calendar-today';
@@ -738,15 +738,15 @@ class EventMessage extends MessageList.Message {
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
if (this._event.date < periodBegin && !this._event.allDay) {
if (rtl)
title = '%s%s'.format(title, ELLIPSIS_CHAR);
title = `${title}${ELLIPSIS_CHAR}`;
else
title = '%s%s'.format(ELLIPSIS_CHAR, title);
title = `${ELLIPSIS_CHAR}${title}`;
}
if (this._event.end > periodEnd && !this._event.allDay) {
if (rtl)
title = '%s%s'.format(ELLIPSIS_CHAR, title);
title = `${ELLIPSIS_CHAR}${title}`;
else
title = '%s%s'.format(title, ELLIPSIS_CHAR);
title = `${title}${ELLIPSIS_CHAR}`;
}
return title;
}
@@ -1204,7 +1204,7 @@ class CalendarMessageList extends St.Widget {
for (let prop of ['visible', 'empty', 'can-clear']) {
connectionsIds.push(
section.connect('notify::%s'.format(prop), this._sync.bind(this)));
section.connect(`notify::${prop}`, this._sync.bind(this)));
}
connectionsIds.push(section.connect('message-focused', (_s, messageActor) => {
Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);

View File

@@ -192,7 +192,6 @@ var CloseDialog = GObject.registerClass({
this._dialog = null;
this._removeWindowEffect();
dialog.makeInactive();
dialog._dialog.ease({
scale_y: 0,
mode: Clutter.AnimationMode.LINEAR,

View File

@@ -113,7 +113,7 @@ var AutomountManager = class {
try {
drive.stop_finish(res);
} catch (e) {
log('Unable to stop the drive after drive-eject-button %s'.format(e.toString()));
log(`Unable to stop the drive after drive-eject-button ${e.toString()}`);
}
});
} else if (drive.can_eject()) {
@@ -122,7 +122,7 @@ var AutomountManager = class {
try {
drive.eject_with_operation_finish(res);
} catch (e) {
log('Unable to eject the drive after drive-eject-button %s'.format(e.toString()));
log(`Unable to eject the drive after drive-eject-button ${e.toString()}`);
}
});
}
@@ -210,7 +210,7 @@ var AutomountManager = class {
}
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
log('Unable to mount volume %s: %s'.format(volume.get_name(), e.toString()));
log(`Unable to mount volume ${volume.get_name()}: ${e.toString()}`);
this._closeOperation(volume);
}
}

View File

@@ -66,7 +66,7 @@ function startAppForMount(app, mount) {
retval = app.launch(files,
global.create_app_launch_context(0, -1));
} catch (e) {
log('Unable to launch the application %s: %s'.format(app.get_name(), e.toString()));
log(`Unable to launch the application ${app.get_name()}: ${e}`);
}
return retval;
@@ -105,7 +105,7 @@ var ContentTypeDiscoverer = class {
try {
contentTypes = mount.guess_content_type_finish(res);
} catch (e) {
log('Unable to guess content types on added mount %s: %s'.format(mount.get_name(), e.toString()));
log(`Unable to guess content types on added mount ${mount.get_name()}: ${e}`);
}
if (contentTypes.length) {

View File

@@ -3,11 +3,13 @@
const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi;
const Animation = imports.ui.animation;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const CheckBox = imports.ui.checkBox;
const Util = imports.misc.util;
var WORK_SPINNER_ICON_SIZE = 16;
var KeyringDialog = GObject.registerClass(
class KeyringDialog extends ModalDialog.ModalDialog {
@@ -19,97 +21,141 @@ class KeyringDialog extends ModalDialog.ModalDialog {
this.prompt.connect('show-confirm', this._onShowConfirm.bind(this));
this.prompt.connect('prompt-close', this._onHidePrompt.bind(this));
let content = new Dialog.MessageDialogContent();
this._content = new Dialog.MessageDialogContent();
this.contentLayout.add(this._content);
this.prompt.bind_property('message',
content, 'title', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('description',
content, 'description', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('message', this._content, 'title', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('description', this._content, 'description', GObject.BindingFlags.SYNC_CREATE);
let passwordBox = new St.BoxLayout({
style_class: 'prompt-dialog-password-layout',
vertical: true,
});
this._workSpinner = null;
this._controlTable = null;
this._passwordEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
can_focus: true,
x_align: Clutter.ActorAlign.CENTER,
});
ShellEntry.addContextMenu(this._passwordEntry);
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
this.prompt.bind_property('password-visible',
this._passwordEntry, 'visible', GObject.BindingFlags.SYNC_CREATE);
passwordBox.add_child(this._passwordEntry);
this._confirmEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
can_focus: true,
x_align: Clutter.ActorAlign.CENTER,
});
ShellEntry.addContextMenu(this._confirmEntry);
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
this.prompt.bind_property('confirm-visible',
this._confirmEntry, 'visible', GObject.BindingFlags.SYNC_CREATE);
passwordBox.add_child(this._confirmEntry);
this.prompt.set_password_actor(this._passwordEntry.clutter_text);
this.prompt.set_confirm_actor(this._confirmEntry.clutter_text);
let warningBox = new St.BoxLayout({ vertical: true });
let capsLockWarning = new ShellEntry.CapsLockWarning();
let syncCapsLockWarningVisibility = () => {
capsLockWarning.visible =
this.prompt.password_visible || this.prompt.confirm_visible;
};
this.prompt.connect('notify::password-visible', syncCapsLockWarningVisibility);
this.prompt.connect('notify::confirm-visible', syncCapsLockWarningVisibility);
warningBox.add_child(capsLockWarning);
let warning = new St.Label({ style_class: 'prompt-dialog-error-label' });
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
warning.clutter_text.line_wrap = true;
this.prompt.bind_property('warning',
warning, 'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.connect('notify::warning-visible', () => {
warning.opacity = this.prompt.warning_visible ? 255 : 0;
});
this.prompt.connect('notify::warning', () => {
if (this._passwordEntry && warning !== '')
Util.wiggle(this._passwordEntry);
});
warningBox.add_child(warning);
passwordBox.add_child(warningBox);
content.add_child(passwordBox);
this._choice = new CheckBox.CheckBox();
this.prompt.bind_property('choice-label', this._choice.getLabelActor(),
'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('choice-chosen', this._choice,
'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
this.prompt.bind_property('choice-visible', this._choice,
'visible', GObject.BindingFlags.SYNC_CREATE);
content.add_child(this._choice);
this.contentLayout.add_child(content);
this._cancelButton = this.addButton({
label: '',
action: this._onCancelButton.bind(this),
key: Clutter.KEY_Escape,
});
this._continueButton = this.addButton({
label: '',
action: this._onContinueButton.bind(this),
default: true,
});
this._cancelButton = this.addButton({ label: '',
action: this._onCancelButton.bind(this),
key: Clutter.KEY_Escape });
this._continueButton = this.addButton({ label: '',
action: this._onContinueButton.bind(this),
default: true });
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
}
_setWorking(working) {
if (!this._workSpinner)
return;
if (working)
this._workSpinner.play();
else
this._workSpinner.stop();
}
_buildControlTable() {
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
let table = new St.Widget({
style_class: 'keyring-dialog-control-table',
layout_manager: layout,
x_expand: true,
y_expand: true,
});
layout.hookup_style(table);
let rtl = table.get_text_direction() == Clutter.TextDirection.RTL;
let row = 0;
if (this.prompt.password_visible) {
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
label.set_text(_("Password:"));
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._passwordEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true,
x_expand: true,
});
ShellEntry.addContextMenu(this._passwordEntry);
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
animate: true,
});
if (rtl) {
layout.attach(this._workSpinner, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(label, 2, row, 1, 1);
} else {
layout.attach(label, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(this._workSpinner, 2, row, 1, 1);
}
row++;
} else {
this._workSpinner = null;
this._passwordEntry = null;
}
if (this.prompt.confirm_visible) {
var label = new St.Label({ style_class: 'prompt-dialog-password-label',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
label.set_text(_("Type again:"));
this._confirmEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true,
x_expand: true,
});
ShellEntry.addContextMenu(this._confirmEntry);
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
if (rtl) {
layout.attach(this._confirmEntry, 0, row, 1, 1);
layout.attach(label, 1, row, 1, 1);
} else {
layout.attach(label, 0, row, 1, 1);
layout.attach(this._confirmEntry, 1, row, 1, 1);
}
row++;
} else {
this._confirmEntry = null;
}
this.prompt.set_password_actor(this._passwordEntry ? this._passwordEntry.clutter_text : null);
this.prompt.set_confirm_actor(this._confirmEntry ? this._confirmEntry.clutter_text : null);
if (this._passwordEntry || this._confirmEntry) {
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
layout.attach(this._capsLockWarningLabel, 1, row, 1, 1);
row++;
}
if (this.prompt.choice_visible) {
let choice = new CheckBox.CheckBox();
this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('choice-chosen', choice, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
layout.attach(choice, rtl ? 0 : 1, row, 1, 1);
row++;
}
let warning = new St.Label({ style_class: 'prompt-dialog-error-label',
x_align: Clutter.ActorAlign.START });
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
warning.clutter_text.line_wrap = true;
layout.attach(warning, rtl ? 0 : 1, row, 1, 1);
this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE);
if (this._controlTable) {
this._controlTable.destroy_all_children();
this._controlTable.destroy();
}
this._controlTable = table;
this._content.add_child(table);
}
_updateSensitivity(sensitive) {
if (this._passwordEntry) {
this._passwordEntry.reactive = sensitive;
@@ -123,6 +169,7 @@ class KeyringDialog extends ModalDialog.ModalDialog {
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
}
_ensureOpen() {
@@ -144,16 +191,16 @@ class KeyringDialog extends ModalDialog.ModalDialog {
}
_onShowPassword() {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._passwordEntry.text = '';
this._passwordEntry.grab_key_focus();
}
_onShowConfirm() {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._confirmEntry.text = '';
this._continueButton.grab_key_focus();
}

View File

@@ -33,26 +33,38 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
title: this._content.title,
description: this._content.message,
});
this.contentLayout.add_actor(contentBox);
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table',
layout_manager: layout });
layout.hookup_style(secretTable);
let rtl = secretTable.get_text_direction() == Clutter.TextDirection.RTL;
let initialFocusSet = false;
let pos = 0;
for (let i = 0; i < this._content.secrets.length; i++) {
let secret = this._content.secrets[i];
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
text: secret.label,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
let reactive = secret.key != null;
let entryParams = {
style_class: 'prompt-dialog-password-entry',
hint_text: secret.label,
text: secret.value,
can_focus: reactive,
reactive,
x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
};
if (secret.password)
secret.entry = new St.PasswordEntry(entryParams);
else
secret.entry = new St.Entry(entryParams);
ShellEntry.addContextMenu(secret.entry);
contentBox.add_child(secret.entry);
if (secret.validate)
secret.valid = secret.validate(secret);
@@ -77,26 +89,36 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
} else {
secret.valid = true;
}
if (rtl) {
layout.attach(secret.entry, 0, pos, 1, 1);
layout.attach(label, 1, pos, 1, 1);
} else {
layout.attach(label, 0, pos, 1, 1);
layout.attach(secret.entry, 1, pos, 1, 1);
}
pos++;
}
if (this._content.secrets.some(s => s.password)) {
let capsLockWarning = new ShellEntry.CapsLockWarning();
contentBox.add_child(capsLockWarning);
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
if (rtl)
layout.attach(this._capsLockWarningLabel, 0, pos, 1, 1);
else
layout.attach(this._capsLockWarningLabel, 1, pos, 1, 1);
}
contentBox.add_child(secretTable);
if (flags & NM.SecretAgentGetSecretsFlags.WPS_PBC_ACTIVE) {
let descriptionLabel = new St.Label({
text: _('Alternatively you can connect by pushing the “WPS” button on your router.'),
style_class: 'message-dialog-description',
});
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: _("Alternatively you can connect by pushing the “WPS” button on your router.") });
descriptionLabel.clutter_text.line_wrap = true;
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
contentBox.add_child(descriptionLabel);
}
this.contentLayout.add_child(contentBox);
this._okButton = {
label: _("Connect"),
action: this._onOk.bind(this),
@@ -199,23 +221,19 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
case 'wpa-none':
case 'wpa-psk':
case 'sae':
secrets.push({ label: _('Password'), key: 'psk',
secrets.push({ label: _("Password: "), key: 'psk',
value: wirelessSecuritySetting.psk || '',
validate: this._validateWpaPsk, password: true });
break;
case 'none': // static WEP
secrets.push({
label: _('Key'),
key: 'wep-key%s'.format(wirelessSecuritySetting.wep_tx_keyidx),
value: wirelessSecuritySetting.get_wep_key(wirelessSecuritySetting.wep_tx_keyidx) || '',
wep_key_type: wirelessSecuritySetting.wep_key_type,
validate: this._validateStaticWep,
password: true,
});
secrets.push({ label: _("Key: "), key: `wep-key${wirelessSecuritySetting.wep_tx_keyidx}`,
value: wirelessSecuritySetting.get_wep_key(wirelessSecuritySetting.wep_tx_keyidx) || '',
wep_key_type: wirelessSecuritySetting.wep_key_type,
validate: this._validateStaticWep, password: true });
break;
case 'ieee8021x':
if (wirelessSecuritySetting.auth_alg == 'leap') { // Cisco LEAP
secrets.push({ label: _('Password'), key: 'leap-password',
secrets.push({ label: _("Password: "), key: 'leap-password',
value: wirelessSecuritySetting.leap_password || '', password: true });
} else { // Dynamic (IEEE 802.1x) WEP
this._get8021xSecrets(secrets);
@@ -225,7 +243,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
this._get8021xSecrets(secrets);
break;
default:
log('Invalid wireless key management: %s'.format(wirelessSecuritySetting.key_mgmt));
log(`Invalid wireless key management: ${wirelessSecuritySetting.key_mgmt}`);
}
}
@@ -235,15 +253,15 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
/* If hints were given we know exactly what we need to ask */
if (this._settingName == "802-1x" && this._hints.length) {
if (this._hints.includes('identity')) {
secrets.push({ label: _('Username'), key: 'identity',
secrets.push({ label: _("Username: "), key: 'identity',
value: ieee8021xSetting.identity || '', password: false });
}
if (this._hints.includes('password')) {
secrets.push({ label: _('Password'), key: 'password',
secrets.push({ label: _("Password: "), key: 'password',
value: ieee8021xSetting.password || '', password: true });
}
if (this._hints.includes('private-key-password')) {
secrets.push({ label: _('Private key password'), key: 'private-key-password',
secrets.push({ label: _("Private key password: "), key: 'private-key-password',
value: ieee8021xSetting.private_key_password || '', password: true });
}
return;
@@ -258,29 +276,29 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
// TTLS and PEAP are actually much more complicated, but this complication
// is not visible here since we only care about phase2 authentication
// (and don't even care of which one)
secrets.push({ label: _('Username'), key: null,
secrets.push({ label: _("Username: "), key: null,
value: ieee8021xSetting.identity || '', password: false });
secrets.push({ label: _('Password'), key: 'password',
secrets.push({ label: _("Password: "), key: 'password',
value: ieee8021xSetting.password || '', password: true });
break;
case 'tls':
secrets.push({ label: _('Identity'), key: null,
secrets.push({ label: _("Identity: "), key: null,
value: ieee8021xSetting.identity || '', password: false });
secrets.push({ label: _('Private key password'), key: 'private-key-password',
secrets.push({ label: _("Private key password: "), key: 'private-key-password',
value: ieee8021xSetting.private_key_password || '', password: true });
break;
default:
log('Invalid EAP/IEEE802.1x method: %s'.format(ieee8021xSetting.get_eap_method(0)));
log(`Invalid EAP/IEEE802.1x method: ${ieee8021xSetting.get_eap_method(0)}`);
}
}
_getPPPoESecrets(secrets) {
let pppoeSetting = this._connection.get_setting_pppoe();
secrets.push({ label: _('Username'), key: 'username',
secrets.push({ label: _("Username: "), key: 'username',
value: pppoeSetting.username || '', password: false });
secrets.push({ label: _('Service'), key: 'service',
secrets.push({ label: _("Service: "), key: 'service',
value: pppoeSetting.service || '', password: false });
secrets.push({ label: _('Password'), key: 'password',
secrets.push({ label: _("Password: "), key: 'password',
value: pppoeSetting.password || '', password: true });
}
@@ -290,7 +308,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
setting = this._connection.get_setting_cdma() || this._connection.get_setting_gsm();
else
setting = this._connection.get_setting_by_name(connectionType);
secrets.push({ label: _('Password'), key: 'password',
secrets.push({ label: _("Password: "), key: 'password',
value: setting.value || '', password: true });
}
@@ -307,14 +325,14 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
case '802-11-wireless':
wirelessSetting = this._connection.get_setting_wireless();
ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
content.title = _('Authentication required');
content.title = _("Authentication required by wireless network");
content.message = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
this._getWirelessSecrets(content.secrets, wirelessSetting);
break;
case '802-3-ethernet':
content.title = _("Wired 802.1X authentication");
content.message = null;
content.secrets.push({ label: _('Network name'), key: null,
content.secrets.push({ label: _("Network name: "), key: null,
value: connectionSetting.get_id(), password: false });
this._get8021xSecrets(content.secrets);
break;
@@ -328,19 +346,19 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
let gsmSetting = this._connection.get_setting_gsm();
content.title = _("PIN code required");
content.message = _("PIN code is needed for the mobile broadband device");
content.secrets.push({ label: _('PIN'), key: 'pin',
content.secrets.push({ label: _("PIN: "), key: 'pin',
value: gsmSetting.pin || '', password: true });
break;
}
// fall through
case 'cdma':
case 'bluetooth':
content.title = _('Authentication required');
content.title = _("Mobile broadband network password");
content.message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
this._getMobileSecrets(content.secrets, connectionType);
break;
default:
log('Invalid connection type: %s'.format(connectionType));
log(`Invalid connection type: ${connectionType}`);
}
return content;
@@ -585,12 +603,12 @@ var VPNRequestHandler = class {
try {
vpnSetting.foreach_data_item((key, value) => {
this._stdin.write('DATA_KEY=%s\n'.format(key), null);
this._stdin.write('DATA_VAL=%s\n\n'.format(value || ''), null);
this._stdin.write(`DATA_KEY=${key}\n`, null);
this._stdin.write(`DATA_VAL=${value || ''}\n\n`, null);
});
vpnSetting.foreach_secret((key, value) => {
this._stdin.write('SECRET_KEY=%s\n'.format(key), null);
this._stdin.write('SECRET_VAL=%s\n\n'.format(value || ''), null);
this._stdin.write(`SECRET_KEY=${key}\n`, null);
this._stdin.write(`SECRET_VAL=${value || ''}\n\n`, null);
});
this._stdin.write('DONE\n\n', null);
} catch (e) {
@@ -620,7 +638,7 @@ var NetworkAgent = class {
let monitor = this._pluginDir.monitor(Gio.FileMonitorFlags.NONE, null);
monitor.connect('changed', () => (this._vpnCacheBuilt = false));
} catch (e) {
log('Failed to create monitor for VPN plugin dir: %s'.format(e.message));
log(`Failed to create monitor for VPN plugin dir: ${e.message}`);
}
this._native.connect('new-request', this._newRequest.bind(this));
@@ -682,7 +700,7 @@ var NetworkAgent = class {
case '802-11-wireless': {
let wirelessSetting = connection.get_setting_wireless();
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
title = _('Authentication required');
title = _("Authentication required by wireless network");
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
break;
}
@@ -703,7 +721,7 @@ var NetworkAgent = class {
// fall through
case 'cdma':
case 'bluetooth':
title = _('Authentication required');
title = _("Mobile broadband network password");
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
case 'vpn':
@@ -711,7 +729,7 @@ var NetworkAgent = class {
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
default:
log('Invalid connection type: %s'.format(connectionType));
log(`Invalid connection type: ${connectionType}`);
this._native.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}

View File

@@ -4,19 +4,21 @@
const { AccountsService, Clutter, GLib,
GObject, Pango, PolkitAgent, Polkit, Shell, St } = imports.gi;
const Animation = imports.ui.animation;
const Dialog = imports.ui.dialog;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget;
const Util = imports.misc.util;
const DialogMode = {
AUTH: 0,
CONFIRM: 1,
};
const DIALOG_ICON_SIZE = 64;
var DIALOG_ICON_SIZE = 48;
var WORK_SPINNER_ICON_SIZE = 16;
const DELAYED_RESET_TIMEOUT = 200;
@@ -38,13 +40,11 @@ var AuthenticationDialog = GObject.registerClass({
let title = _("Authentication Required");
let headerContent = new Dialog.MessageDialogContent({ title, description });
this.contentLayout.add_child(headerContent);
let bodyContent = new Dialog.MessageDialogContent();
let content = new Dialog.MessageDialogContent({ title, description });
this.contentLayout.add_actor(content);
if (userNames.length > 1) {
log('polkitAuthenticationAgent: Received %d'.format(userNames.length) +
log(`polkitAuthenticationAgent: Received ${userNames.length} ` +
'identities that can be used for authentication. Only ' +
'considering one.');
}
@@ -59,21 +59,22 @@ var AuthenticationDialog = GObject.registerClass({
let userBox = new St.BoxLayout({
style_class: 'polkit-dialog-user-layout',
vertical: true,
vertical: false,
});
bodyContent.add_child(userBox);
content.add_child(userBox);
this._userAvatar = new UserWidget.Avatar(this._user, {
iconSize: DIALOG_ICON_SIZE,
styleClass: 'polkit-dialog-user-icon',
});
this._userAvatar.x_align = Clutter.ActorAlign.CENTER;
userBox.add_child(this._userAvatar);
this._userLabel = new St.Label({
style_class: userName === 'root'
? 'polkit-dialog-user-root-label'
: 'polkit-dialog-user-label',
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
if (userName === 'root')
@@ -81,60 +82,58 @@ var AuthenticationDialog = GObject.registerClass({
userBox.add_child(this._userLabel);
let passwordBox = new St.BoxLayout({
style_class: 'prompt-dialog-password-layout',
vertical: true,
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
content.add_child(this._passwordBox);
this._passwordLabel = new St.Label({
style_class: 'prompt-dialog-password-label',
y_align: Clutter.ActorAlign.CENTER,
});
this._passwordBox.add_child(this._passwordLabel);
this._passwordEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
text: "",
can_focus: true,
visible: false,
x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
});
ShellEntry.addContextMenu(this._passwordEntry);
this._passwordEntry.clutter_text.connect('activate', this._onEntryActivate.bind(this));
this._passwordEntry.bind_property('reactive',
this._passwordEntry.clutter_text, 'editable',
GObject.BindingFlags.SYNC_CREATE);
passwordBox.add_child(this._passwordEntry);
this._passwordBox.add_child(this._passwordEntry);
let warningBox = new St.BoxLayout({ vertical: true });
let capsLockWarning = new ShellEntry.CapsLockWarning();
this._passwordEntry.bind_property('visible',
capsLockWarning, 'visible',
GObject.BindingFlags.SYNC_CREATE);
warningBox.add_child(capsLockWarning);
this._errorMessageLabel = new St.Label({
style_class: 'prompt-dialog-error-label',
visible: false,
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
animate: true,
});
this._passwordBox.add(this._workSpinner);
this._passwordBox.hide();
let capsLockWarning = new ShellEntry.CapsLockWarning();
content.add_child(capsLockWarning);
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.line_wrap = true;
warningBox.add_child(this._errorMessageLabel);
content.add_child(this._errorMessageLabel);
this._errorMessageLabel.hide();
this._infoMessageLabel = new St.Label({
style_class: 'prompt-dialog-info-label',
visible: false,
});
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });
this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._infoMessageLabel.clutter_text.line_wrap = true;
warningBox.add_child(this._infoMessageLabel);
content.add_child(this._infoMessageLabel);
this._infoMessageLabel.hide();
/* text is intentionally non-blank otherwise the height is not the same as for
* infoMessage and errorMessageLabel - but it is still invisible because
* gnome-shell.css sets the color to be transparent
*/
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label' });
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
text: 'abc' });
this._nullMessageLabel.add_style_class_name('hidden');
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._nullMessageLabel.clutter_text.line_wrap = true;
warningBox.add_child(this._nullMessageLabel);
passwordBox.add_child(warningBox);
bodyContent.add_child(passwordBox);
content.add_child(this._nullMessageLabel);
this._nullMessageLabel.show();
this._cancelButton = this.addButton({ label: _("Cancel"),
action: this.cancel.bind(this),
@@ -150,8 +149,6 @@ var AuthenticationDialog = GObject.registerClass({
this._okButton.reactive = text.get_text().length > 0;
});
this.contentLayout.add_child(bodyContent);
this._doneEmitted = false;
this._mode = -1;
@@ -166,6 +163,13 @@ var AuthenticationDialog = GObject.registerClass({
this._onUserChanged();
}
_setWorking(working) {
if (working)
this._workSpinner.play();
else
this._workSpinner.stop();
}
_initiateSession() {
this._destroySession(DELAYED_RESET_TIMEOUT);
@@ -194,8 +198,8 @@ var AuthenticationDialog = GObject.registerClass({
// We could add retrying if this turns out to be a problem
log('polkitAuthenticationAgent: Failed to show modal dialog. ' +
'Dismissing authentication request for action-id %s '.format(this.actionId) +
'cookie %s'.format(this._cookie));
`Dismissing authentication request for action-id ${this.actionId} ` +
`cookie ${this._cookie}`);
this._emitDone(true);
}
}
@@ -214,6 +218,7 @@ var AuthenticationDialog = GObject.registerClass({
this._passwordEntry.reactive = false;
this._okButton.reactive = false;
this._setWorking(true);
this._session.response(response);
// When the user responds, dismiss already shown info and
@@ -255,8 +260,6 @@ var AuthenticationDialog = GObject.registerClass({
this._errorMessageLabel.show();
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
Util.wiggle(this._passwordEntry);
}
/* Try and authenticate again */
@@ -270,20 +273,19 @@ var AuthenticationDialog = GObject.registerClass({
this._sessionRequestTimeoutId = 0;
}
// Hack: The request string comes directly from PAM, if it's "Password:"
// we replace it with our own to allow localization, if it's something
// else we remove the last colon and any trailing or leading spaces.
if (request === 'Password:' || request === 'Password: ')
this._passwordEntry.hint_text = _('Password');
// Cheap localization trick
if (request == 'Password:' || request == 'Password: ')
this._passwordLabel.set_text(_("Password:"));
else
this._passwordEntry.hint_text = request.replace(/: *$/, '').trim();
this._passwordLabel.set_text(request);
this._passwordEntry.password_visible = echoOn;
this._passwordEntry.show();
this._passwordBox.show();
this._passwordEntry.set_text('');
this._passwordEntry.reactive = true;
this._okButton.reactive = false;
this._setWorking(false);
this._ensureOpen();
this._passwordEntry.grab_key_focus();
@@ -330,7 +332,7 @@ var AuthenticationDialog = GObject.registerClass({
if (this.state != ModalDialog.State.OPENED)
return;
this._passwordEntry.hide();
this._passwordBox.hide();
this._cancelButton.grab_key_focus();
this._okButton.reactive = false;
};

View File

@@ -87,7 +87,7 @@ var TelepathyComponent = class {
try {
this._client.register();
} catch (e) {
throw new Error('Could not register Telepathy client. Error: %s'.format(e.toString()));
throw new Error(`Could not register Telepathy client. Error: ${e}`);
}
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
@@ -254,7 +254,7 @@ class TelepathyClient extends Tp.BaseClient {
dispatchOp.claim_with_finish(result);
this._handlingChannels(account, conn, [channel], false);
} catch (err) {
log('Failed to Claim channel: %s'.format(err.toString()));
log(`Failed to Claim channel: ${err}`);
}
});

View File

@@ -230,7 +230,7 @@ class WorldClocksSection extends St.Button {
_onProxyReady(proxy, error) {
if (error) {
log('Failed to create GNOME Clocks proxy: %s'.format(error));
log(`Failed to create GNOME Clocks proxy: ${error}`);
return;
}
@@ -454,8 +454,6 @@ class MessagesIndicator extends St.Icon {
let sources = Main.messageTray.getSources();
sources.forEach(source => this._onSourceAdded(null, source));
this._sync();
this.connect('destroy', () => {
this._settings.run_dispose();
this._settings = null;
@@ -490,6 +488,26 @@ class MessagesIndicator extends St.Icon {
}
});
var IndicatorPad = GObject.registerClass(
class IndicatorPad extends St.Widget {
_init(actor) {
this._source = actor;
this._source.connect('notify::size', () => this.queue_relayout());
super._init();
this._source.bind_property('visible',
this, 'visible',
GObject.BindingFlags.SYNC_CREATE);
}
vfunc_get_preferred_width(forHeight) {
return this._source.get_preferred_width(forHeight);
}
vfunc_get_preferred_height(forWidth) {
return this._source.get_preferred_height(forWidth);
}
});
var FreezableBinLayout = GObject.registerClass(
class FreezableBinLayout extends Clutter.BinLayout {
_init() {
@@ -550,24 +568,16 @@ class DateMenuButton extends PanelMenu.Button {
let hbox;
let vbox;
super._init(0.5);
this._clockDisplay = new St.Label({ style_class: 'clock' });
this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER;
let menuAlignment = 0.5;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
super._init(menuAlignment);
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator();
const indicatorPad = new St.Widget();
this._indicator.bind_property('visible',
indicatorPad, 'visible',
GObject.BindingFlags.SYNC_CREATE);
indicatorPad.add_constraint(new Clutter.BindConstraint({
source: this._indicator,
coordinate: Clutter.BindCoordinate.SIZE,
}));
let box = new St.BoxLayout({ style_class: 'clock-display-box' });
box.add_actor(indicatorPad);
box.add_actor(new IndicatorPad(this._indicator));
box.add_actor(this._clockDisplay);
box.add_actor(this._indicator);
@@ -620,7 +630,7 @@ class DateMenuButton extends PanelMenu.Button {
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true,
overlay_scrollbars: true });
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.EXTERNAL);
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
vbox.add_actor(this._displaysSection);
let displaysBox = new St.BoxLayout({ vertical: true,

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Dialog, MessageDialogContent, ListSection, ListSectionItem */
const { Clutter, GObject, Meta, Pango, St } = imports.gi;
const { Clutter, GObject, Pango, St } = imports.gi;
function _setLabel(label, value) {
label.set({
@@ -58,16 +58,10 @@ class Dialog extends St.Widget {
this._dialog.add_child(this.buttonLayout);
}
makeInactive() {
_onDestroy() {
if (this._eventId != 0)
this._parentActor.disconnect(this._eventId);
this._eventId = 0;
this.buttonLayout.get_children().forEach(c => c.set_reactive(false));
}
_onDestroy() {
this.makeInactive();
}
_modalEventHandler(actor, event) {
@@ -185,20 +179,10 @@ var MessageDialogContent = GObject.registerClass({
};
super._init(Object.assign(defaultParams, params));
this.connect('notify::size', this._updateTitleStyle.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
this.add_child(this._title);
this.add_child(this._description);
}
_onDestroy() {
if (this._updateTitleStyleLater) {
Meta.later_remove(this._updateTitleStyleLater);
delete this._updateTitleStyleLater;
}
}
get title() {
return this._title.text;
}
@@ -207,32 +191,8 @@ var MessageDialogContent = GObject.registerClass({
return this._description.text;
}
_updateTitleStyle() {
if (!this._title.mapped)
return;
this._title.ensure_style();
const [, titleNatWidth] = this._title.get_preferred_width(-1);
if (titleNatWidth > this.width) {
if (this._updateTitleStyleLater)
return;
this._updateTitleStyleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._updateTitleStyleLater = 0;
this._title.add_style_class_name('leightweight');
return false;
});
}
}
set title(title) {
_setLabel(this._title, title);
this._title.remove_style_class_name('leightweight');
this._updateTitleStyle();
this.notify('title');
}

View File

@@ -411,18 +411,14 @@ var _Draggable = class _Draggable {
this._snapBackY = this._dragStartY + this._dragOffsetY;
this._snapBackScale = this._dragActor.scale_x;
let origDragOffsetX = this._dragOffsetX;
let origDragOffsetY = this._dragOffsetY;
let [transX, transY] = this._dragActor.get_translation();
this._dragOffsetX -= transX;
this._dragOffsetY -= transY;
if (this._dragActorMaxSize != undefined) {
let [scaledWidth, scaledHeight] = this._dragActor.get_transformed_size();
let currentSize = Math.max(scaledWidth, scaledHeight);
if (currentSize > this._dragActorMaxSize) {
let scale = this._dragActorMaxSize / currentSize;
let origScale = this._dragActor.scale_x;
let origDragOffsetX = this._dragOffsetX;
let origDragOffsetY = this._dragOffsetY;
// The position of the actor changes as we scale
// around the drag position, but we can't just tween
@@ -439,8 +435,8 @@ var _Draggable = class _Draggable {
this._dragActor.get_transition('scale-x').connect('new-frame', () => {
let currentScale = this._dragActor.scale_x / origScale;
this._dragOffsetX = currentScale * origDragOffsetX - transX;
this._dragOffsetY = currentScale * origDragOffsetY - transY;
this._dragOffsetX = currentScale * origDragOffsetX;
this._dragOffsetY = currentScale * origDragOffsetY;
this._dragActor.set_position(
this._dragX + this._dragOffsetX,
this._dragY + this._dragOffsetY);

View File

@@ -299,7 +299,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
try {
this._updatesPermission = Polkit.Permission.new_finish(res);
} catch (e) {
log('No permission to trigger offline updates: %s'.format(e.toString()));
log(`No permission to trigger offline updates: ${e}`);
}
});
}
@@ -563,7 +563,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
if (!sessionId) {
this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
sessionId = currentSessionProxy.Id;
log('endSessionDialog: No XDG_SESSION_ID, fetched from logind: %d'.format(sessionId));
log(`endSessionDialog: No XDG_SESSION_ID, fetched from logind: ${sessionId}`);
});
}

View File

@@ -111,11 +111,6 @@ function _easeActor(actor, params) {
autoReverse = params.autoReverse;
delete params.autoReverse;
// repeatCount doesn't include the initial iteration
const numIterations = repeatCount + 1;
// whether the transition should finish where it started
const isReversed = autoReverse && numIterations % 2 === 0;
if (params.mode != undefined)
actor.set_easing_mode(params.mode);
delete params.mode;
@@ -127,8 +122,7 @@ function _easeActor(actor, params) {
let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g'));
animatedProps.forEach(p => actor.remove_transition(p));
if (actor.get_easing_duration() > 0 || !isReversed)
actor.set(params);
actor.set(params);
actor.restore_easing_state();
let transition = animatedProps.map(p => actor.get_transition(p))
@@ -167,11 +161,6 @@ function _easeActorProperty(actor, propName, target, params) {
autoReverse = params.autoReverse;
delete params.autoReverse;
// repeatCount doesn't include the initial iteration
const numIterations = repeatCount + 1;
// whether the transition should finish where it started
const isReversed = autoReverse && numIterations % 2 === 0;
// Copy Clutter's behavior for implicit animations, see
// should_skip_implicit_transition()
if (actor instanceof Clutter.Actor && !actor.mapped)
@@ -185,9 +174,7 @@ function _easeActorProperty(actor, propName, target, params) {
if (duration == 0) {
let [obj, prop] = _getPropertyTarget(actor, propName);
if (!isReversed)
obj[prop] = target;
obj[prop] = target;
Meta.disable_unredirect_for_display(global.display);
callback(true);

View File

@@ -10,9 +10,10 @@ const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
var REPOSITORY_URL_DOWNLOAD = 'https://extensions.gnome.org/download-extension/%s.shell-extension.zip';
var REPOSITORY_URL_INFO = 'https://extensions.gnome.org/extension-info/';
var REPOSITORY_URL_UPDATE = 'https://extensions.gnome.org/update-info/';
var REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
var REPOSITORY_URL_DOWNLOAD = `${REPOSITORY_URL_BASE}/download-extension/%s.shell-extension.zip`;
var REPOSITORY_URL_INFO = `${REPOSITORY_URL_BASE}/extension-info/`;
var REPOSITORY_URL_UPDATE = `${REPOSITORY_URL_BASE}/update-info/`;
let _httpSession;
@@ -24,7 +25,7 @@ function installExtension(uuid, invocation) {
_httpSession.queue_message(message, () => {
if (message.status_code != Soup.KnownStatusCode.OK) {
Main.extensionManager.logExtensionError(uuid, 'downloading info: %d'.format(message.status_code));
Main.extensionManager.logExtensionError(uuid, `downloading info: ${message.status_code}`);
invocation.return_dbus_error('org.gnome.Shell.DownloadInfoError', message.status_code.toString());
return;
}
@@ -33,7 +34,7 @@ function installExtension(uuid, invocation) {
try {
info = JSON.parse(message.response_body.data);
} catch (e) {
Main.extensionManager.logExtensionError(uuid, 'parsing info: %s'.format(e.toString()));
Main.extensionManager.logExtensionError(uuid, `parsing info: ${e}`);
invocation.return_dbus_error('org.gnome.Shell.ParseInfoError', e.toString());
return;
}
@@ -111,7 +112,7 @@ function downloadExtensionUpdate(uuid) {
gotExtensionZipFile(session, message, uuid, dir, () => {
Main.extensionManager.notifyExtensionUpdate(uuid);
}, (code, msg) => {
log('Error while downloading update for extension %s: %s (%s)'.format(uuid, code, msg));
log(`Error while downloading update for extension ${uuid}: ${code} (${msg})`);
});
});
}
@@ -132,7 +133,7 @@ function checkForUpdates() {
let params = {
shell_version: Config.PACKAGE_VERSION,
installed: JSON.stringify(metadatas),
disable_version_validation: versionCheck.toString(),
disable_version_validation: `${versionCheck}`,
};
let url = REPOSITORY_URL_UPDATE;
@@ -194,8 +195,8 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
let dir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
let invocation = this._invocation;
function errback(code, msg) {
log('Error while installing %s: %s (%s)'.format(uuid, code, msg));
invocation.return_dbus_error('org.gnome.Shell.%s'.format(code), msg || '');
log(`Error while installing ${uuid}: ${code} (${msg})`);
invocation.return_dbus_error(`org.gnome.Shell.${code}`, msg || '');
}
function callback() {
@@ -203,7 +204,7 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
let extension = Main.extensionManager.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
Main.extensionManager.loadExtension(extension);
if (!Main.extensionManager.enableExtension(uuid))
throw new Error('Cannot add %s to enabled extensions gsettings key'.format(uuid));
throw new Error(`Cannot add ${uuid} to enabled extensions gsettings key`);
} catch (e) {
uninstallExtension(uuid);
errback('LoadExtensionError', e);

View File

@@ -1,14 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported init connect disconnect */
const { GLib, Gio, GObject, Shell, St } = imports.gi;
const { GLib, Gio, St } = imports.gi;
const Signals = imports.signals;
const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils;
const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const { ExtensionState, ExtensionType } = ExtensionUtils;
@@ -17,13 +15,10 @@ const DISABLED_EXTENSIONS_KEY = 'disabled-extensions';
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
const UPDATE_CHECK_TIMEOUT = 24 * 60 * 60; // 1 day in seconds
var ExtensionManager = class {
constructor() {
this._initialized = false;
this._enabled = false;
this._updateNotified = false;
this._extensions = new Map();
this._enabledExtensions = [];
@@ -42,7 +37,7 @@ var ExtensionManager = class {
try {
disableFile.create(Gio.FileCreateFlags.REPLACE_DESTINATION, null);
} catch (e) {
log('Failed to create file %s: %s'.format(disableFilename, e.message));
log(`Failed to create file ${disableFilename}: ${e.message}`);
}
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 60, () => {
@@ -52,12 +47,6 @@ var ExtensionManager = class {
this._installExtensionUpdates();
this._sessionUpdated();
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, UPDATE_CHECK_TIMEOUT, () => {
ExtensionDownloader.checkForUpdates();
return GLib.SOURCE_CONTINUE;
});
ExtensionDownloader.checkForUpdates();
}
lookup(uuid) {
@@ -140,7 +129,7 @@ var ExtensionManager = class {
if (extension.state != ExtensionState.DISABLED)
return;
let stylesheetNames = ['%s.css'.format(global.session_mode), 'stylesheet.css'];
let stylesheetNames = [`${global.session_mode}.css`, 'stylesheet.css'];
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (let i = 0; i < stylesheetNames.length; i++) {
try {
@@ -217,18 +206,6 @@ var ExtensionManager = class {
extension.hasUpdate = true;
this.emit('extension-state-changed', extension);
if (!this._updateNotified) {
this._updateNotified = true;
let source = new ExtensionUpdateSource();
Main.messageTray.add(source);
let notification = new MessageTray.Notification(source,
_('Extension Updates Available'),
_('Extension updates are ready to be installed.'));
source.showNotification(notification);
}
}
logExtensionError(uuid, error) {
@@ -236,7 +213,7 @@ var ExtensionManager = class {
if (!extension)
return;
let message = error.toString();
let message = `${error}`;
extension.error = message;
extension.state = ExtensionState.ERROR;
@@ -244,7 +221,7 @@ var ExtensionManager = class {
extension.errors = [];
extension.errors.push(message);
logError(error, 'Extension %s'.format(uuid));
logError(error, `Extension ${uuid}`);
this.emit('extension-state-changed', extension);
}
@@ -259,24 +236,24 @@ var ExtensionManager = class {
if (metadataContents instanceof Uint8Array)
metadataContents = imports.byteArray.toString(metadataContents);
} catch (e) {
throw new Error('Failed to load metadata.json: %s'.format(e.toString()));
throw new Error(`Failed to load metadata.json: ${e}`);
}
let meta;
try {
meta = JSON.parse(metadataContents);
} catch (e) {
throw new Error('Failed to parse metadata.json: %s'.format(e.toString()));
throw new Error(`Failed to parse metadata.json: ${e}`);
}
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
for (let i = 0; i < requiredProperties.length; i++) {
let prop = requiredProperties[i];
if (!meta[prop])
throw new Error('missing "%s" property in metadata.json'.format(prop));
throw new Error(`missing "${prop}" property in metadata.json`);
}
if (uuid != meta.uuid)
throw new Error('uuid "%s" from metadata.json does not match directory name "%s"'.format(meta.uuid, uuid));
throw new Error(`uuid "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
let extension = {
metadata: meta,
@@ -496,17 +473,17 @@ var ExtensionManager = class {
}
_loadExtensions() {
global.settings.connect('changed::%s'.format(ENABLED_EXTENSIONS_KEY),
global.settings.connect(`changed::${ENABLED_EXTENSIONS_KEY}`,
this._onEnabledExtensionsChanged.bind(this));
global.settings.connect('changed::%s'.format(DISABLED_EXTENSIONS_KEY),
global.settings.connect(`changed::${DISABLED_EXTENSIONS_KEY}`,
this._onEnabledExtensionsChanged.bind(this));
global.settings.connect('changed::%s'.format(DISABLE_USER_EXTENSIONS_KEY),
global.settings.connect(`changed::${DISABLE_USER_EXTENSIONS_KEY}`,
this._onUserExtensionsEnabledChanged.bind(this));
global.settings.connect('changed::%s'.format(EXTENSION_DISABLE_VERSION_CHECK_KEY),
global.settings.connect(`changed::${EXTENSION_DISABLE_VERSION_CHECK_KEY}`,
this._onVersionValidationChanged.bind(this));
global.settings.connect('writable-changed::%s'.format(ENABLED_EXTENSIONS_KEY),
global.settings.connect(`writable-changed::${ENABLED_EXTENSIONS_KEY}`,
this._onSettingsWritableChanged.bind(this));
global.settings.connect('writable-changed::%s'.format(DISABLED_EXTENSIONS_KEY),
global.settings.connect(`writable-changed::${DISABLED_EXTENSIONS_KEY}`,
this._onSettingsWritableChanged.bind(this));
this._enabledExtensions = this._getEnabledExtensions();
@@ -519,7 +496,7 @@ var ExtensionManager = class {
let uuid = info.get_name();
let existing = this.lookup(uuid);
if (existing) {
log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path, dir.get_path()));
log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be loaded`);
return;
}
@@ -530,7 +507,7 @@ var ExtensionManager = class {
try {
extension = this.createExtensionObject(uuid, dir, type);
} catch (e) {
logError(e, 'Could not load extension %s'.format(uuid));
logError(e, `Could not load extension ${uuid}`);
return;
}
this.loadExtension(extension);
@@ -580,27 +557,3 @@ var ExtensionManager = class {
}
};
Signals.addSignalMethods(ExtensionManager.prototype);
const ExtensionUpdateSource = GObject.registerClass(
class ExtensionUpdateSource extends MessageTray.Source {
_init() {
let appSys = Shell.AppSystem.get_default();
this._app = appSys.lookup_app('org.gnome.Extensions.desktop');
super._init(this._app.get_name());
}
getIcon() {
return this._app.app_info.get_icon();
}
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy(this._app.id);
}
open() {
this._app.activate();
Main.overview.hide();
Main.panel.closeCalendar();
}
});

View File

@@ -195,7 +195,7 @@ function zoomOutActorAtPos(actor, x, y) {
}
function animateIconPosition(icon, box, flags, nChangedIcons) {
if (!icon.has_allocation() || icon.allocation.equal(box) || icon.opacity === 0) {
if (!icon.has_allocation() || icon.allocation.equal(box)) {
icon.allocate(box, flags);
return false;
}
@@ -556,25 +556,15 @@ var IconGrid = GObject.registerClass({
}, Infinity);
let normalization = maxDist - minDist;
actors.forEach(actor => {
let clone = new Clutter.Clone({ source: actor });
this._clonesAnimating.push(clone);
Main.uiGroup.add_actor(clone);
});
/*
* ^
* | These need to be separate loops because Main.uiGroup.add_actor
* | is excessively slow if done inside the below loop and we want the
* | below loop to complete within one frame interval (#2065, !1002).
* v
*/
this._clonesAnimating.forEach(actorClone => {
let actor = actorClone.source;
for (let index = 0; index < actors.length; index++) {
let actor = actors[index];
actor.opacity = 0;
actor.reactive = false;
let actorClone = new Clutter.Clone({ source: actor });
this._clonesAnimating.push(actorClone);
Main.uiGroup.add_actor(actorClone);
let [width, height] = this._getAllocatedChildSizeAndSpacing(actor);
actorClone.set_size(width, height);
let scaleX = sourceScaledWidth / width;
@@ -641,7 +631,7 @@ var IconGrid = GObject.registerClass({
actorClone.ease(movementParams);
actorClone.ease(fadeParams);
});
}
}
_getAllocatedChildSizeAndSpacing(child) {

View File

@@ -24,29 +24,29 @@ const SHOW_KEYBOARD = 'screen-keyboard-enabled';
const KEY_SIZE = 2;
const defaultKeysPre = [
[[], [], [{ width: 1.5, level: 1, extraClassName: 'shift-key-lowercase', icon: 'keyboard-shift-filled-symbolic' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ width: 1.5, level: 0, extraClassName: 'shift-key-uppercase', icon: 'keyboard-shift-filled-symbolic' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ width: 1.5, level: 1, extraClassName: 'shift-key-lowercase' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ width: 1.5, level: 0, extraClassName: 'shift-key-uppercase' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ label: '=/<', width: 1.5, level: 3 }], [{ label: 'ABC', width: 1.5, level: 0 }]],
[[], [], [{ label: '?123', width: 1.5, level: 2 }], [{ label: 'ABC', width: 1.5, level: 0 }]],
];
const defaultKeysPost = [
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ width: 3, level: 1, right: true, extraClassName: 'shift-key-lowercase', icon: 'keyboard-shift-filled-symbolic' }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ width: 3, level: 0, right: true, extraClassName: 'shift-key-uppercase', icon: 'keyboard-shift-filled-symbolic' }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ width: 3, level: 1, right: true, extraClassName: 'shift-key-lowercase' }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ width: 3, level: 0, right: true, extraClassName: 'shift-key-uppercase' }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ label: '=/<', width: 3, level: 3, right: true }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ label: '?123', width: 3, level: 2, right: true }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
];
var AspectContainer = GObject.registerClass(
@@ -257,11 +257,11 @@ var Key = GObject.registerClass({
'released': { param_types: [GObject.TYPE_UINT, GObject.TYPE_STRING] },
},
}, class Key extends St.BoxLayout {
_init(key, extendedKeys, icon = null) {
_init(key, extendedKeys) {
super._init({ style_class: 'key-container' });
this.key = key || "";
this.keyButton = this._makeKey(this.key, icon);
this.keyButton = this._makeKey(this.key);
/* Add the key in a container, so keys can be padded without losing
* logical proportions between those.
@@ -404,21 +404,14 @@ var Key = GObject.registerClass({
this._capturedPress = false;
}
_makeKey(key, icon) {
_makeKey(key) {
let label = GLib.markup_escape_text(key, -1);
let button = new St.Button({
label,
style_class: 'keyboard-key',
x_expand: true,
});
if (icon) {
let child = new St.Icon({ icon_name: icon });
button.set_child(child);
this._icon = child;
} else {
let label = GLib.markup_escape_text(key, -1);
button.set_label(label);
}
button.keyWidth = 1;
button.connect('button-press-event', () => {
this._press(key);
@@ -482,16 +475,10 @@ var Key = GObject.registerClass({
}
setLatched(latched) {
if (!this._icon)
return;
if (latched) {
if (latched)
this.keyButton.add_style_pseudo_class('latched');
this._icon.icon_name = 'keyboard-caps-lock-filled-symbolic';
} else {
else
this.keyButton.remove_style_pseudo_class('latched');
this._icon.icon_name = 'keyboard-shift-filled-symbolic';
}
}
});
@@ -1035,7 +1022,7 @@ var EmojiSelection = GObject.registerClass({
section.button = key;
}
key = new Key(null, [], 'go-down-symbolic');
key = new Key(null, []);
key.keyButton.add_style_class_name('default-key');
key.keyButton.add_style_class_name('hide-key');
key.connect('released', () => {
@@ -1115,9 +1102,6 @@ var KeyboardManager = class KeyBoardManager {
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
this._seat = Clutter.get_default_backend().get_default_seat();
this._seat.connect('notify::touch-mode', this._syncEnabled.bind(this));
this._lastDevice = null;
Meta.get_backend().connect('last-device-changed', (backend, device) => {
if (device.get_device_name().indexOf('XTEST') < 0) {
@@ -1138,9 +1122,7 @@ var KeyboardManager = class KeyBoardManager {
_syncEnabled() {
let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
let autoEnabled = this._seat.get_touch_mode() && this._lastDeviceIsTouchscreen();
let enabled = enableKeyboard || autoEnabled;
let enabled = enableKeyboard || this._lastDeviceIsTouchscreen();
if (!enabled && !this._keyboard)
return;
@@ -1268,7 +1250,11 @@ class Keyboard extends St.BoxLayout {
this._clearShowIdle();
this._keyboardController.destroy();
this._keyboardController = null;
this._suggestions = null;
this._aspectContainer = null;
this._emojiSelection = null;
this._keypad = null;
Main.layoutManager.untrackChrome(this);
Main.layoutManager.keyboardBox.remove_actor(this);
@@ -1448,13 +1434,12 @@ class Keyboard extends St.BoxLayout {
let keyval = key.keyval;
let switchToLevel = key.level;
let action = key.action;
let icon = key.icon;
/* Skip emoji button if necessary */
if (!this._emojiKeyVisible && action == 'emoji')
continue;
extraButton = new Key(key.label || '', [], icon);
extraButton = new Key(key.label || '', []);
extraButton.keyButton.add_style_class_name('default-key');
if (key.extraClassName != null)
@@ -1854,20 +1839,13 @@ var KeyboardController = class {
this._onSourcesModified.bind(this));
this._currentSource = this._inputSourceManager.currentSource;
this._notifyContentPurposeId = Main.inputMethod.connect(
'notify::content-purpose', this._onContentPurposeHintsChanged.bind(this));
this._notifyContentHintsId = Main.inputMethod.connect(
'notify::content-hints', this._onContentPurposeHintsChanged.bind(this));
this._notifyInputPanelStateId = Main.inputMethod.connect(
'input-panel-state', (o, state) => this.emit('panel-state', state));
}
destroy() {
this._inputSourceManager.disconnect(this._sourceChangedId);
this._inputSourceManager.disconnect(this._sourcesModifiedId);
Main.inputMethod.disconnect(this._notifyContentPurposeId);
Main.inputMethod.disconnect(this._notifyContentHintsId);
Main.inputMethod.disconnect(this._notifyInputPanelStateId);
Main.inputMethod.connect('notify::content-purpose',
this._onContentPurposeHintsChanged.bind(this));
Main.inputMethod.connect('notify::content-hints',
this._onContentPurposeHintsChanged.bind(this));
Main.inputMethod.connect('input-panel-state', (o, state) => {
this.emit('panel-state', state);
});
}
_onSourcesModified() {

View File

@@ -738,7 +738,7 @@ var LayoutManager = GObject.registerClass({
showKeyboard() {
this.keyboardBox.show();
this.keyboardBox.ease({
translation_y: -this.keyboardBox.height,
anchor_y: this.keyboardBox.height,
opacity: 255,
duration: KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -755,7 +755,7 @@ var LayoutManager = GObject.registerClass({
this._updateRegions();
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', () => {
this.keyboardBox.translation_y = -this.keyboardBox.height;
this.keyboardBox.anchor_y = this.keyboardBox.height;
});
}
@@ -765,7 +765,7 @@ var LayoutManager = GObject.registerClass({
this._keyboardHeightNotifyId = 0;
}
this.keyboardBox.ease({
translation_y: this.keyboardBox.height,
anchor_y: 0,
opacity: 0,
duration: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_IN_QUAD,

View File

@@ -244,13 +244,7 @@ function objectToString(o) {
// special case this since the default is way, way too verbose
return '<js function>';
} else {
if (o === undefined)
return 'undefined';
if (o === null)
return 'null';
return o.toString();
return `${o}`;
}
}
@@ -297,7 +291,7 @@ class Result extends St.BoxLayout {
this.add(cmdTxt);
let box = new St.BoxLayout({});
this.add(box);
let resultTxt = new St.Label({ text: 'r(%d) = '.format(index) });
let resultTxt = new St.Label({ text: `r(${index}) = ` });
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
box.add(resultTxt);
let objLink = new ObjLink(this._lookingGlass, o);
@@ -337,7 +331,7 @@ var WindowList = GObject.registerClass({
box.add_child(windowLink);
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
box.add(propsBox);
propsBox.add(new St.Label({ text: 'wmclass: %s'.format(metaWindow.get_wm_class()) }));
propsBox.add(new St.Label({ text: `wmclass: ${metaWindow.get_wm_class()}` }));
let app = tracker.get_window_app(metaWindow);
if (app != null && !app.is_window_backed()) {
let icon = app.create_icon_texture(22);
@@ -430,7 +424,7 @@ class ObjInspector extends St.ScrollView {
link = new St.Label({ text: '<error>' });
}
let box = new St.BoxLayout();
box.add(new St.Label({ text: '%s: '.format(propName) }));
box.add(new St.Label({ text: `${propName}: ` }));
box.add(link);
this._container.add_actor(box);
}
@@ -647,9 +641,9 @@ var Inspector = GObject.registerClass({
this._target = target;
this._pointerTarget = target;
let position = '[inspect x: %d y: %d]'.format(stageX, stageY);
let position = `[inspect x: ${stageX} y: ${stageY}]`;
this._displayText.text = '';
this._displayText.text = '%s %s'.format(position, this._target);
this._displayText.text = `${position} ${this._target}`;
this._lookingGlass.setBorderPaintTarget(this._target);
}
@@ -852,7 +846,7 @@ class LookingGlass extends St.BoxLayout {
inspectIcon.connect('button-press-event', () => {
let inspector = new Inspector(this);
inspector.connect('target', (i, target, stageX, stageY) => {
this._pushResult('inspect(%d, %d)'.format(Math.round(stageX), Math.round(stageY)), target);
this._pushResult(`inspect(${Math.round(stageX)}, ${Math.round(stageY)})`, target);
});
inspector.connect('closed', () => {
this.show();
@@ -958,8 +952,9 @@ class LookingGlass extends St.BoxLayout {
// monospace font to be bold/oblique/etc. Could easily be added here.
let size = fontDesc.get_size() / 1024.;
let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt';
this.style = 'font-size: %d%s; font-family: "%s";'.format(
size, unit, fontDesc.get_family());
this.style = `
font-size: ${size}${unit};
font-family: "${fontDesc.get_family()}";`;
}
setBorderPaintTarget(obj) {
@@ -1040,7 +1035,7 @@ class LookingGlass extends St.BoxLayout {
this._history.addItem(command);
let lines = command.split(';');
lines.push('return %s'.format(lines.pop()));
lines.push(`return ${lines.pop()}`);
let fullCmd = commandHeader + lines.join(';');
@@ -1048,7 +1043,7 @@ class LookingGlass extends St.BoxLayout {
try {
resultObj = Function(fullCmd)();
} catch (e) {
resultObj = '<exception %s>'.format(e.toString());
resultObj = `<exception ${e}>`;
}
this._pushResult(command, resultObj);
@@ -1067,7 +1062,7 @@ class LookingGlass extends St.BoxLayout {
try {
return this._resultsArea.get_child_at_index(idx - this._offset).o;
} catch (e) {
throw new Error('Unknown result at index %d'.format(idx));
throw new Error(`Unknown result at index ${idx}`);
}
}

View File

@@ -127,10 +127,6 @@ var Magnifier = class Magnifier {
* Show the system mouse pointer.
*/
showSystemCursor() {
const seat = Clutter.get_default_backend().get_default_seat();
if (seat.is_unfocus_inhibited())
seat.uninhibit_unfocus();
this._cursorTracker.set_pointer_visible(true);
}
@@ -139,10 +135,6 @@ var Magnifier = class Magnifier {
* Hide the system mouse pointer.
*/
hideSystemCursor() {
const seat = Clutter.get_default_backend().get_default_seat();
if (!seat.is_unfocus_inhibited())
seat.inhibit_unfocus();
this._cursorTracker.set_pointer_visible(false);
}
@@ -177,7 +169,7 @@ var Magnifier = class Magnifier {
// Make sure system mouse pointer is shown when all zoom regions are
// invisible.
if (!activate)
this.showSystemCursor();
this._cursorTracker.set_pointer_visible(true);
// Notify interested parties of this change
this.emit('active-changed', activate);
@@ -438,10 +430,8 @@ var Magnifier = class Magnifier {
* lines making up the crosshairs.
*/
setCrosshairsLength(length) {
if (this._crossHairs) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._crossHairs.setLength(length / scaleFactor);
}
if (this._crossHairs)
this._crossHairs.setLength(length);
}
/**
@@ -755,7 +745,8 @@ var ZoomRegion = class ZoomRegion {
this._xCaret = 0;
this._yCaret = 0;
this._pointerIdleMonitor = Meta.IdleMonitor.get_core();
let seat = Clutter.get_default_backend().get_default_seat();
this._pointerIdleMonitor = Meta.IdleMonitor.get_for_device(seat.get_pointer());
this._scrollContentsTimerId = 0;
}
@@ -807,14 +798,9 @@ var ZoomRegion = class ZoomRegion {
return;
}
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let [xFocus, yFocus] = [(extents.x + (extents.width / 2)) * scaleFactor,
(extents.y + (extents.height / 2)) * scaleFactor];
if (this._xFocus !== xFocus || this._yFocus !== yFocus) {
[this._xFocus, this._yFocus] = [xFocus, yFocus];
this._centerFromFocusPosition();
}
[this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
extents.y + (extents.height / 2)];
this._centerFromFocusPosition();
}
_updateCaret(caller, event) {
@@ -829,13 +815,8 @@ var ZoomRegion = class ZoomRegion {
return;
}
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let [xCaret, yCaret] = [extents.x * scaleFactor, extents.y * scaleFactor];
if (this._xCaret !== xCaret || this._yCaret !== yCaret) {
[this._xCaret, this._yCaret] = [xCaret, yCaret];
this._centerFromCaretPosition();
}
[this._xCaret, this._yCaret] = [extents.x, extents.y];
this._centerFromCaretPosition();
}
/**
@@ -883,8 +864,7 @@ var ZoomRegion = class ZoomRegion {
setMagFactor(xMagFactor, yMagFactor) {
this._changeROI({ xMagFactor,
yMagFactor,
redoCursorTracking: this._followingCursor,
animate: true });
redoCursorTracking: this._followingCursor });
}
/**
@@ -1142,13 +1122,6 @@ var ZoomRegion = class ZoomRegion {
return this._screenPosition;
}
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId !== 0) {
GLib.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
}
/**
* scrollToMousePos:
* Set the region of interest based on the position of the system pointer.
@@ -1162,31 +1135,30 @@ var ZoomRegion = class ZoomRegion {
else
this._updateMousePosition();
this._clearScrollContentsTimer();
this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
this._followingCursor = false;
if (this._xDelayed !== null && this._yDelayed !== null) {
this._scrollContentsToDelayed(this._xDelayed, this._yDelayed);
this._xDelayed = null;
this._yDelayed = null;
}
return GLib.SOURCE_REMOVE;
});
// Determine whether the system mouse pointer is over this zoom region.
return this._isMouseOverRegion();
}
_scrollContentsToDelayed(x, y) {
if (this._followingCursor) {
this._xDelayed = x;
this._yDelayed = y;
} else {
this.scrollContentsTo(x, y);
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId != 0) {
GLib.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
}
_scrollContentsToDelayed(x, y) {
if (this._pointerIdleMonitor.get_idletime() >= POINTER_REST_TIME) {
this.scrollContentsTo(x, y);
return;
}
this._clearScrollContentsTimer();
this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
this._scrollContentsToDelayed(x, y);
return GLib.SOURCE_REMOVE;
});
}
/**
* scrollContentsTo:
* Shift the contents of the magnified view such it is centered on the given
@@ -1195,16 +1167,11 @@ var ZoomRegion = class ZoomRegion {
* @param {number} y: The y-coord of the point to center on.
*/
scrollContentsTo(x, y) {
if (x < 0 || x > global.screen_width ||
y < 0 || y > global.screen_height)
return;
this._clearScrollContentsTimer();
this._followingCursor = false;
this._changeROI({ xCenter: x,
yCenter: y,
animate: true });
yCenter: y });
}
/**
@@ -1356,7 +1323,7 @@ var ZoomRegion = class ZoomRegion {
this._crossHairsActor = null;
// Contrast and brightness effects.
this._magShaderEffects = new MagShaderEffects(mainGroup);
this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
this._magShaderEffects.setColorSaturation(this._colorSaturation);
this._magShaderEffects.setInvertLightness(this._invertLightness);
this._magShaderEffects.setBrightness(this._brightness);
@@ -1413,8 +1380,7 @@ var ZoomRegion = class ZoomRegion {
yMagFactor: this._yMagFactor,
xCenter: this._xCenter,
yCenter: this._yCenter,
redoCursorTracking: false,
animate: false });
redoCursorTracking: false });
if (params.xMagFactor <= 0)
params.xMagFactor = this._xMagFactor;
@@ -1453,7 +1419,8 @@ var ZoomRegion = class ZoomRegion {
height: this._viewPortHeight }, true);
}
this._updateCloneGeometry(params.animate);
this._updateCloneGeometry();
this._updateMousePosition();
}
_isMouseOverRegion() {
@@ -1591,64 +1558,38 @@ var ZoomRegion = class ZoomRegion {
this._magView.set_position(this._viewPortX, this._viewPortY);
}
_updateCloneGeometry(animate = false) {
_updateCloneGeometry() {
if (!this.isActive())
return;
this._uiGroupClone.set_scale(this._xMagFactor, this._yMagFactor);
this._mouseActor.set_scale(this._xMagFactor, this._yMagFactor);
let [x, y] = this._screenToViewPort(0, 0);
this._uiGroupClone.ease({
x: Math.round(x),
y: Math.round(y),
scale_x: this._xMagFactor,
scale_y: this._yMagFactor,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: animate ? 100 : 0,
});
this._uiGroupClone.set_position(Math.round(x), Math.round(y));
let [mouseX, mouseY] = this._getMousePosition();
this._mouseActor.ease({
x: mouseX,
y: mouseY,
scale_x: this._xMagFactor,
scale_y: this._yMagFactor,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: animate ? 100 : 0,
});
if (this._crossHairsActor) {
let [crossX, crossY] = this._getCrossHairsPosition();
this._crossHairsActor.ease({
x: crossX,
y: crossY,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: animate ? 100 : 0,
});
}
this._updateMousePosition();
}
_updateMousePosition() {
let [xMagMouse, yMagMouse] = this._getMousePosition();
if (!this.isActive())
return;
let [xMagMouse, yMagMouse] = this._screenToViewPort(this._magnifier.xMouse,
this._magnifier.yMouse);
xMagMouse = Math.round(xMagMouse);
yMagMouse = Math.round(yMagMouse);
this._mouseActor.set_position(xMagMouse, yMagMouse);
if (this._crossHairsActor) {
let [crossX, crossY] = this._getCrossHairsPosition();
this._crossHairsActor.set_position(crossX, crossY);
let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
this._crossHairsActor.set_position(xMagMouse - groupWidth / 2,
yMagMouse - groupHeight / 2);
}
}
_getMousePosition() {
let [xMagMouse, yMagMouse] = this._screenToViewPort(
this._magnifier.xMouse, this._magnifier.yMouse);
return [Math.round(xMagMouse), Math.round(yMagMouse)];
}
_getCrossHairsPosition() {
let [xMagMouse, yMagMouse] = this._getMousePosition();
let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
return [xMagMouse - groupWidth / 2, yMagMouse - groupHeight / 2];
}
_monitorsChanged() {
this._background.set_size(global.screen_width, global.screen_height);
this._updateScreenPosition();
@@ -1867,10 +1808,12 @@ class Crosshairs extends Clutter.Actor {
let clipWidth = this._clipSize[0];
let clipHeight = this._clipSize[1];
let left = groupWidth / 2 - clipWidth / 2 - leftLength - thickness / 2;
let right = groupWidth / 2 + clipWidth / 2 + thickness / 2;
let top = groupHeight / 2 - clipHeight / 2 - topLength - thickness / 2;
let bottom = groupHeight / 2 + clipHeight / 2 + thickness / 2;
// Note that clip, if present, is not centred on the cross hair
// intersection, but biased towards the top left.
let left = groupWidth / 2 - clipWidth * 0.25 - leftLength;
let right = groupWidth / 2 + clipWidth * 0.75;
let top = groupHeight / 2 - clipHeight * 0.25 - topLength - thickness / 2;
let bottom = groupHeight / 2 + clipHeight * 0.75 + thickness / 2;
this._horizLeftHair.set_position(left, (groupHeight - thickness) / 2);
this._horizRightHair.set_position(right, (groupHeight - thickness) / 2);
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);

View File

@@ -161,8 +161,6 @@ function _initializeUI() {
_loadOskLayouts();
_loadDefaultStylesheet();
new AnimationsSettings();
// Setup the stage hierarchy early
layoutManager = new Layout.LayoutManager();
@@ -259,7 +257,7 @@ function _initializeUI() {
if (sessionMode.currentMode != 'gdm' &&
sessionMode.currentMode != 'initial-setup') {
GLib.log_structured(LOG_DOMAIN, GLib.LogLevelFlags.LEVEL_MESSAGE, {
'MESSAGE': 'GNOME Shell started at %s'.format(_startDate),
'MESSAGE': `GNOME Shell started at ${_startDate}`,
'MESSAGE_ID': GNOMESHELL_STARTED_MESSAGE_ID,
});
}
@@ -282,7 +280,7 @@ function _initializeUI() {
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
if (perfModuleName) {
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
let module = eval('imports.perf.%s;'.format(perfModuleName));
let module = eval(`imports.perf.${perfModuleName};`);
Scripting.runPerfScript(module, perfOutput);
}
});
@@ -291,7 +289,7 @@ function _initializeUI() {
function _getStylesheet(name) {
let stylesheet;
stylesheet = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/%s'.format(name));
stylesheet = Gio.File.new_for_uri(`resource:///org/gnome/shell/theme/${name}`);
if (stylesheet.query_exists(null))
return stylesheet;
@@ -303,7 +301,7 @@ function _getStylesheet(name) {
return stylesheet;
}
stylesheet = Gio.File.new_for_path('%s/theme/%s'.format(global.datadir, name));
stylesheet = Gio.File.new_for_path(`${global.datadir}/theme/${name}`);
if (stylesheet.query_exists(null))
return stylesheet;
@@ -361,12 +359,12 @@ function reloadThemeResource() {
if (_themeResource)
_themeResource._unregister();
_themeResource = Gio.Resource.load('%s/gnome-shell-theme.gresource'.format(global.datadir));
_themeResource = Gio.Resource.load(`${global.datadir}/gnome-shell-theme.gresource`);
_themeResource._register();
}
function _loadOskLayouts() {
_oskResource = Gio.Resource.load('%s/gnome-shell-osk-layouts.gresource'.format(global.datadir));
_oskResource = Gio.Resource.load(`${global.datadir}/gnome-shell-osk-layouts.gresource`);
_oskResource._register();
}
@@ -420,9 +418,9 @@ function notify(msg, details) {
function notifyError(msg, details) {
// Also print to stderr so it's logged somewhere
if (details)
log('error: %s: %s'.format(msg, details));
log(`error: ${msg}: ${details}`);
else
log('error: %s'.format(msg));
log(`error: ${msg}`);
notify(msg, details);
}
@@ -689,7 +687,7 @@ function _queueBeforeRedraw(workId) {
*/
function initializeDeferredWork(actor, callback) {
// Turn into a string so we can use as an object property
let workId = (++_deferredWorkSequence).toString();
let workId = `${++_deferredWorkSequence}`;
_deferredWorkData[workId] = { actor,
callback };
actor.connect('notify::mapped', () => {
@@ -760,46 +758,3 @@ function showRestartMessage(message) {
let restartMessage = new RestartMessage(message);
restartMessage.open();
}
var AnimationsSettings = class {
constructor() {
let backend = Meta.get_backend();
if (!backend.is_rendering_hardware_accelerated()) {
St.Settings.get().inhibit_animations();
return;
}
let isXvnc = Shell.util_has_x11_display_extension(
global.display, 'VNC-EXTENSION');
if (isXvnc) {
St.Settings.get().inhibit_animations();
return;
}
let remoteAccessController = backend.get_remote_access_controller();
if (!remoteAccessController)
return;
this._handles = new Set();
remoteAccessController.connect('new-handle',
(_, handle) => this._onNewRemoteAccessHandle(handle));
}
_onRemoteAccessHandleStopped(handle) {
let settings = St.Settings.get();
settings.uninhibit_animations();
this._handles.delete(handle);
}
_onNewRemoteAccessHandle(handle) {
if (!handle.get_disable_animations())
return;
let settings = St.Settings.get();
settings.inhibit_animations();
this._handles.add(handle);
handle.connect('stopped', this._onRemoteAccessHandleStopped.bind(this));
}
};

View File

@@ -79,7 +79,7 @@ class URLHighlighter extends St.Label {
if (urlId != -1) {
let url = this._urls[urlId].url;
if (!url.includes(':'))
url = 'http://%s'.format(url);
url = `http://${url}`;
Gio.app_info_launch_default_for_uri(
url, global.create_app_launch_context(0, -1));
@@ -132,7 +132,7 @@ class URLHighlighter extends St.Label {
for (let i = 0; i < urls.length; i++) {
let url = urls[i];
let str = this._text.substr(pos, url.pos - pos);
markup += '%s<span foreground="%s"><u>%s</u></span>'.format(str, this._linkColor, url.url);
markup += `${str}<span foreground="${this._linkColor}"><u>${url.url}</u></span>`;
pos = url.pos + url.url.length;
}
markup += this._text.substr(pos);

View File

@@ -229,17 +229,15 @@ var NotificationApplicationPolicy = GObject.registerClass({
this._canonicalId = this._canonicalizeId(id);
this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' });
this._settings = new Gio.Settings({
schema_id: 'org.gnome.desktop.notifications.application',
path: '/org/gnome/desktop/notifications/application/%s/'.format(this._canonicalId),
});
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications.application',
path: `/org/gnome/desktop/notifications/application/${this._canonicalId}/` });
this._masterSettings.connect('changed', this._changed.bind(this));
this._settings.connect('changed', this._changed.bind(this));
}
store() {
this._settings.set_string('application-id', '%s.desktop'.format(this.id));
this._settings.set_string('application-id', `${this.id}.desktop`);
let apps = this._masterSettings.get_strv('application-children');
if (!apps.includes(this._canonicalId)) {
@@ -1079,7 +1077,7 @@ var MessageTray = GObject.registerClass({
add(source) {
if (this.contains(source)) {
log('Trying to re-add source %s'.format(source.title));
log(`Trying to re-add source ${source.title}`);
return;
}

View File

@@ -147,7 +147,7 @@ var MprisPlayer = class MprisPlayer {
// so prefer activating the app via .desktop file if possible
let app = null;
if (this._mprisProxy.DesktopEntry) {
let desktopId = '%s.desktop'.format(this._mprisProxy.DesktopEntry);
let desktopId = `${this._mprisProxy.DesktopEntry}.desktop`;
app = Shell.AppSystem.get_default().lookup_app(desktopId);
}
@@ -192,9 +192,9 @@ var MprisPlayer = class MprisPlayer {
if (!Array.isArray(this._trackArtists) ||
!this._trackArtists.every(artist => typeof artist === 'string')) {
if (typeof this._trackArtists !== 'undefined') {
log(('Received faulty track artist metadata from %s; ' +
'expected an array of strings, got %s (%s)').format(
this._busName, this._trackArtists, typeof this._trackArtists));
log(`Received faulty track artist metadata from ${
this._busName}; expected an array of strings, got ${
this._trackArtists} (${typeof this._trackArtists})`);
}
this._trackArtists = [_("Unknown artist")];
}
@@ -202,9 +202,9 @@ var MprisPlayer = class MprisPlayer {
this._trackTitle = metadata['xesam:title'];
if (typeof this._trackTitle !== 'string') {
if (typeof this._trackTitle !== 'undefined') {
log(('Received faulty track title metadata from %s; ' +
'expected a string, got %s (%s)').format(
this._busName, this._trackTitle, typeof this._trackTitle));
log(`Received faulty track title metadata from ${
this._busName}; expected a string, got ${
this._trackTitle} (${typeof this._trackTitle})`);
}
this._trackTitle = _("Unknown title");
}
@@ -212,9 +212,9 @@ var MprisPlayer = class MprisPlayer {
this._trackCoverUrl = metadata['mpris:artUrl'];
if (typeof this._trackCoverUrl !== 'string') {
if (typeof this._trackCoverUrl !== 'undefined') {
log(('Received faulty track cover art metadata from %s; ' +
'expected a string, got %s (%s)').format(
this._busName, this._trackCoverUrl, typeof this._trackCoverUrl));
log(`Received faulty track cover art metadata from ${
this._busName}; expected a string, got ${
this._trackCoverUrl} (${typeof this._trackCoverUrl})`);
}
this._trackCoverUrl = '';
}

View File

@@ -477,7 +477,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
return app;
if (appId) {
app = Shell.AppSystem.get_default().lookup_app('%s.desktop'.format(appId));
app = Shell.AppSystem.get_default().lookup_app(`${appId}.desktop`);
if (app != null)
return app;
}
@@ -614,7 +614,7 @@ function objectPathFromAppId(appId) {
}
function getPlatformData() {
let startupId = GLib.Variant.new('s', '_TIME%s'.format(global.get_current_time()));
let startupId = GLib.Variant.new('s', `_TIME${global.get_current_time()}`);
return { "desktop-startup-id": startupId };
}
@@ -627,7 +627,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
if (!GLib.Variant.is_object_path(objectPath))
throw new InvalidAppError();
let app = Shell.AppSystem.get_default().lookup_app('%s.desktop'.format(appId));
let app = Shell.AppSystem.get_default().lookup_app(`${appId}.desktop`);
if (!app)
throw new InvalidAppError();

View File

@@ -104,7 +104,7 @@ class OverviewActor extends St.BoxLayout {
in the search entry when no search is
active; it should not exceed ~30
characters. */
hint_text: _('Type to search'),
hint_text: _("Type to search…"),
track_hover: true,
can_focus: true,
});
@@ -137,7 +137,6 @@ class OverviewActor extends St.BoxLayout {
var Overview = class {
constructor() {
this._initCalled = false;
this._visible = false;
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
@@ -270,11 +269,7 @@ var Overview = class {
}
_sessionUpdated() {
const { hasOverview } = Main.sessionMode;
if (!hasOverview)
this.hide();
this.isDummy = !hasOverview;
this.isDummy = !Main.sessionMode.hasOverview;
this._createOverview();
}

View File

@@ -127,7 +127,7 @@ class SlidingControl extends St.Widget {
}
_getSlide() {
throw new GObject.NotImplementedError('_getSlide in %s'.format(this.constructor.name));
throw new GObject.NotImplementedError(`_getSlide in ${this.constructor.name}`);
}
_updateSlide() {

View File

@@ -347,7 +347,9 @@ var PadDiagram = GObject.registerClass({
return '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" ' +
'xmlns:xi="http://www.w3.org/2001/XInclude" ' +
'width="%d" height="%d">'.format(this._imageWidth, this._imageHeight) +
`width="${ // " (give xgettext the paired quotes it expects)
this._imageWidth
}" height="${this._imageHeight}"> ` + // "
'<style type="text/css">';
}
@@ -362,10 +364,10 @@ var PadDiagram = GObject.registerClass({
for (let i = 0; i < this._activeButtons.length; i++) {
let ch = String.fromCharCode('A'.charCodeAt() + this._activeButtons[i]);
css += '.%s {'.format(ch);
css += ' stroke: %s !important;'.format(ACTIVE_COLOR);
css += ' fill: %s !important;'.format(ACTIVE_COLOR);
css += '}';
css += `.${ch} {
stroke: ${ACTIVE_COLOR} !important;
fill: ${ACTIVE_COLOR} !important;
}`;
}
return css;
@@ -475,12 +477,12 @@ var PadDiagram = GObject.registerClass({
let leaderPos, leaderSize, pos;
let found, direction;
[found, pos] = this._handle.get_position_sub('#%s'.format(labelName));
[found, pos] = this._handle.get_position_sub(`#${labelName}`);
if (!found)
return [false];
[found, leaderPos] = this._handle.get_position_sub('#%s'.format(leaderName));
[found, leaderSize] = this._handle.get_dimensions_sub('#%s'.format(leaderName));
[found, leaderPos] = this._handle.get_position_sub(`#${leaderName}`);
[found, leaderSize] = this._handle.get_dimensions_sub(`#${leaderName}`);
if (!found)
return [false];
@@ -502,8 +504,8 @@ var PadDiagram = GObject.registerClass({
getButtonLabelCoords(button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let labelName = 'Label%s'.format(ch);
let leaderName = 'Leader%s'.format(ch);
let labelName = `Label${ch}`;
let leaderName = `Leader${ch}`;
return this._getItemLabelCoords(labelName, leaderName);
}
@@ -511,8 +513,8 @@ var PadDiagram = GObject.registerClass({
getRingLabelCoords(number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
let dirStr = dir == CW ? 'CW' : 'CCW';
let labelName = 'LabelRing%s%s'.format(numStr, dirStr);
let leaderName = 'LeaderRing%s%s'.format(numStr, dirStr);
let labelName = `LabelRing${numStr}${dirStr}`;
let leaderName = `LeaderRing${numStr}${dirStr}`;
return this._getItemLabelCoords(labelName, leaderName);
}
@@ -520,8 +522,8 @@ var PadDiagram = GObject.registerClass({
getStripLabelCoords(number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
let dirStr = dir == UP ? 'Up' : 'Down';
let labelName = 'LabelStrip%s%s'.format(numStr, dirStr);
let leaderName = 'LeaderStrip%s%s'.format(numStr, dirStr);
let labelName = `LabelStrip${numStr}${dirStr}`;
let leaderName = `LeaderStrip${numStr}${dirStr}`;
return this._getItemLabelCoords(labelName, leaderName);
}
@@ -868,7 +870,7 @@ var PadOsd = GObject.registerClass({
}
this._titleLabel.clutter_text.set_markup(
'<span size="larger"><b>%s</b></span>'.format(title));
`<span size="larger"><b>${title}</b></span>`);
}
_isEditedAction(type, number, dir) {
@@ -930,7 +932,7 @@ var PadOsd = GObject.registerClass({
_startButtonActionEdition(button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let key = 'button%s'.format(ch);
let key = `button${ch}`;
this._startActionEdition(key, Meta.PadActionType.BUTTON, button);
}

View File

@@ -533,9 +533,6 @@ class PanelCorner extends St.DrawingArea {
if (index < 0)
return null;
if (!(children[index] instanceof St.Widget))
return null;
if (!children[index].has_style_class_name('panel-menu') &&
!children[index].has_style_class_name('panel-button'))
return this._findRightmostButton(children[index]);
@@ -561,9 +558,6 @@ class PanelCorner extends St.DrawingArea {
if (index == children.length)
return null;
if (!(children[index] instanceof St.Widget))
return null;
if (!children[index].has_style_class_name('panel-menu') &&
!children[index].has_style_class_name('panel-button'))
return this._findLeftmostButton(children[index]);
@@ -1105,7 +1099,7 @@ class Panel extends St.Widget {
addToStatusArea(role, indicator, position, box) {
if (this.statusArea[role])
throw new Error('Extension point conflict: there is already a status indicator for role %s'.format(role));
throw new Error(`Extension point conflict: there is already a status indicator for role ${role}`);
if (!(indicator instanceof PanelMenu.Button))
throw new TypeError('Status indicator must be an instance of PanelMenu.Button');

View File

@@ -282,11 +282,8 @@ class PopupMenuItem extends PopupBaseMenuItem {
var PopupSeparatorMenuItem = GObject.registerClass(
class PopupSeparatorMenuItem extends PopupBaseMenuItem {
_init(text) {
super._init({
style_class: 'popup-separator-menu-item',
reactive: false,
can_focus: false,
});
super._init({ reactive: false,
can_focus: false });
this.label = new St.Label({ text: text || '' });
this.add(this.label);
@@ -296,12 +293,10 @@ class PopupSeparatorMenuItem extends PopupBaseMenuItem {
this._syncVisibility.bind(this));
this._syncVisibility();
this._separator = new St.Widget({
style_class: 'popup-separator-menu-item-separator',
x_expand: true,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
this._separator = new St.Widget({ style_class: 'popup-separator-menu-item',
x_expand: true,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this.add_child(this._separator);
}
@@ -462,7 +457,7 @@ class PopupImageMenuItem extends PopupBaseMenuItem {
var PopupMenuBase = class {
constructor(sourceActor, styleClass) {
if (this.constructor === PopupMenuBase)
throw new TypeError('Cannot instantiate abstract class %s'.format(this.constructor.name));
throw new TypeError(`Cannot instantiate abstract class ${this.constructor.name}`);
this.sourceActor = sourceActor;
this.focusActor = sourceActor;
@@ -546,7 +541,7 @@ var PopupMenuBase = class {
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log('Settings panel for desktop file %s could not be loaded!'.format(desktopFile));
log(`Settings panel for desktop file ${desktopFile} could not be loaded!`);
return;
}

View File

@@ -194,7 +194,7 @@ class RunDialog extends ModalDialog.ModalDialog {
if (inTerminal) {
let exec = this._terminalSettings.get_string(EXEC_KEY);
let execArg = this._terminalSettings.get_string(EXEC_ARG_KEY);
command = '%s %s %s'.format(exec, execArg, input);
command = `${exec} ${execArg} ${input}`;
}
Util.trySpawnCommandLine(command);
} catch (e) {
@@ -205,7 +205,7 @@ class RunDialog extends ModalDialog.ModalDialog {
} else {
if (input.charAt(0) == '~')
input = input.slice(1);
path = '%s/%s'.format(GLib.get_home_dir(), input);
path = `${GLib.get_home_dir()}/${input}`;
}
if (GLib.file_test(path, GLib.FileTest.EXISTS)) {

View File

@@ -1,10 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { AccountsService, Clutter, Gio,
GLib, Graphene, Meta, Shell, St } = imports.gi;
const { AccountsService, Clutter, Gio, GLib,
GnomeDesktop, GObject, Graphene, Meta, Shell, St } = imports.gi;
const Cairo = imports.cairo;
const Signals = imports.signals;
const Background = imports.ui.background;
const GnomeSession = imports.misc.gnomeSession;
const Layout = imports.ui.layout;
const OVirt = imports.gdm.oVirt;
const LoginManager = imports.misc.loginManager;
const Lightbox = imports.ui.lightbox;
@@ -24,6 +27,17 @@ const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
const DISABLE_LOCK_KEY = 'disable-lock-screen';
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
// - STANDARD_FADE_TIME is used when the session goes idle
@@ -34,6 +48,384 @@ var STANDARD_FADE_TIME = 10000;
var MANUAL_FADE_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,
* rather than through System Settings, you also need to set
@@ -55,18 +447,59 @@ var ScreenShield = class {
name: 'lockScreenGroup',
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');
this._lockDialogGroup = new St.Widget({
x_expand: true,
y_expand: true,
reactive: true,
can_focus: true,
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
name: 'lockDialogGroup',
});
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
name: 'lockScreenContents' });
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
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._lockScreenGroup);
this.actor.add_actor(this._lockDialogGroup);
this.actor.add_actor(this._lockScreenGroup);
this._presence = new GnomeSession.Presence((proxy, error) => {
if (error) {
@@ -86,14 +519,14 @@ var ScreenShield = class {
this._smartcardManager.connect('smartcard-inserted',
(manager, token) => {
if (this._isLocked && token.UsedToLogin)
this._activateDialog();
this._liftShield(true, 0);
});
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
this._oVirtCredentialsManager.connect('user-authenticated',
() => {
if (this._isLocked)
this._activateDialog();
this._liftShield(true, 0);
});
this._loginManager = LoginManager.getLoginManager();
@@ -112,12 +545,13 @@ var ScreenShield = class {
});
this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA });
this._settings.connect('changed::%s'.format(LOCK_ENABLED_KEY), this._syncInhibitor.bind(this));
this._settings.connect(`changed::${LOCK_ENABLED_KEY}`, this._syncInhibitor.bind(this));
this._lockSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
this._lockSettings.connect('changed::%s'.format(DISABLE_LOCK_KEY), this._syncInhibitor.bind(this));
this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this));
this._isModal = false;
this._hasLockScreen = false;
this._isGreeter = false;
this._isActive = false;
this._isLocked = false;
@@ -157,10 +591,39 @@ var ScreenShield = class {
this._syncInhibitor();
}
_activateDialog() {
_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) {
this._ensureUnlockDialog(true /* allowCancel */);
this._dialog.activate();
if (this._ensureUnlockDialog(onPrimary, true /* allowCancel */))
this._hideLockScreen(true /* animate */, velocity);
} else {
this.deactivate(true /* animate */);
}
@@ -175,7 +638,9 @@ var ScreenShield = class {
// LoginDialog.cancel() will grab the key focus
// on its own, so ensure it stays on lock screen
// instead
this._dialog.grab_key_focus();
this._lockScreenGroup.grab_key_focus();
} else {
this._dialog = null;
}
}
@@ -194,6 +659,55 @@ var ScreenShield = class {
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() {
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
@@ -222,6 +736,78 @@ 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.translation_y = newY;
return true;
}
_onDragEnd(_action, _actor, _eventX, _eventY, _modifiers) {
if (this._lockScreenState != MessageTray.State.HIDING)
return;
if (this._lockScreenGroup.translation_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.translation_y / h;
this._lockScreenGroup.remove_all_transitions();
this._lockScreenGroup.ease({
translation_y: 0,
duration,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
onComplete: () => {
this._lockScreenState = MessageTray.State.SHOWN;
},
});
this._maybeCancelDialog();
}
}
_onStatusChanged(status) {
if (status != GnomeSession.PresenceStatus.IDLE)
return;
@@ -281,7 +867,11 @@ var ScreenShield = class {
// This function gets called here when the user becomes active
// after we activated a lightbox
// There are two possibilities here:
// - we're called when already locked; we just go back to the lock screen curtain
// - we're called when already locked/active; isLocked or isActive is true,
// we just go back to the lock screen curtain
// (isActive == isLocked == true: normal case
// isActive == false, isLocked == true: during the fade for manual locking
// isActive == true, isLocked == false: after session idle, before lock-delay)
// - we're called because the session is IDLE but before the lightbox
// is fully shown; at this point isActive is false, so we just hide
// the lightbox, reset the activationTime and go back to the unlocked
@@ -295,7 +885,7 @@ var ScreenShield = class {
this.idleMonitor.remove_watch(this._becameActiveId);
this._becameActiveId = 0;
if (this._isLocked) {
if (this._isActive || this._isLocked) {
this._longLightbox.lightOff();
this._shortLightbox.lightOff();
} else {
@@ -323,10 +913,14 @@ var ScreenShield = class {
this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter;
this._isLocked = true;
this._ensureUnlockDialog(true);
if (this._ensureUnlockDialog(true, true))
this._hideLockScreen(false, 0);
}
_hideLockScreenComplete() {
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
this._lockScreenState = MessageTray.State.HIDDEN;
this._lockScreenGroup.hide();
@@ -336,13 +930,13 @@ var ScreenShield = class {
}
}
_hideLockScreen(animate) {
_hideLockScreen(animate, velocity) {
if (this._lockScreenState == MessageTray.State.HIDDEN)
return;
this._lockScreenState = MessageTray.State.HIDING;
this._lockDialogGroup.remove_all_transitions();
this._lockScreenGroup.remove_all_transitions();
if (animate) {
// Tween the lock screen out of screen
@@ -350,14 +944,16 @@ var ScreenShield = class {
// use the same speed regardless of original position
// if velocity is specified, it's in pixels per milliseconds
let h = global.stage.height;
let delta = h + this._lockDialogGroup.translation_y;
let velocity = global.stage.height / CURTAIN_SLIDE_TIME;
let delta = h + this._lockScreenGroup.translation_y;
let minVelocity = global.stage.height / CURTAIN_SLIDE_TIME;
velocity = Math.max(minVelocity, velocity);
let duration = delta / velocity;
this._lockDialogGroup.ease({
this._lockScreenGroup.ease({
translation_y: -h,
duration,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
onComplete: () => this._hideLockScreenComplete(),
});
} else {
@@ -367,7 +963,7 @@ var ScreenShield = class {
this._cursorTracker.set_pointer_visible(true);
}
_ensureUnlockDialog(allowCancel) {
_ensureUnlockDialog(onPrimary, allowCancel) {
if (!this._dialog) {
let constructor = Main.sessionMode.unlockDialog;
if (!constructor) {
@@ -379,7 +975,7 @@ var ScreenShield = class {
this._dialog = new constructor(this._lockDialogGroup);
let time = global.get_current_time();
if (!this._dialog.open(time)) {
if (!this._dialog.open(time, onPrimary)) {
// This is kind of an impossible error: we're already modal
// by the time we reach this...
log('Could not open login dialog: failed to acquire grab');
@@ -388,12 +984,9 @@ var ScreenShield = class {
}
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.grab_key_focus();
return true;
}
@@ -410,31 +1003,94 @@ var ScreenShield = class {
if (this._lockScreenState != MessageTray.State.HIDDEN)
return;
this._ensureLockScreen();
this._lockDialogGroup.scale_x = 1;
this._lockDialogGroup.scale_y = 1;
this._lockScreenGroup.show();
this._lockScreenState = MessageTray.State.SHOWING;
let fadeToBlack = params.fadeToBlack;
if (params.animateLockScreen) {
this._lockDialogGroup.translation_y = -global.screen_height;
this._lockDialogGroup.remove_all_transitions();
this._lockDialogGroup.ease({
this._lockScreenGroup.translation_y = -global.screen_height;
this._lockScreenGroup.remove_all_transitions();
this._lockScreenGroup.ease({
translation_y: 0,
duration: Overview.ANIMATION_TIME,
duration: MANUAL_FADE_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this._lockScreenShown({ fadeToBlack, animateFade: true });
},
});
} else {
this._lockDialogGroup.translation_y = 0;
this._lockScreenGroup.translation_y = 0;
this._lockScreenShown({ fadeToBlack, animateFade: false });
}
this._dialog.grab_key_focus();
this._lockScreenGroup.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) {
if (this._dialog && !this._isGreeter) {
this._dialog.destroy();
this._dialog = null;
}
this._checkArrowAnimation();
let motionId = global.stage.connect('captured-event', (stage, event) => {
if (event.type() == Clutter.EventType.MOTION) {
this._cursorTracker.set_pointer_visible(true);
@@ -446,6 +1102,7 @@ var ScreenShield = class {
this._cursorTracker.set_pointer_visible(false);
this._lockScreenState = MessageTray.State.SHOWN;
this._lockScreenScrollCounter = 0;
if (params.fadeToBlack && params.animateFade) {
// Take a beat
@@ -468,11 +1125,52 @@ var ScreenShield = class {
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() {
this._onUserBecameActive();
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() {
return this._isLocked;
}
@@ -493,8 +1191,13 @@ var ScreenShield = class {
}
_continueDeactivate(animate) {
this._hideLockScreen(animate);
this._hideLockScreen(animate, 0);
if (this._hasLockScreen)
this._clearLockScreen();
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
if (Main.sessionMode.currentMode == 'unlock-dialog')
Main.sessionMode.popMode('unlock-dialog');
@@ -520,8 +1223,9 @@ var ScreenShield = class {
}
this._lockDialogGroup.ease({
translation_y: -global.screen_height,
duration: Overview.ANIMATION_TIME,
scale_x: 0,
scale_y: 0,
duration: animate ? Overview.ANIMATION_TIME : 0,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._completeDeactivate(),
});
@@ -558,11 +1262,10 @@ var ScreenShield = class {
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
this._ensureUnlockDialog(true);
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;
if (!this._isGreeter)
Main.sessionMode.pushMode('unlock-dialog');

View File

@@ -231,18 +231,18 @@ var SearchResultsBase = GObject.registerClass({
this.provider.getResultMetas(metasNeeded, metas => {
if (this._cancellable.is_cancelled()) {
if (metas.length > 0)
log('Search provider %s returned results after the request was canceled'.format(this.provider.id));
log(`Search provider ${this.provider.id} returned results after the request was canceled`);
callback(false);
return;
}
if (metas.length != metasNeeded.length) {
log('Wrong number of result metas returned by search provider %s: '.format(this.provider.id) +
'expected %d but got %d'.format(metasNeeded.length, metas.length));
log(`Wrong number of result metas returned by search provider ${this.provider.id}: ` +
`expected ${metasNeeded.length} but got ${metas.length}`);
callback(false);
return;
}
if (metas.some(meta => !meta.name || !meta.id)) {
log('Invalid result meta returned from search provider %s'.format(this.provider.id));
log(`Invalid result meta returned from search provider ${this.provider.id}`);
callback(false);
return;
}
@@ -609,7 +609,7 @@ var SearchResultsView = GObject.registerClass({
this._searchTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 150, this._onSearchTimeout.bind(this));
let escapedTerms = this._terms.map(term => Shell.util_regex_escape(term));
this._highlightRegex = new RegExp('(%s)'.format(escapedTerms.join('|')), 'gi');
this._highlightRegex = new RegExp(`(${escapedTerms.join('|')})`, 'gi');
this.emit('terms-changed');
}

Some files were not shown because too many files have changed in this diff Show More