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
166 changed files with 16422 additions and 20992 deletions

View File

@@ -46,20 +46,6 @@ eslint:
- reports - reports
when: always when: always
potfile_check:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: review
script:
- ./.gitlab-ci/check-potfiles.sh
<<: *only_default
no_template_check:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: review
script:
- ./.gitlab-ci/check-template-strings.sh
<<: *only_default
build: build:
image: registry.gitlab.gnome.org/gnome/mutter/master:v3 image: registry.gitlab.gnome.org/gnome/mutter/master:v3
stage: build stage: build

View File

@@ -19,7 +19,7 @@ fi
function commit_message_has_url() { function commit_message_has_url() {
commit=$1 commit=$1
commit_message=$(git show -s --format='format:%b' $commit) 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 $? return $?
} }

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
srcdirs="js src subprojects/extensions-tool"
globs=('*.js' '*.c')
# find source files that contain gettext keywords
files=$(grep -lR ${globs[@]/#/--include=} '\(gettext\|[^I_)]_\)(' $srcdirs)
# find those that aren't listed in POTFILES.in
missing=$(for f in $files; do ! grep -q ^$f po/POTFILES.in && echo $f; done)
if [ ${#missing} -eq 0 ]; then
exit 0
fi
cat >&2 <<EOT
The following files are missing from po/POTFILES.po:
EOT
for f in $missing; do
echo " $f" >&2
done
echo >&2
exit 1

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
# find files from POTFILES.in that use js template strings
baddies=$(grep -l '${' $(grep ^js po/POTFILES.in))
if [ ${#baddies} -eq 0 ]; then
exit 0
fi
cat >&2 <<EOT
xgettext cannot handle template strings properly, so we ban their use
in files with translatable strings.
The following files are listed in po/POTFILES.in and use template strings:
EOT
for f in $baddies; do
echo " $f" >&2
done
echo >&2
exit 1

114
NEWS
View File

@@ -1,117 +1,3 @@
3.35.92
=======
* Plug a memory leak [Jonas D.; !1015]
* Fix missing "back" button on login screen [Florian; #2228]
* Fix width of window preview titles in overview [Jonas D.; #58]
* Fix looking glass text with light style variant [Feichtmeier; !1023]
* Center unlock entry [Florian; !1021]
* Hide overlay scrollbars in notification popup [Jonas D.; !1013]
* Work around add_actor() slowness in icon spring animation [Daniel; !1002]
* Add disable-animations heuristics [Jonas Å.; !757]
* Fix visual glitches in on-screen keyboard [Carlos; #2214]
* Fix clearing changed textures from cache [Florian; #2244]
* Fix visual glitch in sliders [Daniel; #1569]
* Stop using dedicated lock screen background [Florian; !1001]
* Fix entries disappearing after authentication errors [Florian; #2236]
* Fix crash when animations are disabled [Florian; #2255]
* Fix passing pointer events to clients when magnified [Jonas D.; !993]
* Fix keynav on new lock screen [Florian; #2210]
* Avoid short-lived allocations on actor removal [Christian; #2263]
* Fix super-sized default avatars in user list [Florian, Sam; #2242]
* Leave overview when locking the screen [Jonas D.; !1043]
* Hide message list on login screen [Florian; #2241]
* Avoid IO on the main thread [Christian, Florian; !1050, !1051]
* Fix window animations getting stuck when client doesn't respond [Jonas; !1055]
* Only subscribe to touchpad events for touchpad gestures [Daniel; !925]
* Start X11 session services before Xwayland clients [Carlos; !836, !1056]
* Only show switch-user button with unlock prompt [Florian; !1029]
* Misc. bug fixes and cleanups [Jonas D., Florian, Georges, Jonas Å., Daniel,
Jakub, Philippe; !1018, !1020, !1024, !1027, !1026, !1022, !1031, !1035,
!1032, !1025, !1039, #2157, !1037, !1042, !1047, !1048, #2270, !1046,
!167, !1016]
Contributors:
Jonas Dreßler, Feichtmeier, Carlos Garnacho, Christian Hergert, Sam Hewitt,
Florian Müllner, Georges Basile Stavracas Neto, Jakub Steiner, Philippe Troin,
Daniel van Vugt, Jonas Ådahl
Translators:
Danial Behzadi [fa], Efstathios Iosifidis [el], Daniel Mustieles [es],
Sabri Ünal [tr], sicklylife [ja], Piotr Drąg [pl], Jordi Mas [ca],
Anders Jonsson [sv], Chao-Hsiung Liao [zh_TW], Asier Sarasua Garmendia [eu],
Rafael Fontenelle [pt_BR], Марко Костић [sr], Changwoo Ryu [ko],
Charles Monzat [fr], Jiri Grönroos [fi], Jor Teron [mjw], Bruce Cowan [en_GB],
Emin Tufan Çetin [tr], Alan Mortensen [da], Balázs Úr [hu], Fran Dieguez [gl],
Kukuh Syafaat [id]
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 3.35.3
====== ======
* Add discrete GPU support for NVidia drivers [Bastien; #1810] * Add discrete GPU support for NVidia drivers [Bastien; #1810]

View File

@@ -57,19 +57,5 @@
<method name="GetWindows"> <method name="GetWindows">
<arg name="windows" direction="out" type="a{ta{sv}}" /> <arg name="windows" direction="out" type="a{ta{sv}}" />
</method> </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> </interface>
</node> </node>

View File

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

View File

@@ -9,9 +9,16 @@
<file>dash-placeholder.svg</file> <file>dash-placeholder.svg</file>
<file>gnome-shell.css</file> <file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.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 alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file>no-events.svg</file> <file>no-events.svg</file>
<file>no-notifications.svg</file> <file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>pad-osd.css</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-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> <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-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-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/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>process-working.svg</file>
<file>toggle-off.svg</file> <file>toggle-off.svg</file>
<file>toggle-off-dark.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 = [ desktop_files = [
'org.gnome.Shell.desktop', 'org.gnome.Shell.desktop',
'org.gnome.Extensions.desktop', 'gnome-shell-extension-prefs.desktop'
] ]
service_files = [] service_files = []
@@ -43,7 +43,6 @@ endforeach
subdir('dbus-interfaces') subdir('dbus-interfaces')
subdir('icons')
subdir('theme') subdir('theme')
data_resources = [ data_resources = [

View File

@@ -19,13 +19,13 @@ $error_color: #ff8080;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%)); $success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%)); $destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$osd_fg_color: #eeeeec; $osd_fg_color: $fg_color;
$osd_text_color: white; $osd_text_color: if($variant == 'light', #000, #fff);
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04); $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_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_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
$osd_borders_color: transparentize(black, 0.3); $osd_borders_color: if($variant == 'light', rgba(255,255,255,0.1), rgba(0,0,0,0.7));
$osd_outer_borders_color: transparentize(white, 0.84); $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)); $shadow_color: if($variant == 'light', rgba(0,0,0,0.1), rgba(0,0,0,0.2));

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

View File

@@ -137,7 +137,7 @@
// normal button // normal button
@if $t==normal { @if $t==normal {
color: $tc; color: $tc;
background-color: lighten($c, 3%); background-color: lighten($c, 3%) !important;
border-color: draw_border_color($c); border-color: draw_border_color($c);
@include draw_shadows($button_shadow); @include draw_shadows($button_shadow);
// box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1); // box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
@@ -150,14 +150,14 @@
color: $tc; color: $tc;
text-shadow: 0 1px $text_shadow_color; text-shadow: 0 1px $text_shadow_color;
icon-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; //border-color: $selected_bg_color;
} }
// hover button // hover button
@else if $t==hover { @else if $t==hover {
color: $tc; 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)); border-color: if($variant == 'light', draw_border_color(lighten($c, 7%)), draw_border_color($c));
@include draw_shadows($button_shadow); @include draw_shadows($button_shadow);
text-shadow: 0 1px $text_shadow_color; text-shadow: 0 1px $text_shadow_color;
@@ -167,7 +167,7 @@
// active button // active button
@else if $t==active { @else if $t==active {
color: $tc; 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%))); border-color: draw_border_color(if($variant == 'light', $c, darken($c,7%)));
text-shadow: none; text-shadow: none;
icon-shadow: none; icon-shadow: none;
@@ -178,7 +178,7 @@
@else if $t==insensitive { @else if $t==insensitive {
color: $insensitive_fg_color; color: $insensitive_fg_color;
border-color: $insensitive_borders_color; border-color: $insensitive_borders_color;
background-color: $insensitive_bg_color; background-color: $insensitive_bg_color !important;
box-shadow: none; box-shadow: none;
text-shadow: none; text-shadow: none;
icon-shadow: none; icon-shadow: none;
@@ -194,38 +194,3 @@
icon-shadow: none; 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 */ /* WIDGETS */
@import 'widgets/app-grid';
// Primary widgets @import 'widgets/app-switcher';
@import 'widgets/base';
@import 'widgets/entries';
@import 'widgets/buttons'; @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/calendar';
@import 'widgets/message-list'; @import 'widgets/check-box';
@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/corner-ripple'; @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/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-entry';
@import 'widgets/search-results'; @import 'widgets/search-results';
@import 'widgets/app-grid'; @import 'widgets/slider';
@import 'widgets/dash'; @import 'widgets/switches';
@import 'widgets/workspace-thumbnails';
// A11y / misc
@import 'widgets/a11y';
@import 'widgets/misc';
@import 'widgets/tiled-previews'; @import 'widgets/tiled-previews';
@import 'widgets/keyboard'; @import 'widgets/window-picker';
@import 'widgets/looking-glass'; @import 'widgets/workspace-switcher';
// Lock / login screens
@import 'widgets/login-dialog';
@import 'widgets/screen-shield';

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 { .overview-icon {
icon-size: $app_icon_size; 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; $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 // Icon tiles in the app grid
.app-well-app, .app-well-app,
%app-well-app { .app-folder {
@include overview-icon($app_grid_fg_color);
.overview-icon.overview-icon-with-label { .overview-icon {
padding: 10px 8px 5px 8px; @extend %icon_tile;
color: $app_grid_fg_color !important;
}
> StBoxLayout { &:selected {
spacing: $base_spacing; .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 Folders */
.app-folder { .app-folder {
.overview-icon { .overview-icon {
@extend %icon_tile;
} }
} }
// expanded folder // expanded folder
.app-folder-dialog { .app-folder-dialog {
border-radius: $modal_radius * 1.5; border-radius: 8px;
border: 1px solid $osd_outer_borders_color; spacing: 24px;
spacing: 12px;
background-color: transparentize(darken($osd_bg_color,10%), 0.05); background-color: transparentize(darken($osd_bg_color,10%), 0.05);
& .folder-name-container { & .folder-name-container {
padding: 24px 36px 0; padding: 12px 18px;
spacing: 12px; spacing: 12px;
& .folder-name-label, & .folder-name-label,
@@ -73,10 +117,6 @@ $app_grid_fg_color: #fff;
& > StIcon { icon-size: 16px } & > StIcon { icon-size: 16px }
} }
} }
& StButton#vhandle,
& StButton#vhandle:hover,
& StButton#vhandle:active { background-color: transparent; }
} }
.app-folder-dialog-container { .app-folder-dialog-container {
padding: 12px; padding: 12px;
@@ -133,6 +173,11 @@ $app_grid_fg_color: #fff;
padding: 0px 88px 10px 88px; 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 // Label when no frequent apps
.no-frequent-applications-label { @extend %status_text; } .no-frequent-applications-label { @extend %status_text; }
@@ -153,34 +198,40 @@ $app_grid_fg_color: #fff;
// buttons // buttons
.app-view-control { .app-view-control {
padding: 4px 32px; padding: $base_padding $base_padding*5;
margin: 0 4px; margin: 0;
background-color: transparentize($osd_bg_color, 0.5);
border-width: 1px;
color: darken($osd_fg_color, 25%);
&, &:hover, &:checked { &:hover {
@include button(undecorated); background-color: transparentize($osd_bg_color, 0.5) !important;
box-shadow:none !important;
color: darken($osd_fg_color, 25%); color: darken($osd_fg_color, 25%);
} }
&:hover {
color: $osd_fg_color;
box-shadow: inset 0 -2px darken($osd_fg_color, 25%);
}
&:active { &: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 { &:checked {
color: $osd_fg_color; background-color: $selected_bg_color !important;
box-shadow: inset 0 -2px $selected_bg_color; 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 { &:first-child {
border-right-width: 0; border-right-width: 0 !important;
border-radius: 0; border-radius: $base_border_radius 0 0 $base_border_radius;
} }
&:last-child { &:last-child {
border-radius: 0; border-radius: 0 $base_border_radius $base_border_radius 0;
} }
} }

View File

@@ -53,15 +53,3 @@
color: $fg_color; 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 */ /* Date/Time Menu */
.clock-display-box { .clock-display-box { spacing: $base_spacing; }
spacing: $base_spacing / 2;
.clock {
padding-left: $base_padding;
padding-right: $base_padding;
}
}
// overall menu // overall menu
#calendarArea { #calendarArea {
padding:0; padding:0;
margin:0;
} }
// Calendar menu side column // Calendar menu side column
.datemenu-calendar-column { .datemenu-calendar-column {
spacing: $base_spacing; spacing: 0;
border: 0 solid $bubble_borders_color; 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; } &:ltr {margin-right: $base_margin * 2; border-left-width: 1px; }
&:rtl {margin-left: $base_margin * 2; border-right-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 { .datemenu-displays-section {
margin:0;
} }
.datemenu-displays-box { .datemenu-displays-box {
spacing: $base_spacing; spacing: $base_spacing;
margin:0;
// world clocks and weather
.world-clocks-button,
.weather-button {
@extend %notification_bubble;
padding:$base_padding !important;
}
} }
} }
.events-section-title { .events-section-title {
@include notification_bubble($flat: true);
color: desaturate(darken($fg_color,40%), 10%); color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold; font-weight: bold;
border-radius: 4px;
padding: .4em; 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 */
.calendar { .calendar {
@include notification_bubble;
padding: $base_padding;
// month // month
.calendar-month-label { .calendar-month-label {
@@ -110,7 +132,6 @@
@include fontsize($base_font_size - 4); @include fontsize($base_font_size - 4);
} }
} }
.calendar-day { //border collapse hack - see calendar.js .calendar-day { //border collapse hack - see calendar.js
border-width: 0; border-width: 0;
} }
@@ -119,12 +140,8 @@
border-top-width: 1px; border-top-width: 1px;
} }
.calendar-day-left { .calendar-day-left { border-left-width: 1px; }
border-left-width: 1px;
}
.calendar-work-day {} .calendar-work-day {}
.calendar-nonwork-day { .calendar-nonwork-day {
color: $insensitive_fg_color; color: $insensitive_fg_color;
} }
@@ -144,14 +161,13 @@
&:active,&:selected { &:active,&:selected {
background-color: $selected_bg_color; background-color: $selected_bg_color;
color: $selected_fg_color; color: $selected_fg_color;
&:hover,&:focus { &:hover,&:focus {
background-color:lighten($selected_bg_color, 3%); background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color; color: $selected_fg_color;
} }
} }
}
}
.calendar-day-with-events { .calendar-day-with-events {
color: lighten($fg_color,10%); color: lighten($fg_color,10%);
font-weight: bold; font-weight: bold;
@@ -160,6 +176,7 @@
.calendar-other-month-day { .calendar-other-month-day {
color: transparentize($fg_color ,0.5); color: transparentize($fg_color ,0.5);
opacity: 0.5;
} }
.calendar-week-number { .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-rows: $base_spacing;
spacing-columns: $base_spacing * 2; 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 // title
.world-clocks-header { .world-clocks-header {
color: desaturate(darken($fg_color,40%), 10%); color: desaturate(darken($fg_color,40%), 10%);
@@ -214,49 +266,3 @@
@include fontsize($base_font_size - 1); @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 // just a simple change to the border radius position
&:rtl { border-radius: 0 0 0 $ripple_size + 2px; } &: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); @include fontsize($base_font_size - 2);
padding: ($dash_spacing / 2) 0; padding: ($dash_spacing / 2) 0;
//fixme: can't have non uniform borders :(
border-radius: 0 $dash_border_radius $dash_border_radius 0; border-radius: 0 $dash_border_radius $dash_border_radius 0;
border-left-width: 0; border-left-width: 0 !important;
&:rtl { &:rtl {
border-radius: $dash_border_radius 0 0 $dash_border_radius; border-radius: $dash_border_radius 0 0 $dash_border_radius;
border-right-width: 0; border-right-width: 0 !important;
} }
.placeholder { .placeholder {
@@ -48,13 +49,36 @@ $dash_border_radius: $modal_radius * 1.5;
// Show apps button // Show apps button
.show-apps { .show-apps {
@include overview-icon($osd_fg_color); color: $osd_fg_color;
& .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
&:hover,
&:focus, &: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 { .overview-icon {
background-color: darken($osd_bg_color,10%); background-color: darken($osd_bg_color,10%);
}
}
&:checked, &:focus {
.show-apps-icon {
color: $fg_color; color: $fg_color;
transition-duration: 100ms;
} }
} }
} }

View File

@@ -1,9 +1,5 @@
/* Modal Dialogs */ /* Modal Dialogs */
.headline {
@include fontsize($base_font_size + 1);
}
.modal-dialog { .modal-dialog {
border-radius: $modal_radius; border-radius: $modal_radius;
@extend %bubble_panel; @extend %bubble_panel;
@@ -19,7 +15,12 @@
} }
} }
.mount-dialog-subject {
@include fontsize($base_font_size + 3);
}
/* End Session Dialog */ /* End Session Dialog */
.end-session-dialog { .end-session-dialog {
width: 30em; width: 30em;
@@ -37,11 +38,6 @@
text-align: center; text-align: center;
font-size: 18pt; font-size: 18pt;
font-weight: 800; font-weight: 800;
&.leightweight {
font-size: 13pt;
font-weight: 800;
}
} }
.message-dialog-description { text-align: center; } .message-dialog-description { text-align: center; }
} }
@@ -88,58 +84,76 @@
/* Password or Authentication Dialog */ /* Password or Authentication Dialog */
.prompt-dialog { .prompt-dialog {
width: 28em; //this is the width of the entire modal popup
width: 34em;
.modal-dialog-content-box { .message-dialog-content { spacing: $base_spacing * 4; }
margin-bottom: 24px; .message-dialog-title { color: lighten($fg_color,15%); }
}
} }
.prompt-dialog-password-grid { .prompt-dialog-description:rtl {
spacing-rows: 8px; text-align: right;
spacing-columns: 4px;
.prompt-dialog-password-entry {
width: auto;
// 4px (spacing) + 16px (spinner-width)
&:ltr { margin-left: 20px; }
&:rtl { margin-right: 20px; }
}
} }
.prompt-dialog-password-layout { .prompt-dialog-password-box {
spacing: 8px; spacing: 1em;
} padding-bottom: 1em;
.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-error-label { .prompt-dialog-error-label {
@include fontsize($base_font_size - 1);
color: $warning_color; 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 */
.polkit-dialog-user-layout { .polkit-dialog-user-layout {
text-align: center; padding-left: 10px;
spacing: 8px; spacing: 10px;
margin-bottom: 6px; &:rtl {
padding-left: 0px;
.polkit-dialog-user-icon { padding-right: 10px;
border-radius: 99px;
background-size: contain;
} }
.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 */ /* Audio selection dialog */
@@ -166,3 +180,20 @@
.audio-selection-device-icon { .audio-selection-device-icon {
icon-size: $base_icon_size * 4; 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 // IBus Candidate Popup
.candidate-popup-boxpointer {
@extend .popup-menu-boxpointer;
}
.candidate-popup-content { .candidate-popup-content {
padding: 0.5em; padding: 0.5em;
spacing: 0.3em; 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 // draw keys using button function
#keyboard { #keyboard {
background-color: transparentize(if($variant=='light', darken($bg_color, 5%), darken($bg_color, 8%)), 0.1); 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 { .page-indicator {
padding: $base_padding; padding: $base_padding;
@@ -52,6 +52,10 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// non-character keys // non-character keys
&.default-key { &.default-key {
// size of the icon asset
background-size: 24px;
@include button(normal, $c:$default_key_bg_color); @include button(normal, $c:$default_key_bg_color);
&:hover, &:checked {@include button(hover, $c: $default_key_bg_color);} &:hover, &:checked {@include button(hover, $c: $default_key_bg_color);}
&:active { @include button(active, $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 is suggested-action
&.enter-key { &.enter-key {
background-image: url("resource:///org/gnome/shell/theme/key-enter.svg");
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color); @include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
&:hover, &:checked { @include button(hover, $c: lighten($selected_bg_color, 3%));} &:hover, &:checked { @include button(hover, $c: lighten($selected_bg_color, 3%));}
&:active {@include button(active, $c: darken($selected_bg_color, 2%));} &:active {@include button(active, $c: darken($selected_bg_color, 2%));}
} }
&.shift-key-uppercase { color: $selected_bg_color } // key assets
&.shift-key-lowercase {background-image: url("resource:///org/gnome/shell/theme/key-shift.svg");}
StIcon { icon-size: 1.125em; } &.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 // long press on a key popup

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-logo-bin { padding: 24px 0px; }
.login-dialog-banner { color: darken($osd_fg_color,10%); } .login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { width: 23em; spacing: 5px; } .login-dialog-button-box { spacing: 5px; }
.login-dialog-message { text-align: center; } .login-dialog-message-warning { color: $warning_color; }
.login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; } .login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
.login-dialog-user-selection-box { padding: 100px 0px; } .login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label { .login-dialog-not-listed-label {
@@ -118,7 +100,7 @@
} }
.login-dialog-user-list-item { .login-dialog-user-list-item {
border-radius: $base_border_radius + 4px; border-radius: 5px;
padding: 6px; padding: 6px;
color: darken($osd_fg_color,30%); color: darken($osd_fg_color,30%);
&:ltr .user-widget { padding-right: 1em; } &:ltr .user-widget { padding-right: 1em; }
@@ -131,25 +113,18 @@
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; } &:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
} }
.login-dialog-username,
.user-widget-label { .user-widget-label {
color: $osd_fg_color; color: $osd_fg_color;
}
.user-widget.horizontal .user-widget-label {
@include fontsize($base_font_size + 2); @include fontsize($base_font_size + 2);
font-weight: bold; font-weight: bold;
text-align: left; text-align: left;
padding-left: 15px; padding-left: 15px;
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
} }
.user-widget.vertical .user-widget-label { .user-widget-label {
@include fontsize($base_font_size + 5); &:ltr { padding-left: 14px; }
text-align: center; &:rtl { padding-right: 14px; }
font-weight: normal;
padding-top: 16px;
} }
.login-dialog-prompt-layout { .login-dialog-prompt-layout {
@@ -159,12 +134,18 @@
width: 23em; width: 23em;
} }
.login-dialog-prompt-entry {
height: 1.5em;
}
.login-dialog-prompt-label { .login-dialog-prompt-label {
color: darken($osd_fg_color, 20%); color: darken($osd_fg_color, 20%);
@include fontsize($base_font_size + 1); @include fontsize($base_font_size + 1);
padding-top: 1em; 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; background-color: $osd_bg_color;
spacing: $base_spacing; spacing: $base_spacing;
padding: 4px; padding: 4px;
border: 1px solid transparentize($osd_fg_color, 0.8); border: 2px solid transparentize($osd_fg_color, 0.8);
border-radius: $base_border_radius; border-top-width:0;
color: $osd_fg_color; border-radius: 0 0 $base_border_radius $base_border_radius;
& > #Toolbar { & > #Toolbar {
border: none; border: none;
border-radius: $base_border_radius; border-radius: $base_border_radius;
background-color: $osd_bg_color; background-color: darken($osd_bg_color, 10%);
} }
.labels { spacing: $base_spacing; } .labels { spacing: $base_spacing; }
@@ -20,18 +20,19 @@
-natural-hpadding: $base_padding * 2; -natural-hpadding: $base_padding * 2;
-minimum-hpadding: 6px; -minimum-hpadding: 6px;
font-weight: bold; font-weight: bold;
color: darken($osd_fg_color, 15%); color: $fg_color;
transition-duration: 100ms; transition-duration: 100ms;
padding-left: .3em; padding-left: .3em;
padding-right: .3em; padding-right: .3em;
border-bottom-width: 2px;
&:hover { &:hover {
color: $osd_fg_color; color: white;
text-shadow: black 0px 2px 2px;
} }
&:selected { &:selected {
border-bottom-width: 2px; border-bottom-width: 2px;
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color, 5%); border-color: lighten($selected_bg_color,5%);
color: $osd_fg_color; color: white;
text-shadow: black 0px 2px 2px;
} }
} }
StBoxLayout#EvalBox { padding: 4px; spacing: $base_spacing; } StBoxLayout#EvalBox { padding: 4px; spacing: $base_spacing; }
@@ -40,17 +41,12 @@
.lg-dialog { .lg-dialog {
StEntry { StEntry {
background-color: transparentize(lighten($osd_bg_color, 5%), 0.4); selection-background-color: #bbbbbb;
color: $osd_fg_color; selected-color: $osd_bg_color;
border-color: transparentize($osd_fg_color, 0.8);
min-height: 22px;
selection-background-color: $selected_bg_color;
selected-color: $selected_fg_color;
} }
.shell-link { .shell-link {
color: $link_color; color: #999999;
&:hover { color: lighten($link_color, 10%); } &:hover { color: #dddddd; }
&:active { color: darken($link_color, 10%); }
} }
} }
@@ -64,7 +60,7 @@
} }
.lg-obj-inspector-button { .lg-obj-inspector-button {
border: 1px solid $osd_borders_color; border: 1px solid gray;
padding: 4px; padding: 4px;
border-radius: $base_border_radius; border-radius: $base_border_radius;
&:hover { border: 1px solid #ffffff; } &:hover { border: 1px solid #ffffff; }
@@ -79,8 +75,7 @@
} }
.lg-extension { .lg-extension {
border: 1px solid lighten($osd_borders_color, 5%); border: 1px solid $osd_borders_color;
background-color: lighten($osd_bg_color, 5%);
border-radius: $base_border_radius; border-radius: $base_border_radius;
padding: 4px; padding: 4px;
} }

View File

@@ -11,7 +11,7 @@
.message-list-sections { .message-list-sections {
spacing: $base_spacing; spacing: $base_spacing;
margin: 0 $base_margin * 4; // to account for scrollbar margin: $base_margin * 4; // to account for scrollbar
} }
.message-list-section, .message-list-section,
@@ -19,61 +19,40 @@
spacing: $base_spacing; spacing: $base_spacing;
} }
.message-list-section-list {
&:ltr {padding:0;}
&:rtl {padding:0;}
}
// do-not-disturb + clear button // do-not-disturb + clear button
.message-list-controls { .message-list-controls {
margin: ($base_margin * 2) ($base_margin * 4) 0; margin: $base_margin $base_margin*2;
// NOTE: remove the padding if notification_bubble could remove margin for drop shadow spacing: $base_spacing;
padding: $base_margin;
spacing: $base_spacing * 2;
} }
// message bubbles // message bubbles
.message { .message {
@include notification_bubble; @extend %notification_bubble;
// icon container // title
.message-icon-bin { .message-title {
padding: ($base_padding * 3) 0 ($base_padding * 3) ($base_padding * 2); color: $fg_color;
font-weight: bold;
&:rtl { margin-bottom:4px;
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;
}
} }
// content // content
.message-content { .message-content {
padding: $base_padding + $base_margin * 2; color: darken($fg_color, 10%);
spacing: 4px; padding: $base_padding 0;
} margin:$base_margin * 2;
&:ltr {
// title margin-left: $base_margin;
.message-title { padding-right:$base_padding;
font-weight: bold; }
} &:rtl {
margin-right: $base_margin;
// secondary container in title box padding-left:$base_padding;
.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;
} }
} }
@@ -84,15 +63,48 @@
&:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); } &:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); }
} }
// body
.message-body {
color: darken($fg_color, 10%);
}
}
// URLs in messages // icon container
.url-highlighter { .message-icon-bin {
link-color: $link_color; 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 */ /* Media Controls */
@@ -113,9 +125,9 @@
&:insensitive { color: darken($fg_color,40%); } &:insensitive { color: darken($fg_color,40%); }
// fix border-radius for last button // fix border-radius for last button on hover
&:last-child:ltr { border-radius: 0 $base_border_radius+2 $base_border_radius+2 0; } &:last-child:ltr { &:hover {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; } &:last-child:rtl { &:hover {border-radius: $base_border_radius+2 0 0 $base_border_radius+2;} }
} }
// album-art // album-art
@@ -130,5 +142,6 @@
border: 1px solid transparent; border: 1px solid transparent;
border-radius: $base_border_radius; border-radius: $base_border_radius;
icon-size: $base_icon_size * 2 !important; 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 // Rubberband for select-area screenshots
.select-area-rubberband { .select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7); background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color; 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
.user-icon { .user-icon {
background-size: contain; background-size: contain;
@@ -12,33 +35,22 @@
&:hover { &:hover {
color: lighten($osd_fg_color,30%); color: lighten($osd_fg_color,30%);
} }
& StIcon {
background-color: transparentize($osd_fg_color,0.95);
border-radius: 99px;
}
} }
.user-widget.vertical .user-icon { // Input Source Switcher
icon-size: $base_icon_size * 6; // 128px .input-source-switcher-symbol {
font-size: 34pt;
& StIcon { width: 96px;
padding: $base_padding * 3 + 2px; // 20px height: 96px;
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;
}
} }
.user-widget.horizontal .user-icon { // Window cycler highlight
icon-size: $base_icon_size * 4; // 64px .cycler-highlight {
border: 5px solid $selected_bg_color;
& StIcon {
padding: $base_padding * 2 ; // 12px
width: $base_icon_size * 2.5; height: $base_icon_size * 2.5; // 40px;
}
} }
// Text
.headline { @include fontsize($base_font_size + 1); }
.lightbox { background-color: black; } .lightbox { background-color: black; }
.flashspot { background-color: white; } .flashspot { background-color: white; }
@@ -48,8 +60,8 @@
// Caps-lock warning // Caps-lock warning
.caps-lock-warning-label { .caps-lock-warning-label {
text-align: center;
padding-bottom: 8px; padding-bottom: 8px;
padding-left: 6.2em;
@include fontsize($base_font_size - 1); @include fontsize($base_font_size - 1);
color: $warning_color; color: $warning_color;
} }

View File

@@ -7,8 +7,39 @@ $notification_banner_width: 34em;
.notification-banner { .notification-banner {
min-height: $notification_banner_height; min-height: $notification_banner_height;
width: $notification_banner_width; 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 { .notification-actions {
padding-top: 0;
spacing: 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%; 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 bubbles
.chat-body { spacing: 5px; } .chat-body { spacing: 5px; }
.chat-response { margin: 5px; } .chat-response { margin: 5px; }

View File

@@ -2,8 +2,8 @@
// a.k.a. the panel // a.k.a. the panel
$panel_corner_radius: $base_border_radius+1; $panel_corner_radius: $base_border_radius+1;
$panel_bg_color: #000; $panel_bg_color: if($variant == 'light', rgba(0,0,0,0.9), #000);
$panel_fg_color: #ccc; $panel_fg_color: if($variant == 'light', darken($fg_color, 15%), darken($fg_color, 10%));
$panel_height: 1.86em; $panel_height: 1.86em;
@@ -15,7 +15,8 @@ $panel_height: 1.86em;
// transparent panel on lock & login screens // transparent panel on lock & login screens
&.unlock-screen, &.unlock-screen,
&.login-screen { &.login-screen,
&.lock-screen {
background-color: transparent; background-color: transparent;
.panel-corner { .panel-corner {
@@ -54,6 +55,9 @@ $panel_height: 1.86em;
} }
&:active, &:overview, &:focus, &:checked { &: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%); color: lighten($panel_fg_color, 20%);
} }
@@ -73,32 +77,13 @@ $panel_height: 1.86em;
// lock & login screen styles // lock & login screen styles
.unlock-screen &, .unlock-screen &,
.login-screen & { .login-screen &,
.lock-screen & {
color: lighten($fg_color, 10%); color: lighten($fg_color, 10%);
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); } &:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
} }
} }
.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-indicators-box,
.panel-status-menu-box { .panel-status-menu-box {
spacing: 2px; spacing: 2px;

View File

@@ -3,7 +3,8 @@
$popover_arrow_height: 12px; $popover_arrow_height: 12px;
//.the popover itself //.the popover itself
.popup-menu-boxpointer { .popup-menu-boxpointer,
.candidate-popup-boxpointer {
-arrow-border-radius: $base_border_radius+4; -arrow-border-radius: $base_border_radius+4;
-arrow-background-color: $bg_color; -arrow-background-color: $bg_color;
-arrow-border-width: 1px; -arrow-border-width: 1px;
@@ -82,20 +83,11 @@ $popover_arrow_height: 12px;
// separator // separator
.popup-separator-menu-item { .popup-separator-menu-item {
padding: 0; //-margin-horizontal: 24px;
height: 1px; //not really the whole box
.popup-separator-menu-item-separator { margin: 6px 64px;
//-margin-horizontal: 24px; background-color: lighten($borders_color, 2%);
height: 1px; //not really the whole box border: none !important;
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%);
}
}
}
} }
// desktop background menu // desktop background menu

View File

@@ -1,64 +1,68 @@
/* Screen Shield */ /* Screen Shield */
.unlock-dialog-clock { $_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
color: white;
font-weight: 300; .screen-shield-arrows {
text-align: center; padding-bottom: 3em;
spacing: 24px;
padding-bottom: 2.5em;
} }
.unlock-dialog-clock-time { .screen-shield-arrows Gjs_Arrow {
font-size: 64pt; color: white;
padding-top: 42px; 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"; font-feature-settings: "tnum";
} }
.unlock-dialog-clock-date { .screen-shield-clock-date {
font-size: 16pt; font-size: 28pt;
font-weight: normal; font-weight: normal;
} }
.unlock-dialog-clock-hint { .screen-shield-notifications-container {
font-weight: normal;
padding-top: 48px;
}
.unlock-dialog-notifications-container {
margin: 12px 0;
spacing: 6px; spacing: 6px;
width: 23em; width: 30em;
background-color: transparent; background-color: transparent;
max-height: 500px;
.summary-notification-stack-scrollview { .summary-notification-stack-scrollview {
padding-top: 0; padding-top: 0;
padding-bottom: 0; padding-bottom: 0;
} }
.notification, .notification,
.unlock-dialog-notification-source { .screen-shield-notification-source {
padding: 12px 6px; padding: 12px 6px;
border: none; border: 1px solid $osd_outer_borders_color;
background-color: transparentize($osd_bg_color,0.7); background-color: transparentize($osd_bg_color,0.5);
color: $osd_fg_color; color: $osd_fg_color;
border-radius: $modal_radius; border-radius: 4px;
&.critical { background-color: transparentize($osd_bg_color,0.1) }
} }
.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; padding: 0px 0px 0px 12px;
} }
.unlock-dialog-notification-count-text { .screen-shield-notification-count-text { padding: 0px 0px 0px 12px; }
weight: bold;
padding: 0 6px;
color: $osd_bg_color;
background-color: transparentize($osd_fg_color, 0.7);
border-radius: 99px;
margin-right: 12px;
} #panel.lock-screen { background-color: transparentize($osd_bg_color, 0.5); }
.screen-shield-background { //just the shadow, really .screen-shield-background { //just the shadow, really
background: black; background: black;
@@ -66,10 +70,11 @@
} }
#lockDialogGroup { #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 { StButton#vhandle, StButton#hhandle {
background-color: transparentize($bg_color,0.7); background-color: transparentize($bg_color,0.7);
&:hover, &:focus { background-color: transparentize($bg_color,0.5); } &:hover, &:focus { background-color: transparentize($bg_color,0.5); }

View File

@@ -3,16 +3,19 @@
// search overview container // search overview container
#searchResultsContent { #searchResultsContent {
max-width: 1024px; max-width: 1024px;
spacing: $base_margin * 2;
} }
// search results sections "the boxes" // search results sections "the boxes"
.search-section { .search-section {
// This should be equal to #searchResultsContent spacing
spacing: $base_margin * 2; spacing: $base_margin * 2;
padding:0 !important;
margin:0 !important;
background-color:transparent;
box-shadow:none;
border:none;
// separator // separator
.search-section-separator { .search-section-separator {
// margin-top: $base_padding * 2;
// height: 1px; // height: 1px;
// background-color: $osd_outer_borders_color; // background-color: $osd_outer_borders_color;
height: 0; 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)); text-shadow: 0 1px if($variant == 'light', rgba(255,255,255,0.2), rgba(0,0,0,0.2));
color: $osd_fg_color; color: $osd_fg_color;
padding: $base_padding * 3; padding: $base_padding * 3;
// This is the space between the provider icon and the results container margin: $base_margin 0;
spacing: $base_margin * 2; spacing: 0;
}
%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);
}
} }
// "no results" text // "no results" text
@@ -56,12 +43,54 @@
// Search results with icons // Search results with icons
.grid-search-result { .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 result provider
.search-provider-icon { .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 // content
.list-search-provider-content { .list-search-provider-content {
@@ -84,16 +113,34 @@
// search result listitem // search result listitem
.list-search-result { .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 // content
.list-search-result-content { .list-search-result-content {
spacing: $base_padding; spacing: 0;
} }
// list item title (with leading icon) // list item title
.list-search-result-title { .list-search-result-title {
color: $osd_fg_color;
spacing: $base_spacing * 2; spacing: $base_spacing * 2;
padding-right: $base_padding;
// font-weight: bold; // font-weight: bold;
} }

View File

@@ -1,7 +1,7 @@
/* Window Picker */ /* Window Picker */
$window_picker_spacing: $base_spacing * 2; // 16px $window_picker_spacing: $base_spacing * 8; // 48px
$window_picker_padding: $base_padding * 2; // 16px $window_picker_padding: $base_padding * 10; // 60px
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65); $window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);

View File

@@ -16,6 +16,7 @@
} }
.ws-switcher-box { .ws-switcher-box {
// background: transparent;
background: transparent; background: transparent;
height: 50px; height: 50px;
background-size: 32px; background-size: 32px;
@@ -28,9 +29,44 @@
.ws-switcher-active-down, .ws-switcher-active-down,
.ws-switcher-active-left, .ws-switcher-active-left,
.ws-switcher-active-right { .ws-switcher-active-right {
height: 52px;
background-color: $selected_bg_color; background-color: $selected_bg_color;
border: 1px solid if($variant=='light', darken($selected_bg_color, 8%), lighten($selected_bg_color, 5%)); border: 1px solid if($variant=='light', darken($selected_bg_color, 8%), lighten($selected_bg_color, 5%));
border-radius: $base_border_radius + 3px; border-radius: $base_border_radius + 3px;
color: $selected_fg_color; 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/_drawing.scss',
'gnome-shell-sass/_high-contrast-colors.scss', 'gnome-shell-sass/_high-contrast-colors.scss',
'gnome-shell-sass/_widgets.scss', 'gnome-shell-sass/_widgets.scss',
'gnome-shell-sass/widgets/_a11y.scss',
'gnome-shell-sass/widgets/_app-grid.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/_buttons.scss',
'gnome-shell-sass/widgets/_calendar.scss', 'gnome-shell-sass/widgets/_calendar.scss',
'gnome-shell-sass/widgets/_check-box.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-entry.scss',
'gnome-shell-sass/widgets/_search-results.scss', 'gnome-shell-sass/widgets/_search-results.scss',
'gnome-shell-sass/widgets/_slider.scss', 'gnome-shell-sass/widgets/_slider.scss',
'gnome-shell-sass/widgets/_switcher-popup.scss',
'gnome-shell-sass/widgets/_switches.scss', 'gnome-shell-sass/widgets/_switches.scss',
'gnome-shell-sass/widgets/_tiled-previews.scss', 'gnome-shell-sass/widgets/_tiled-previews.scss',
'gnome-shell-sass/widgets/_window-picker.scss', 'gnome-shell-sass/widgets/_window-picker.scss',
'gnome-shell-sass/widgets/_workspace-switcher.scss', 'gnome-shell-sass/widgets/_workspace-switcher.scss'
'gnome-shell-sass/widgets/_workspace-thumbnails.scss'
]) ])
styles = [ 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'; imports.gi.versions.Gtk = '3.0';
const Gettext = imports.gettext; 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 Format = imports.format;
const _ = Gettext.gettext; const _ = Gettext.gettext;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
const { ExtensionState, ExtensionType } = ExtensionUtils; const { ExtensionState } = ExtensionUtils;
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions'); const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions');
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface); const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
@@ -28,144 +27,26 @@ class Application extends Gtk.Application {
_init() { _init() {
GLib.set_prgname('gnome-shell-extension-prefs'); GLib.set_prgname('gnome-shell-extension-prefs');
super._init({ super._init({
application_id: 'org.gnome.Extensions', application_id: 'org.gnome.shell.ExtensionPrefs',
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE, flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
}); });
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
this._shellProxy = null;
} }
get shellProxy() { get shellProxy() {
return this._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) { _showPrefs(uuid) {
if (this._prefsDialog) let row = this._extensionSelector.get_children().find(c => {
return false; return c.uuid === uuid && c.hasPrefs;
});
let row = this._findExtensionRow(uuid); if (!row)
if (!row || !row.hasPrefs)
return false; return false;
let widget; let widget;
@@ -176,73 +57,33 @@ var ExtensionsWindow = GObject.registerClass({
widget = this._buildErrorUI(row, e); widget = this._buildErrorUI(row, e);
} }
this._prefsDialog = new Gtk.Window({ let dialog = new Gtk.Window({
application: this.application, modal: !this._skipMainWindow,
default_width: 600,
default_height: 400,
modal: this.visible,
type_hint: Gdk.WindowTypeHint.DIALOG, type_hint: Gdk.WindowTypeHint.DIALOG,
window_position: Gtk.WindowPosition.CENTER,
}); });
dialog.set_titlebar(new Gtk.HeaderBar({
this._prefsDialog.set_titlebar(new Gtk.HeaderBar({
show_close_button: true, show_close_button: true,
title: row.name, title: row.name,
visible: true, visible: true,
})); }));
if (this.visible) if (this._skipMainWindow) {
this._prefsDialog.transient_for = this; 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', () => { dialog.set_default_size(600, 400);
this._prefsDialog = null; dialog.add(widget);
dialog.show();
if (!this.visible)
this.destroy();
});
this._prefsDialog.add(widget);
this._prefsDialog.show();
return true; 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) { _buildErrorUI(row, exc) {
let scroll = new Gtk.ScrolledWindow({ let scroll = new Gtk.ScrolledWindow({
hscrollbar_policy: Gtk.PolicyType.NEVER, hscrollbar_policy: Gtk.PolicyType.NEVER,
@@ -277,10 +118,10 @@ var ExtensionsWindow = GObject.registerClass({
}); });
box.add(expander); box.add(expander);
let errortext = '%s\n\nStack trace:\n'.format(exc); let errortext = `${exc}\n\nStack trace:\n${
// Indent stack trace. // Indent stack trace.
errortext += exc.stack.split('\n').map(line => ` ${line}`).join('\n')
exc.stack.split('\n').map(line => ' %s'.format(line)).join('\n'); }`;
let buffer = new Gtk.TextBuffer({ text: errortext }); let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({ let textview = new Gtk.TextView({
@@ -315,9 +156,9 @@ var ExtensionsWindow = GObject.registerClass({
let clipboard = Gtk.Clipboard.get_default(w.get_display()); let clipboard = Gtk.Clipboard.get_default(w.get_display());
// markdown for pasting in gitlab issues // markdown for pasting in gitlab issues
let lines = [ 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) '```', // '`' (xgettext throws up on odd number of backticks)
exc.toString(), `${exc}`,
'```', // '`' '```', // '`'
'', '',
'Stack trace:', 'Stack trace:',
@@ -337,7 +178,7 @@ var ExtensionsWindow = GObject.registerClass({
label: _("Homepage"), label: _("Homepage"),
tooltip_text: _("Visit extension homepage"), tooltip_text: _("Visit extension homepage"),
no_show_all: true, no_show_all: true,
visible: row.url !== '', visible: row.url != null,
}); });
toolbar.add(urlButton); toolbar.add(urlButton);
@@ -358,6 +199,47 @@ var ExtensionsWindow = GObject.registerClass({
return scroll; 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) { _sortList(row1, row2) {
return row1.name.localeCompare(row2.name); return row1.name.localeCompare(row2.name);
} }
@@ -371,26 +253,13 @@ var ExtensionsWindow = GObject.registerClass({
} }
_findExtensionRow(uuid) { _findExtensionRow(uuid) {
return [ return this._extensionSelector.get_children().find(c => c.uuid === uuid);
...this._userList.get_children(),
...this._systemList.get_children(),
].find(c => c.uuid === uuid);
} }
_onExtensionStateChanged(proxy, senderName, [uuid, newState]) { _onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
let extension = ExtensionUtils.deserializeExtension(newState); let extension = ExtensionUtils.deserializeExtension(newState);
let row = this._findExtensionRow(uuid); 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 (row) {
if (extension.state === ExtensionState.UNINSTALLED) if (extension.state === ExtensionState.UNINSTALLED)
row.destroy(); row.destroy();
@@ -403,7 +272,8 @@ var ExtensionsWindow = GObject.registerClass({
this._shellProxy.ListExtensionsRemote(([extensionsMap], e) => { this._shellProxy.ListExtensionsRemote(([extensionsMap], e) => {
if (e) { if (e) {
if (e instanceof Gio.DBusError) { 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'; this._mainStack.visible_child_name = 'noshell';
} else { } else {
throw e; throw e;
@@ -421,53 +291,58 @@ var ExtensionsWindow = GObject.registerClass({
_addExtensionRow(extension) { _addExtensionRow(extension) {
let row = new ExtensionRow(extension); let row = new ExtensionRow(extension);
row.prefsButton.connect('clicked', () => {
this._showPrefs(row.uuid);
});
row.show_all(); row.show_all();
this._extensionSelector.add(row);
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;
} }
_extensionsLoaded() { _extensionsLoaded() {
this._userList.visible = this._userList.get_children().length > 0; if (this._extensionSelector.get_children().length > 0)
this._systemList.visible = this._systemList.get_children().length > 0; this._mainStack.visible_child_name = 'listing';
if (this._userList.visible || this._systemList.visible)
this._mainStack.visible_child_name = 'main';
else else
this._mainStack.visible_child_name = 'placeholder'; this._mainStack.visible_child_name = 'placeholder';
this._checkUpdates();
if (this._startupUuid) if (this._startupUuid)
this._showPrefs(this._startupUuid); this._showPrefs(this._startupUuid);
this._startupUuid = null; this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true; 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({ var Expander = GObject.registerClass({
@@ -569,19 +444,113 @@ var Expander = GObject.registerClass({
} }
}); });
var ExtensionRow = GObject.registerClass({ var EmptyPlaceholder = GObject.registerClass(
GTypeName: 'ExtensionRow', class EmptyPlaceholder extends Gtk.Box {
Template: 'resource:///org/gnome/shell/ui/extension-row.ui', _init() {
InternalChildren: [ super._init({
'nameLabel', orientation: Gtk.Orientation.VERTICAL,
'descriptionLabel', spacing: 6,
'versionLabel', margin: 32,
'authorLabel', });
'updatesIcon',
'revealButton', let image = new Gtk.Image({
'revealer', icon_name: 'application-x-addon-symbolic',
], pixel_size: 96,
}, class ExtensionRow extends Gtk.ListBoxRow { 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) { _init(extension) {
super._init(); super._init();
@@ -589,77 +558,24 @@ var ExtensionRow = GObject.registerClass({
this._extension = extension; this._extension = extension;
this._prefsModule = null; 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.connect('destroy', this._onDestroy.bind(this));
this._buildUI();
this._extensionStateChangedId = this._app.shellProxy.connectSignal( this._extensionStateChangedId = this._app.shellProxy.connectSignal(
'ExtensionStateChanged', (p, sender, [uuid, newState]) => { 'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
if (this.uuid !== uuid) if (this.uuid !== uuid)
return; return;
this._extension = ExtensionUtils.deserializeExtension(newState); 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() { get uuid() {
@@ -674,40 +590,8 @@ var ExtensionRow = GObject.registerClass({
return this._extension.hasPrefs; 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() { get url() {
return this._extension.metadata.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 !== '';
} }
_onDestroy() { _onDestroy() {
@@ -719,6 +603,54 @@ var ExtensionRow = GObject.registerClass({
this._extensionStateChangedId = 0; 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() { _canToggle() {
return this._extension.canChange; return this._extension.canChange;
} }
@@ -747,7 +679,7 @@ function initEnvironment() {
}, },
logError(s) { logError(s) {
log('ERROR: %s'.format(s)); log(`ERROR: ${s}`);
}, },
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell']), 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; var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
const WIGGLE_OFFSET = 6;
const WIGGLE_DURATION = 65;
const N_WIGGLES = 3;
var AuthPromptMode = { var AuthPromptMode = {
UNLOCK_ONLY: 0, UNLOCK_ONLY: 0,
UNLOCK_OR_LOG_IN: 1, UNLOCK_OR_LOG_IN: 1,
@@ -47,15 +51,12 @@ var AuthPrompt = GObject.registerClass({
super._init({ super._init({
style_class: 'login-dialog-prompt-layout', style_class: 'login-dialog-prompt-layout',
vertical: true, vertical: true,
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
}); });
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient; this._gdmClient = gdmClient;
this._mode = mode; this._mode = mode;
this._defaultButtonWellActor = null;
let reauthenticationOnly; let reauthenticationOnly;
if (this._mode == AuthPromptMode.UNLOCK_ONLY) 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._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
this.smartcardDetected = this._userVerifier.smartcardDetected; 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.connect('destroy', this._onDestroy.bind(this));
this._userWell = new St.Bin({ this._userWell = new St.Bin({
@@ -81,35 +91,67 @@ var AuthPrompt = GObject.registerClass({
y_expand: true, y_expand: true,
}); });
this.add_child(this._userWell); this.add_child(this._userWell);
this._label = new St.Label({
this._hasCancelButton = this._mode === AuthPromptMode.UNLOCK_OR_LOG_IN; style_class: 'login-dialog-prompt-label',
x_expand: false,
this._initEntryRow(); y_expand: true,
let capsLockPlaceholder = new St.Label();
this.add_child(capsLockPlaceholder);
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning({
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
}); });
this.add_child(this._capsLockWarningLabel);
this._capsLockWarningLabel.bind_property('visible', this.add_child(this._label);
capsLockPlaceholder, 'visible',
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN); 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({ this._message = new St.Label({
opacity: 0, opacity: 0,
styleClass: 'login-dialog-message', styleClass: 'login-dialog-message',
x_expand: false,
y_expand: true, y_expand: true,
x_expand: true,
y_align: Clutter.ActorAlign.START, y_align: Clutter.ActorAlign.START,
x_align: Clutter.ActorAlign.CENTER,
}); });
this._message.clutter_text.line_wrap = true; this._message.clutter_text.line_wrap = true;
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.add_child(this._message); this.add_child(this._message);
this._buttonBox = new St.BoxLayout({
style_class: 'login-dialog-button-box',
vertical: false,
y_align: Clutter.ActorAlign.END,
});
this.add_child(this._buttonBox);
this._defaultButtonWell = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
});
this._initButtons();
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.opacity = 0;
this._spinner.show();
this._defaultButtonWell.add_child(this._spinner);
} }
_onDestroy() { _onDestroy() {
@@ -123,95 +165,54 @@ var AuthPrompt = GObject.registerClass({
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
_initEntryRow() { _initButtons() {
this._mainBox = new St.BoxLayout({
style_class: 'login-dialog-button-box',
vertical: false,
});
this.add_child(this._mainBox);
this.cancelButton = new St.Button({ this.cancelButton = new St.Button({
style_class: 'modal-dialog-button button cancel-button', style_class: 'modal-dialog-button button',
accessible_name: _('Cancel'),
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: this._hasCancelButton, reactive: true,
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',
can_focus: true, can_focus: true,
label: _("Cancel"),
x_expand: true, x_expand: true,
}; x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END,
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);
});
}); });
this.cancelButton.connect('clicked', () => this.cancel());
this._buttonBox.add_child(this.cancelButton);
this._defaultButtonWell = new St.Widget({ this._buttonBox.add_child(this._defaultButtonWell);
layout_manager: new Clutter.BinLayout(), 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, x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER, y_align: Clutter.ActorAlign.END,
}); });
this._defaultButtonWell.add_constraint(new Clutter.BindConstraint({ this.nextButton.connect('clicked', () => this.emit('next'));
source: this.cancelButton, this.nextButton.add_style_pseudo_class('default');
coordinate: Clutter.BindCoordinate.SIZE, this._buttonBox.add_child(this.nextButton);
}));
this._mainBox.add_child(this._defaultButtonWell);
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE); this._updateNextButtonSensitivity(this._entry.text.length > 0);
this._defaultButtonWell.add_child(this._spinner);
}
_activateNext(shouldSpin) { this._entry.clutter_text.connect('text-changed', () => {
this.updateSensitivity(false); if (!this._userVerifier.hasPendingMessages)
this._fadeOutMessage();
if (shouldSpin) this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
this.startSpinning(); });
this._entry.clutter_text.connect('activate', () => {
if (this._queryingService) if (this.nextButton.reactive)
this._userVerifier.answerQuery(this._queryingService, this._entry.text); this.emit('next');
else });
this._preemptiveAnswer = this._entry.text;
this.emit('next');
} }
_updateEntry(secret) { _updateEntry(secret) {
if (secret && this._entry !== this._passwordEntry) { if (secret && (this._entry != this._passwordEntry)) {
this._mainBox.replace_child(this._entry, this._passwordEntry); this.replace_child(this._entry, this._passwordEntry);
this._entry = this._passwordEntry; this._entry = this._passwordEntry;
} else if (!secret && this._entry !== this._textEntry) { } else if (!secret && (this._entry != this._textEntry)) {
this._mainBox.replace_child(this._entry, this._textEntry); this.replace_child(this._entry, this._textEntry);
this._entry = this._textEntry; this._entry = this._textEntry;
} }
this._capsLockWarningLabel.visible = secret; this._capsLockWarningLabel.visible = secret;
@@ -229,14 +230,16 @@ var AuthPrompt = GObject.registerClass({
} }
this._updateEntry(secret); this._updateEntry(secret);
this.setQuestion(question);
// Hack: The question string comes directly from PAM, if it's "Password:" if (secret) {
// we replace it with our own to allow localization, if it's something if (this._userVerifier.reauthenticating)
// else we remove the last colon and any trailing or leading spaces. this.nextButton.label = _("Unlock");
if (question === 'Password:' || question === 'Password: ') else
this.setQuestion(_('Password')); this.nextButton.label = C_("button", "Sign In");
else } else {
this.setQuestion(question.replace(/: *$/, '').trim()); this.nextButton.label = _("Next");
}
this.updateSensitivity(true); this.updateSensitivity(true);
this.emit('prompted'); this.emit('prompted');
@@ -279,14 +282,17 @@ var AuthPrompt = GObject.registerClass({
this.setActorInDefaultButtonWell(null); this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
Util.wiggle(this._entry); Util.wiggle(this._entry, {
offset: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES,
});
} }
_onVerificationComplete() { _onVerificationComplete() {
this.setActorInDefaultButtonWell(null); this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false; this.cancelButton.reactive = false;
this.cancelButton.can_focus = false;
} }
_onReset() { _onReset() {
@@ -294,6 +300,10 @@ var AuthPrompt = GObject.registerClass({
this.reset(); this.reset();
} }
addActorToDefaultButtonWell(actor) {
this._defaultButtonWell.add_child(actor);
}
setActorInDefaultButtonWell(actor, animate) { setActorInDefaultButtonWell(actor, animate) {
if (!this._defaultButtonWellActor && if (!this._defaultButtonWellActor &&
!actor) !actor)
@@ -373,9 +383,11 @@ var AuthPrompt = GObject.registerClass({
} }
setQuestion(question) { setQuestion(question) {
this._entry.hint_text = question; this._label.set_text(question);
this._label.show();
this._entry.show(); this._entry.show();
this._entry.grab_key_focus(); 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) { updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive; this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive; this._entry.clutter_text.editable = sensitive;
} }
@@ -444,18 +462,18 @@ var AuthPrompt = GObject.registerClass({
if (oldChild) if (oldChild)
oldChild.destroy(); oldChild.destroy();
let userWidget = new UserWidget.UserWidget(user, Clutter.Orientation.VERTICAL); if (user) {
this._userWell.set_child(userWidget); let userWidget = new UserWidget.UserWidget(user);
userWidget.x_align = Clutter.ActorAlign.START;
if (!user) this._userWell.set_child(userWidget);
this._updateEntry(false); }
} }
reset() { reset() {
let oldStatus = this.verificationStatus; let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = this._hasCancelButton; this.cancelButton.reactive = true;
this.cancelButton.can_focus = this._hasCancelButton; this.nextButton.label = _("Next");
this._preemptiveAnswer = null; this._preemptiveAnswer = null;
if (this._userVerifier) if (this._userVerifier)
@@ -465,7 +483,6 @@ var AuthPrompt = GObject.registerClass({
this.clear(); this.clear();
this._message.opacity = 0; this._message.opacity = 0;
this.setUser(null); this.setUser(null);
this._updateEntry(true);
this.stopSpinning(); this.stopSpinning();
if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED) if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED)

View File

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

View File

@@ -61,12 +61,7 @@ var IBusManager = class {
_spawn(extraArgs = []) { _spawn(extraArgs = []) {
try { try {
let cmdLine = ['ibus-daemon', '--panel', 'disable', ...extraArgs]; let cmdLine = ['ibus-daemon', '--panel', 'disable', ...extraArgs];
let launcher = Gio.SubprocessLauncher.new(Gio.SubprocessFlags.NONE); Gio.Subprocess.new(cmdLine, Gio.SubprocessFlags.NONE);
// Forward the right X11 Display for ibus-x11
let display = GLib.getenv('GNOME_SETUP_DISPLAY');
if (display)
launcher.setenv('DISPLAY', display, true);
launcher.launch(cmdLine);
} catch (e) { } catch (e) {
log(`Failed to launch ibus-daemon: ${e.message}`); log(`Failed to launch ibus-daemon: ${e.message}`);
} }

View File

@@ -1,12 +1,10 @@
/* exported IntrospectService */ /* 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_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect'; const INTROSPECT_KEY = 'introspect';
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk']; const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const INTROSPECT_DBUS_API_VERSION = 2;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect'); const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
@@ -24,7 +22,6 @@ var IntrospectService = class {
this._runningApplicationsDirty = true; this._runningApplicationsDirty = true;
this._activeApplication = null; this._activeApplication = null;
this._activeApplicationDirty = true; this._activeApplicationDirty = true;
this._animationsEnabled = true;
this._appSystem = Shell.AppSystem.get_default(); this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('app-state-changed', this._appSystem.connect('app-state-changed',
@@ -33,9 +30,7 @@ var IntrospectService = class {
this._syncRunningApplications(); this._syncRunningApplications();
}); });
this._introspectSettings = new Gio.Settings({ this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
schema_id: INTROSPECT_SCHEMA,
});
let tracker = Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app', tracker.connect('notify::focus-app',
@@ -54,11 +49,6 @@ var IntrospectService = class {
(conn, name, owner) => this._whitelistMap.set(name, owner), (conn, name, owner) => this._whitelistMap.set(name, owner),
(conn, name) => this._whitelistMap.delete(name)); (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) { _isStandaloneApp(app) {
@@ -66,7 +56,7 @@ var IntrospectService = class {
} }
_isIntrospectEnabled() { _isIntrospectEnabled() {
return this._introspectSettings.get_boolean(INTROSPECT_KEY); return this._settings.get_boolean(INTROSPECT_KEY);
} }
_isSenderWhitelisted(sender) { _isSenderWhitelisted(sender) {
@@ -129,18 +119,9 @@ var IntrospectService = class {
type == Meta.WindowType.UTILITY; type == Meta.WindowType.UTILITY;
} }
_isInvocationAllowed(invocation) {
if (this._isIntrospectEnabled())
return true;
if (this._isSenderWhitelisted(invocation.get_sender()))
return true;
return false;
}
GetRunningApplicationsAsync(params, invocation) { GetRunningApplicationsAsync(params, invocation) {
if (!this._isInvocationAllowed(invocation)) { if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError, invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED, Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed'); 'App introspection not allowed');
@@ -155,7 +136,8 @@ var IntrospectService = class {
let apps = this._appSystem.get_running(); let apps = this._appSystem.get_running();
let windowsList = {}; let windowsList = {};
if (!this._isInvocationAllowed(invocation)) { if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError, invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED, Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed'); 'App introspection not allowed');
@@ -199,21 +181,4 @@ var IntrospectService = class {
} }
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList])); 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._userManager.connect('user-removed',
() => this._updateMultiUser()); () => this._updateMultiUser());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_USER_SWITCH_KEY), this._lockdownSettings.connect(`changed::${DISABLE_USER_SWITCH_KEY}`,
() => this._updateSwitchUser()); () => this._updateSwitchUser());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOG_OUT_KEY), this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
() => this._updateLogout()); () => 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._updateLogout());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOCK_SCREEN_KEY), this._lockdownSettings.connect(`changed::${DISABLE_LOCK_SCREEN_KEY}`,
() => this._updateLockScreen()); () => this._updateLockScreen());
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOG_OUT_KEY), this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
() => this._updateHaveShutdown()); () => this._updateHaveShutdown());
this.forceUpdate(); this.forceUpdate();

View File

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

View File

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

View File

@@ -7,10 +7,5 @@
<file>misc/extensionUtils.js</file> <file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file> <file>misc/fileUtils.js</file>
<file>misc/params.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> </gresource>
</gresources> </gresources>

View File

@@ -138,7 +138,7 @@ var AccessDialogDBus = class {
let [handle, appId, parentWindow_, title, description, body, options] = params; let [handle, appId, parentWindow_, title, description, body, options] = params;
// We probably want to use parentWindow and global.display.focus_window // We probably want to use parentWindow and global.display.focus_window
// for this check in the future // 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, invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED, Gio.DBusError.ACCESS_DENIED,
'Only the focused app is allowed to show a system access dialog'); 'Only the focused app is allowed to show a system access dialog');

View File

@@ -280,10 +280,12 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
} }
_onDestroy() { _onDestroy() {
super._onDestroy();
if (this._thumbnails)
this._destroyThumbnails();
if (this._thumbnailTimeoutId != 0) if (this._thumbnailTimeoutId != 0)
GLib.source_remove(this._thumbnailTimeoutId); GLib.source_remove(this._thumbnailTimeoutId);
super._onDestroy();
} }
/** /**
@@ -363,7 +365,8 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}, },
}); });
this._thumbnails = null; this._thumbnails = null;
this._switcherList.removeAccessibleState(this._selectedIndex, Atk.StateType.EXPANDED); if (this._switcherList._items[this._selectedIndex])
this._switcherList._items[this._selectedIndex].remove_accessible_state(Atk.StateType.EXPANDED);
} }
_createThumbnails() { _createThumbnails() {
@@ -392,7 +395,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}, },
}); });
this._switcherList.addAccessibleState(this._selectedIndex, Atk.StateType.EXPANDED); this._switcherList._items[this._selectedIndex].add_accessible_state(Atk.StateType.EXPANDED);
} }
}); });
@@ -773,9 +776,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
// We override SwitcherList's _onItemEnter method to delay // We override SwitcherList's _onItemEnter method to delay
// activation when the thumbnail list is open // activation when the thumbnail list is open
_onItemEnter(item) { _onItemEnter(index) {
const index = this._items.indexOf(item);
if (this._mouseTimeOutId != 0) if (this._mouseTimeOutId != 0)
GLib.source_remove(this._mouseTimeOutId); GLib.source_remove(this._mouseTimeOutId);
if (this._altTabPopup.thumbnailsVisible) { if (this._altTabPopup.thumbnailsVisible) {

View File

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

View File

@@ -66,7 +66,7 @@ class AppFavorites {
constructor() { constructor() {
this.FAVORITE_APPS_KEY = 'favorite-apps'; this.FAVORITE_APPS_KEY = 'favorite-apps';
this._favorites = {}; 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(); this.reload();
} }

View File

@@ -120,7 +120,7 @@ var AudioDeviceSelectionDialog = GObject.registerClass({
let app = Shell.AppSystem.get_default().lookup_app(desktopFile); let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) { 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; return;
} }

View File

@@ -504,9 +504,12 @@ var SystemBackground = GObject.registerClass({
Signals: { 'loaded': {} }, Signals: { 'loaded': {} },
}, class SystemBackground extends Meta.BackgroundActor { }, class SystemBackground extends Meta.BackgroundActor {
_init() { _init() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) { if (_systemBackground == null) {
_systemBackground = new Meta.Background({ meta_display: global.display }); _systemBackground = new Meta.Background({ meta_display: global.display });
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR); _systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
} }
super._init({ super._init({
@@ -515,11 +518,22 @@ var SystemBackground = GObject.registerClass({
background: _systemBackground, background: _systemBackground,
}); });
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { let cache = Meta.BackgroundImageCache.get_default();
this.emit('loaded'); let image = cache.load(file);
return GLib.SOURCE_REMOVE; if (image.is_loaded()) {
}); image = null;
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded'); 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 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) { function sameYear(dateA, dateB) {
return dateA.getYear() == dateB.getYear(); return dateA.getYear() == dateB.getYear();
@@ -114,26 +114,26 @@ var EventSourceBase = GObject.registerClass({
Signals: { 'changed': {} }, Signals: { 'changed': {} },
}, class EventSourceBase extends GObject.Object { }, class EventSourceBase extends GObject.Object {
get isLoading() { get isLoading() {
throw new GObject.NotImplementedError('isLoading in %s'.format(this.constructor.name)); throw new GObject.NotImplementedError(`isLoading in ${this.constructor.name}`);
} }
get hasCalendars() { get hasCalendars() {
throw new GObject.NotImplementedError('hasCalendars in %s'.format(this.constructor.name)); throw new GObject.NotImplementedError(`hasCalendars in ${this.constructor.name}`);
} }
destroy() { destroy() {
} }
requestRange(_begin, _end) { 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) { 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) { 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 // about the HasCalendars property and would cause an exception trying
// to read it) // to read it)
} else { } else {
log('Error loading calendars: %s'.format(e.message)); log(`Error loading calendars: ${e.message}`);
return; return;
} }
} }
@@ -359,7 +359,7 @@ var Calendar = GObject.registerClass({
this._weekStart = Shell.util_get_week_start(); this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' }); 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); 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 // Hack used in lieu of border-collapse - see gnome-shell.css
if (row == 2) if (row == 2)
styleClass = 'calendar-day-top %s'.format(styleClass); styleClass = `calendar-day-top ${styleClass}`;
let leftMost = rtl let leftMost = rtl
? iter.getDay() == (this._weekStart + 6) % 7 ? iter.getDay() == (this._weekStart + 6) % 7
: iter.getDay() == this._weekStart; : iter.getDay() == this._weekStart;
if (leftMost) if (leftMost)
styleClass = 'calendar-day-left %s'.format(styleClass); styleClass = `calendar-day-left ${styleClass}`;
if (sameDay(now, iter)) if (sameDay(now, iter))
styleClass += ' calendar-today'; styleClass += ' calendar-today';
@@ -738,15 +738,15 @@ class EventMessage extends MessageList.Message {
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL; let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
if (this._event.date < periodBegin && !this._event.allDay) { if (this._event.date < periodBegin && !this._event.allDay) {
if (rtl) if (rtl)
title = '%s%s'.format(title, ELLIPSIS_CHAR); title = `${title}${ELLIPSIS_CHAR}`;
else else
title = '%s%s'.format(ELLIPSIS_CHAR, title); title = `${ELLIPSIS_CHAR}${title}`;
} }
if (this._event.end > periodEnd && !this._event.allDay) { if (this._event.end > periodEnd && !this._event.allDay) {
if (rtl) if (rtl)
title = '%s%s'.format(ELLIPSIS_CHAR, title); title = `${ELLIPSIS_CHAR}${title}`;
else else
title = '%s%s'.format(title, ELLIPSIS_CHAR); title = `${title}${ELLIPSIS_CHAR}`;
} }
return title; return title;
} }
@@ -1204,7 +1204,7 @@ class CalendarMessageList extends St.Widget {
for (let prop of ['visible', 'empty', 'can-clear']) { for (let prop of ['visible', 'empty', 'can-clear']) {
connectionsIds.push( 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) => { connectionsIds.push(section.connect('message-focused', (_s, messageActor) => {
Util.ensureActorVisibleInScrollView(this._scrollView, messageActor); Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);

View File

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

View File

@@ -113,7 +113,7 @@ var AutomountManager = class {
try { try {
drive.stop_finish(res); drive.stop_finish(res);
} catch (e) { } 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()) { } else if (drive.can_eject()) {
@@ -122,7 +122,7 @@ var AutomountManager = class {
try { try {
drive.eject_with_operation_finish(res); drive.eject_with_operation_finish(res);
} catch (e) { } 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)) 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); this._closeOperation(volume);
} }
} }

View File

@@ -66,7 +66,7 @@ function startAppForMount(app, mount) {
retval = app.launch(files, retval = app.launch(files,
global.create_app_launch_context(0, -1)); global.create_app_launch_context(0, -1));
} catch (e) { } 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; return retval;
@@ -105,7 +105,7 @@ var ContentTypeDiscoverer = class {
try { try {
contentTypes = mount.guess_content_type_finish(res); contentTypes = mount.guess_content_type_finish(res);
} catch (e) { } 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) { if (contentTypes.length) {

View File

@@ -3,11 +3,13 @@
const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi; const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi;
const Animation = imports.ui.animation;
const Dialog = imports.ui.dialog; const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
const CheckBox = imports.ui.checkBox; const CheckBox = imports.ui.checkBox;
const Util = imports.misc.util;
var WORK_SPINNER_ICON_SIZE = 16;
var KeyringDialog = GObject.registerClass( var KeyringDialog = GObject.registerClass(
class KeyringDialog extends ModalDialog.ModalDialog { 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('show-confirm', this._onShowConfirm.bind(this));
this.prompt.connect('prompt-close', this._onHidePrompt.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', this.prompt.bind_property('message', this._content, 'title', GObject.BindingFlags.SYNC_CREATE);
content, 'title', GObject.BindingFlags.SYNC_CREATE); this.prompt.bind_property('description', this._content, 'description', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('description',
content, 'description', GObject.BindingFlags.SYNC_CREATE);
let passwordBox = new St.BoxLayout({ this._workSpinner = null;
style_class: 'prompt-dialog-password-layout', this._controlTable = null;
vertical: true,
});
this._passwordEntry = new St.PasswordEntry({ this._cancelButton = this.addButton({ label: '',
style_class: 'prompt-dialog-password-entry', action: this._onCancelButton.bind(this),
can_focus: true, key: Clutter.KEY_Escape });
x_align: Clutter.ActorAlign.CENTER, this._continueButton = this.addButton({ label: '',
}); action: this._onContinueButton.bind(this),
ShellEntry.addContextMenu(this._passwordEntry); default: true });
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.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE); 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); 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) { _updateSensitivity(sensitive) {
if (this._passwordEntry) { if (this._passwordEntry) {
this._passwordEntry.reactive = sensitive; this._passwordEntry.reactive = sensitive;
@@ -123,6 +169,7 @@ class KeyringDialog extends ModalDialog.ModalDialog {
this._continueButton.can_focus = sensitive; this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive; this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
} }
_ensureOpen() { _ensureOpen() {
@@ -144,16 +191,16 @@ class KeyringDialog extends ModalDialog.ModalDialog {
} }
_onShowPassword() { _onShowPassword() {
this._buildControlTable();
this._ensureOpen(); this._ensureOpen();
this._updateSensitivity(true); this._updateSensitivity(true);
this._passwordEntry.text = '';
this._passwordEntry.grab_key_focus(); this._passwordEntry.grab_key_focus();
} }
_onShowConfirm() { _onShowConfirm() {
this._buildControlTable();
this._ensureOpen(); this._ensureOpen();
this._updateSensitivity(true); this._updateSensitivity(true);
this._confirmEntry.text = '';
this._continueButton.grab_key_focus(); this._continueButton.grab_key_focus();
} }

View File

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

View File

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

View File

@@ -87,7 +87,7 @@ var TelepathyComponent = class {
try { try {
this._client.register(); this._client.register();
} catch (e) { } 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())) 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); dispatchOp.claim_with_finish(result);
this._handlingChannels(account, conn, [channel], false); this._handlingChannels(account, conn, [channel], false);
} catch (err) { } 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) { _onProxyReady(proxy, error) {
if (error) { if (error) {
log('Failed to create GNOME Clocks proxy: %s'.format(error)); log(`Failed to create GNOME Clocks proxy: ${error}`);
return; return;
} }
@@ -454,8 +454,6 @@ class MessagesIndicator extends St.Icon {
let sources = Main.messageTray.getSources(); let sources = Main.messageTray.getSources();
sources.forEach(source => this._onSourceAdded(null, source)); sources.forEach(source => this._onSourceAdded(null, source));
this._sync();
this.connect('destroy', () => { this.connect('destroy', () => {
this._settings.run_dispose(); this._settings.run_dispose();
this._settings = null; 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( var FreezableBinLayout = GObject.registerClass(
class FreezableBinLayout extends Clutter.BinLayout { class FreezableBinLayout extends Clutter.BinLayout {
_init() { _init() {
@@ -550,24 +568,16 @@ class DateMenuButton extends PanelMenu.Button {
let hbox; let hbox;
let vbox; let vbox;
super._init(0.5); let menuAlignment = 0.5;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
this._clockDisplay = new St.Label({ style_class: 'clock' }); menuAlignment = 1.0 - menuAlignment;
this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER; super._init(menuAlignment);
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator(); 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' }); 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._clockDisplay);
box.add_actor(this._indicator); 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', this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true, x_expand: true,
overlay_scrollbars: 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); vbox.add_actor(this._displaysSection);
let displaysBox = new St.BoxLayout({ vertical: true, let displaysBox = new St.BoxLayout({ vertical: true,

View File

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

View File

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

View File

@@ -299,7 +299,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
try { try {
this._updatesPermission = Polkit.Permission.new_finish(res); this._updatesPermission = Polkit.Permission.new_finish(res);
} catch (e) { } 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) { if (!sessionId) {
this._loginManager.getCurrentSessionProxy(currentSessionProxy => { this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
sessionId = currentSessionProxy.Id; 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

@@ -12,9 +12,6 @@ imports.gi.versions.TelepathyLogger = '0.2';
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
const Gettext = imports.gettext; const Gettext = imports.gettext;
const System = imports.system;
let _localTimeZone = null;
// We can't import shell JS modules yet, because they may have // We can't import shell JS modules yet, because they may have
// variable initializations, etc, that depend on init() already having // variable initializations, etc, that depend on init() already having
@@ -114,11 +111,6 @@ function _easeActor(actor, params) {
autoReverse = params.autoReverse; autoReverse = params.autoReverse;
delete 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) if (params.mode != undefined)
actor.set_easing_mode(params.mode); actor.set_easing_mode(params.mode);
delete params.mode; delete params.mode;
@@ -130,8 +122,7 @@ function _easeActor(actor, params) {
let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g')); let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g'));
animatedProps.forEach(p => actor.remove_transition(p)); animatedProps.forEach(p => actor.remove_transition(p));
if (actor.get_easing_duration() > 0 || !isReversed) actor.set(params);
actor.set(params);
actor.restore_easing_state(); actor.restore_easing_state();
let transition = animatedProps.map(p => actor.get_transition(p)) let transition = animatedProps.map(p => actor.get_transition(p))
@@ -170,11 +161,6 @@ function _easeActorProperty(actor, propName, target, params) {
autoReverse = params.autoReverse; autoReverse = params.autoReverse;
delete 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 // Copy Clutter's behavior for implicit animations, see
// should_skip_implicit_transition() // should_skip_implicit_transition()
if (actor instanceof Clutter.Actor && !actor.mapped) if (actor instanceof Clutter.Actor && !actor.mapped)
@@ -188,9 +174,7 @@ function _easeActorProperty(actor, propName, target, params) {
if (duration == 0) { if (duration == 0) {
let [obj, prop] = _getPropertyTarget(actor, propName); let [obj, prop] = _getPropertyTarget(actor, propName);
obj[prop] = target;
if (!isReversed)
obj[prop] = target;
Meta.disable_unredirect_for_display(global.display); Meta.disable_unredirect_for_display(global.display);
callback(true); callback(true);
@@ -307,25 +291,9 @@ function init() {
} }
}; };
// Override to clear our own timezone cache as well
const origClearDateCaches = System.clearDateCaches;
System.clearDateCaches = function () {
_localTimeZone = null;
origClearDateCaches();
};
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783
Date.prototype.toLocaleFormat = function (format) { Date.prototype.toLocaleFormat = function (format) {
if (_localTimeZone === null) let dt = GLib.DateTime.new_from_unix_local(this.getTime() / 1000);
_localTimeZone = GLib.TimeZone.new_local();
let dt = GLib.DateTime.new(_localTimeZone,
this.getYear(),
this.getMonth() + 1,
this.getDate(),
this.getHours(),
this.getMinutes(),
this.getSeconds());
return dt ? dt.format(format) : ''; return dt ? dt.format(format) : '';
}; };

View File

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

View File

@@ -1,14 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported init connect disconnect */ /* exported init connect disconnect */
const { GLib, Gio, GObject, Shell, St } = imports.gi; const { GLib, Gio, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const FileUtils = imports.misc.fileUtils; const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const { ExtensionState, ExtensionType } = ExtensionUtils; const { ExtensionState, ExtensionType } = ExtensionUtils;
@@ -17,13 +15,10 @@ const DISABLED_EXTENSIONS_KEY = 'disabled-extensions';
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions'; const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation'; const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
const UPDATE_CHECK_TIMEOUT = 24 * 60 * 60; // 1 day in seconds
var ExtensionManager = class { var ExtensionManager = class {
constructor() { constructor() {
this._initialized = false; this._initialized = false;
this._enabled = false; this._enabled = false;
this._updateNotified = false;
this._extensions = new Map(); this._extensions = new Map();
this._enabledExtensions = []; this._enabledExtensions = [];
@@ -42,7 +37,7 @@ var ExtensionManager = class {
try { try {
disableFile.create(Gio.FileCreateFlags.REPLACE_DESTINATION, null); disableFile.create(Gio.FileCreateFlags.REPLACE_DESTINATION, null);
} catch (e) { } 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, () => { GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 60, () => {
@@ -52,12 +47,6 @@ var ExtensionManager = class {
this._installExtensionUpdates(); this._installExtensionUpdates();
this._sessionUpdated(); this._sessionUpdated();
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, UPDATE_CHECK_TIMEOUT, () => {
ExtensionDownloader.checkForUpdates();
return GLib.SOURCE_CONTINUE;
});
ExtensionDownloader.checkForUpdates();
} }
lookup(uuid) { lookup(uuid) {
@@ -140,7 +129,7 @@ var ExtensionManager = class {
if (extension.state != ExtensionState.DISABLED) if (extension.state != ExtensionState.DISABLED)
return; 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(); let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (let i = 0; i < stylesheetNames.length; i++) { for (let i = 0; i < stylesheetNames.length; i++) {
try { try {
@@ -217,18 +206,6 @@ var ExtensionManager = class {
extension.hasUpdate = true; extension.hasUpdate = true;
this.emit('extension-state-changed', extension); 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) { logExtensionError(uuid, error) {
@@ -236,7 +213,7 @@ var ExtensionManager = class {
if (!extension) if (!extension)
return; return;
let message = error.toString(); let message = `${error}`;
extension.error = message; extension.error = message;
extension.state = ExtensionState.ERROR; extension.state = ExtensionState.ERROR;
@@ -244,7 +221,7 @@ var ExtensionManager = class {
extension.errors = []; extension.errors = [];
extension.errors.push(message); extension.errors.push(message);
logError(error, 'Extension %s'.format(uuid)); logError(error, `Extension ${uuid}`);
this.emit('extension-state-changed', extension); this.emit('extension-state-changed', extension);
} }
@@ -259,24 +236,24 @@ var ExtensionManager = class {
if (metadataContents instanceof Uint8Array) if (metadataContents instanceof Uint8Array)
metadataContents = imports.byteArray.toString(metadataContents); metadataContents = imports.byteArray.toString(metadataContents);
} catch (e) { } 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; let meta;
try { try {
meta = JSON.parse(metadataContents); meta = JSON.parse(metadataContents);
} catch (e) { } 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']; let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
for (let i = 0; i < requiredProperties.length; i++) { for (let i = 0; i < requiredProperties.length; i++) {
let prop = requiredProperties[i]; let prop = requiredProperties[i];
if (!meta[prop]) 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) 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 = { let extension = {
metadata: meta, metadata: meta,
@@ -496,17 +473,17 @@ var ExtensionManager = class {
} }
_loadExtensions() { _loadExtensions() {
global.settings.connect('changed::%s'.format(ENABLED_EXTENSIONS_KEY), global.settings.connect(`changed::${ENABLED_EXTENSIONS_KEY}`,
this._onEnabledExtensionsChanged.bind(this)); this._onEnabledExtensionsChanged.bind(this));
global.settings.connect('changed::%s'.format(DISABLED_EXTENSIONS_KEY), global.settings.connect(`changed::${DISABLED_EXTENSIONS_KEY}`,
this._onEnabledExtensionsChanged.bind(this)); 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)); 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)); 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)); 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._onSettingsWritableChanged.bind(this));
this._enabledExtensions = this._getEnabledExtensions(); this._enabledExtensions = this._getEnabledExtensions();
@@ -519,7 +496,7 @@ var ExtensionManager = class {
let uuid = info.get_name(); let uuid = info.get_name();
let existing = this.lookup(uuid); let existing = this.lookup(uuid);
if (existing) { 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; return;
} }
@@ -530,7 +507,7 @@ var ExtensionManager = class {
try { try {
extension = this.createExtensionObject(uuid, dir, type); extension = this.createExtensionObject(uuid, dir, type);
} catch (e) { } catch (e) {
logError(e, 'Could not load extension %s'.format(uuid)); logError(e, `Could not load extension ${uuid}`);
return; return;
} }
this.loadExtension(extension); this.loadExtension(extension);
@@ -580,27 +557,3 @@ var ExtensionManager = class {
} }
}; };
Signals.addSignalMethods(ExtensionManager.prototype); 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) { 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); icon.allocate(box, flags);
return false; return false;
} }
@@ -556,25 +556,15 @@ var IconGrid = GObject.registerClass({
}, Infinity); }, Infinity);
let normalization = maxDist - minDist; let normalization = maxDist - minDist;
actors.forEach(actor => { for (let index = 0; index < actors.length; index++) {
let clone = new Clutter.Clone({ source: actor }); let actor = actors[index];
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;
actor.opacity = 0; actor.opacity = 0;
actor.reactive = false; 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); let [width, height] = this._getAllocatedChildSizeAndSpacing(actor);
actorClone.set_size(width, height); actorClone.set_size(width, height);
let scaleX = sourceScaledWidth / width; let scaleX = sourceScaledWidth / width;
@@ -641,7 +631,7 @@ var IconGrid = GObject.registerClass({
actorClone.ease(movementParams); actorClone.ease(movementParams);
actorClone.ease(fadeParams); actorClone.ease(fadeParams);
}); }
} }
_getAllocatedChildSizeAndSpacing(child) { _getAllocatedChildSizeAndSpacing(child) {

View File

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

View File

@@ -738,7 +738,7 @@ var LayoutManager = GObject.registerClass({
showKeyboard() { showKeyboard() {
this.keyboardBox.show(); this.keyboardBox.show();
this.keyboardBox.ease({ this.keyboardBox.ease({
translation_y: -this.keyboardBox.height, anchor_y: this.keyboardBox.height,
opacity: 255, opacity: 255,
duration: KEYBOARD_ANIMATION_TIME, duration: KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -755,7 +755,7 @@ var LayoutManager = GObject.registerClass({
this._updateRegions(); this._updateRegions();
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', () => { 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._keyboardHeightNotifyId = 0;
} }
this.keyboardBox.ease({ this.keyboardBox.ease({
translation_y: this.keyboardBox.height, anchor_y: 0,
opacity: 0, opacity: 0,
duration: immediate ? 0 : KEYBOARD_ANIMATION_TIME, duration: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_IN_QUAD, 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 // special case this since the default is way, way too verbose
return '<js function>'; return '<js function>';
} else { } else {
if (o === undefined) return `${o}`;
return 'undefined';
if (o === null)
return 'null';
return o.toString();
} }
} }
@@ -297,7 +291,7 @@ class Result extends St.BoxLayout {
this.add(cmdTxt); this.add(cmdTxt);
let box = new St.BoxLayout({}); let box = new St.BoxLayout({});
this.add(box); 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; resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
box.add(resultTxt); box.add(resultTxt);
let objLink = new ObjLink(this._lookingGlass, o); let objLink = new ObjLink(this._lookingGlass, o);
@@ -337,7 +331,7 @@ var WindowList = GObject.registerClass({
box.add_child(windowLink); box.add_child(windowLink);
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' }); let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
box.add(propsBox); 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); let app = tracker.get_window_app(metaWindow);
if (app != null && !app.is_window_backed()) { if (app != null && !app.is_window_backed()) {
let icon = app.create_icon_texture(22); let icon = app.create_icon_texture(22);
@@ -430,7 +424,7 @@ class ObjInspector extends St.ScrollView {
link = new St.Label({ text: '<error>' }); link = new St.Label({ text: '<error>' });
} }
let box = new St.BoxLayout(); let box = new St.BoxLayout();
box.add(new St.Label({ text: '%s: '.format(propName) })); box.add(new St.Label({ text: `${propName}: ` }));
box.add(link); box.add(link);
this._container.add_actor(box); this._container.add_actor(box);
} }
@@ -647,9 +641,9 @@ var Inspector = GObject.registerClass({
this._target = target; this._target = target;
this._pointerTarget = 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 = '';
this._displayText.text = '%s %s'.format(position, this._target); this._displayText.text = `${position} ${this._target}`;
this._lookingGlass.setBorderPaintTarget(this._target); this._lookingGlass.setBorderPaintTarget(this._target);
} }
@@ -852,7 +846,7 @@ class LookingGlass extends St.BoxLayout {
inspectIcon.connect('button-press-event', () => { inspectIcon.connect('button-press-event', () => {
let inspector = new Inspector(this); let inspector = new Inspector(this);
inspector.connect('target', (i, target, stageX, stageY) => { 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', () => { inspector.connect('closed', () => {
this.show(); this.show();
@@ -958,8 +952,9 @@ class LookingGlass extends St.BoxLayout {
// monospace font to be bold/oblique/etc. Could easily be added here. // monospace font to be bold/oblique/etc. Could easily be added here.
let size = fontDesc.get_size() / 1024.; let size = fontDesc.get_size() / 1024.;
let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt'; let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt';
this.style = 'font-size: %d%s; font-family: "%s";'.format( this.style = `
size, unit, fontDesc.get_family()); font-size: ${size}${unit};
font-family: "${fontDesc.get_family()}";`;
} }
setBorderPaintTarget(obj) { setBorderPaintTarget(obj) {
@@ -1040,7 +1035,7 @@ class LookingGlass extends St.BoxLayout {
this._history.addItem(command); this._history.addItem(command);
let lines = command.split(';'); let lines = command.split(';');
lines.push('return %s'.format(lines.pop())); lines.push(`return ${lines.pop()}`);
let fullCmd = commandHeader + lines.join(';'); let fullCmd = commandHeader + lines.join(';');
@@ -1048,7 +1043,7 @@ class LookingGlass extends St.BoxLayout {
try { try {
resultObj = Function(fullCmd)(); resultObj = Function(fullCmd)();
} catch (e) { } catch (e) {
resultObj = '<exception %s>'.format(e.toString()); resultObj = `<exception ${e}>`;
} }
this._pushResult(command, resultObj); this._pushResult(command, resultObj);
@@ -1067,7 +1062,7 @@ class LookingGlass extends St.BoxLayout {
try { try {
return this._resultsArea.get_child_at_index(idx - this._offset).o; return this._resultsArea.get_child_at_index(idx - this._offset).o;
} catch (e) { } 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. * Show the system mouse pointer.
*/ */
showSystemCursor() { showSystemCursor() {
const seat = Clutter.get_default_backend().get_default_seat();
if (seat.is_unfocus_inhibited())
seat.uninhibit_unfocus();
this._cursorTracker.set_pointer_visible(true); this._cursorTracker.set_pointer_visible(true);
} }
@@ -139,10 +135,6 @@ var Magnifier = class Magnifier {
* Hide the system mouse pointer. * Hide the system mouse pointer.
*/ */
hideSystemCursor() { hideSystemCursor() {
const seat = Clutter.get_default_backend().get_default_seat();
if (!seat.is_unfocus_inhibited())
seat.inhibit_unfocus();
this._cursorTracker.set_pointer_visible(false); 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 // Make sure system mouse pointer is shown when all zoom regions are
// invisible. // invisible.
if (!activate) if (!activate)
this.showSystemCursor(); this._cursorTracker.set_pointer_visible(true);
// Notify interested parties of this change // Notify interested parties of this change
this.emit('active-changed', activate); this.emit('active-changed', activate);
@@ -438,10 +430,8 @@ var Magnifier = class Magnifier {
* lines making up the crosshairs. * lines making up the crosshairs.
*/ */
setCrosshairsLength(length) { setCrosshairsLength(length) {
if (this._crossHairs) { if (this._crossHairs)
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; this._crossHairs.setLength(length);
this._crossHairs.setLength(length / scaleFactor);
}
} }
/** /**
@@ -755,7 +745,8 @@ var ZoomRegion = class ZoomRegion {
this._xCaret = 0; this._xCaret = 0;
this._yCaret = 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; this._scrollContentsTimerId = 0;
} }
@@ -807,14 +798,9 @@ var ZoomRegion = class ZoomRegion {
return; return;
} }
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; [this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
let [xFocus, yFocus] = [(extents.x + (extents.width / 2)) * scaleFactor, extents.y + (extents.height / 2)];
(extents.y + (extents.height / 2)) * scaleFactor]; this._centerFromFocusPosition();
if (this._xFocus !== xFocus || this._yFocus !== yFocus) {
[this._xFocus, this._yFocus] = [xFocus, yFocus];
this._centerFromFocusPosition();
}
} }
_updateCaret(caller, event) { _updateCaret(caller, event) {
@@ -829,13 +815,8 @@ var ZoomRegion = class ZoomRegion {
return; return;
} }
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; [this._xCaret, this._yCaret] = [extents.x, extents.y];
let [xCaret, yCaret] = [extents.x * scaleFactor, extents.y * scaleFactor]; this._centerFromCaretPosition();
if (this._xCaret !== xCaret || this._yCaret !== yCaret) {
[this._xCaret, this._yCaret] = [xCaret, yCaret];
this._centerFromCaretPosition();
}
} }
/** /**
@@ -883,8 +864,7 @@ var ZoomRegion = class ZoomRegion {
setMagFactor(xMagFactor, yMagFactor) { setMagFactor(xMagFactor, yMagFactor) {
this._changeROI({ xMagFactor, this._changeROI({ xMagFactor,
yMagFactor, yMagFactor,
redoCursorTracking: this._followingCursor, redoCursorTracking: this._followingCursor });
animate: true });
} }
/** /**
@@ -1142,13 +1122,6 @@ var ZoomRegion = class ZoomRegion {
return this._screenPosition; return this._screenPosition;
} }
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId !== 0) {
GLib.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
}
/** /**
* scrollToMousePos: * scrollToMousePos:
* Set the region of interest based on the position of the system pointer. * Set the region of interest based on the position of the system pointer.
@@ -1162,31 +1135,30 @@ var ZoomRegion = class ZoomRegion {
else else
this._updateMousePosition(); 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. // Determine whether the system mouse pointer is over this zoom region.
return this._isMouseOverRegion(); return this._isMouseOverRegion();
} }
_scrollContentsToDelayed(x, y) { _clearScrollContentsTimer() {
if (this._followingCursor) { if (this._scrollContentsTimerId != 0) {
this._xDelayed = x; GLib.source_remove(this._scrollContentsTimerId);
this._yDelayed = y; this._scrollContentsTimerId = 0;
} else {
this.scrollContentsTo(x, y);
} }
} }
_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: * scrollContentsTo:
* Shift the contents of the magnified view such it is centered on the given * 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. * @param {number} y: The y-coord of the point to center on.
*/ */
scrollContentsTo(x, y) { scrollContentsTo(x, y) {
if (x < 0 || x > global.screen_width ||
y < 0 || y > global.screen_height)
return;
this._clearScrollContentsTimer(); this._clearScrollContentsTimer();
this._followingCursor = false; this._followingCursor = false;
this._changeROI({ xCenter: x, this._changeROI({ xCenter: x,
yCenter: y, yCenter: y });
animate: true });
} }
/** /**
@@ -1356,7 +1323,7 @@ var ZoomRegion = class ZoomRegion {
this._crossHairsActor = null; this._crossHairsActor = null;
// Contrast and brightness effects. // Contrast and brightness effects.
this._magShaderEffects = new MagShaderEffects(mainGroup); this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
this._magShaderEffects.setColorSaturation(this._colorSaturation); this._magShaderEffects.setColorSaturation(this._colorSaturation);
this._magShaderEffects.setInvertLightness(this._invertLightness); this._magShaderEffects.setInvertLightness(this._invertLightness);
this._magShaderEffects.setBrightness(this._brightness); this._magShaderEffects.setBrightness(this._brightness);
@@ -1413,8 +1380,7 @@ var ZoomRegion = class ZoomRegion {
yMagFactor: this._yMagFactor, yMagFactor: this._yMagFactor,
xCenter: this._xCenter, xCenter: this._xCenter,
yCenter: this._yCenter, yCenter: this._yCenter,
redoCursorTracking: false, redoCursorTracking: false });
animate: false });
if (params.xMagFactor <= 0) if (params.xMagFactor <= 0)
params.xMagFactor = this._xMagFactor; params.xMagFactor = this._xMagFactor;
@@ -1453,7 +1419,8 @@ var ZoomRegion = class ZoomRegion {
height: this._viewPortHeight }, true); height: this._viewPortHeight }, true);
} }
this._updateCloneGeometry(params.animate); this._updateCloneGeometry();
this._updateMousePosition();
} }
_isMouseOverRegion() { _isMouseOverRegion() {
@@ -1591,64 +1558,38 @@ var ZoomRegion = class ZoomRegion {
this._magView.set_position(this._viewPortX, this._viewPortY); this._magView.set_position(this._viewPortX, this._viewPortY);
} }
_updateCloneGeometry(animate = false) { _updateCloneGeometry() {
if (!this.isActive()) if (!this.isActive())
return; return;
this._uiGroupClone.set_scale(this._xMagFactor, this._yMagFactor);
this._mouseActor.set_scale(this._xMagFactor, this._yMagFactor);
let [x, y] = this._screenToViewPort(0, 0); let [x, y] = this._screenToViewPort(0, 0);
this._uiGroupClone.ease({ this._uiGroupClone.set_position(Math.round(x), Math.round(y));
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,
});
let [mouseX, mouseY] = this._getMousePosition(); this._updateMousePosition();
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,
});
}
} }
_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); this._mouseActor.set_position(xMagMouse, yMagMouse);
if (this._crossHairsActor) { if (this._crossHairsActor) {
let [crossX, crossY] = this._getCrossHairsPosition(); let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
this._crossHairsActor.set_position(crossX, crossY); 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() { _monitorsChanged() {
this._background.set_size(global.screen_width, global.screen_height); this._background.set_size(global.screen_width, global.screen_height);
this._updateScreenPosition(); this._updateScreenPosition();
@@ -1867,10 +1808,12 @@ class Crosshairs extends Clutter.Actor {
let clipWidth = this._clipSize[0]; let clipWidth = this._clipSize[0];
let clipHeight = this._clipSize[1]; let clipHeight = this._clipSize[1];
let left = groupWidth / 2 - clipWidth / 2 - leftLength - thickness / 2; // Note that clip, if present, is not centred on the cross hair
let right = groupWidth / 2 + clipWidth / 2 + thickness / 2; // intersection, but biased towards the top left.
let top = groupHeight / 2 - clipHeight / 2 - topLength - thickness / 2; let left = groupWidth / 2 - clipWidth * 0.25 - leftLength;
let bottom = groupHeight / 2 + clipHeight / 2 + thickness / 2; 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._horizLeftHair.set_position(left, (groupHeight - thickness) / 2);
this._horizRightHair.set_position(right, (groupHeight - thickness) / 2); this._horizRightHair.set_position(right, (groupHeight - thickness) / 2);
this._vertTopHair.set_position((groupWidth - thickness) / 2, top); this._vertTopHair.set_position((groupWidth - thickness) / 2, top);

View File

@@ -161,8 +161,6 @@ function _initializeUI() {
_loadOskLayouts(); _loadOskLayouts();
_loadDefaultStylesheet(); _loadDefaultStylesheet();
new AnimationsSettings();
// Setup the stage hierarchy early // Setup the stage hierarchy early
layoutManager = new Layout.LayoutManager(); layoutManager = new Layout.LayoutManager();
@@ -259,7 +257,7 @@ function _initializeUI() {
if (sessionMode.currentMode != 'gdm' && if (sessionMode.currentMode != 'gdm' &&
sessionMode.currentMode != 'initial-setup') { sessionMode.currentMode != 'initial-setup') {
GLib.log_structured(LOG_DOMAIN, GLib.LogLevelFlags.LEVEL_MESSAGE, { 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, 'MESSAGE_ID': GNOMESHELL_STARTED_MESSAGE_ID,
}); });
} }
@@ -282,7 +280,7 @@ function _initializeUI() {
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE"); let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
if (perfModuleName) { if (perfModuleName) {
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT"); 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); Scripting.runPerfScript(module, perfOutput);
} }
}); });
@@ -291,7 +289,7 @@ function _initializeUI() {
function _getStylesheet(name) { function _getStylesheet(name) {
let stylesheet; 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)) if (stylesheet.query_exists(null))
return stylesheet; return stylesheet;
@@ -303,7 +301,7 @@ function _getStylesheet(name) {
return stylesheet; 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)) if (stylesheet.query_exists(null))
return stylesheet; return stylesheet;
@@ -361,12 +359,12 @@ function reloadThemeResource() {
if (_themeResource) if (_themeResource)
_themeResource._unregister(); _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(); _themeResource._register();
} }
function _loadOskLayouts() { 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(); _oskResource._register();
} }
@@ -420,9 +418,9 @@ function notify(msg, details) {
function notifyError(msg, details) { function notifyError(msg, details) {
// Also print to stderr so it's logged somewhere // Also print to stderr so it's logged somewhere
if (details) if (details)
log('error: %s: %s'.format(msg, details)); log(`error: ${msg}: ${details}`);
else else
log('error: %s'.format(msg)); log(`error: ${msg}`);
notify(msg, details); notify(msg, details);
} }
@@ -689,7 +687,7 @@ function _queueBeforeRedraw(workId) {
*/ */
function initializeDeferredWork(actor, callback) { function initializeDeferredWork(actor, callback) {
// Turn into a string so we can use as an object property // Turn into a string so we can use as an object property
let workId = (++_deferredWorkSequence).toString(); let workId = `${++_deferredWorkSequence}`;
_deferredWorkData[workId] = { actor, _deferredWorkData[workId] = { actor,
callback }; callback };
actor.connect('notify::mapped', () => { actor.connect('notify::mapped', () => {
@@ -760,46 +758,3 @@ function showRestartMessage(message) {
let restartMessage = new RestartMessage(message); let restartMessage = new RestartMessage(message);
restartMessage.open(); 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) { if (urlId != -1) {
let url = this._urls[urlId].url; let url = this._urls[urlId].url;
if (!url.includes(':')) if (!url.includes(':'))
url = 'http://%s'.format(url); url = `http://${url}`;
Gio.app_info_launch_default_for_uri( Gio.app_info_launch_default_for_uri(
url, global.create_app_launch_context(0, -1)); 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++) { for (let i = 0; i < urls.length; i++) {
let url = urls[i]; let url = urls[i];
let str = this._text.substr(pos, url.pos - pos); 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; pos = url.pos + url.url.length;
} }
markup += this._text.substr(pos); markup += this._text.substr(pos);

View File

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

View File

@@ -147,7 +147,7 @@ var MprisPlayer = class MprisPlayer {
// so prefer activating the app via .desktop file if possible // so prefer activating the app via .desktop file if possible
let app = null; let app = null;
if (this._mprisProxy.DesktopEntry) { 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); app = Shell.AppSystem.get_default().lookup_app(desktopId);
} }
@@ -192,9 +192,9 @@ var MprisPlayer = class MprisPlayer {
if (!Array.isArray(this._trackArtists) || if (!Array.isArray(this._trackArtists) ||
!this._trackArtists.every(artist => typeof artist === 'string')) { !this._trackArtists.every(artist => typeof artist === 'string')) {
if (typeof this._trackArtists !== 'undefined') { if (typeof this._trackArtists !== 'undefined') {
log(('Received faulty track artist metadata from %s; ' + log(`Received faulty track artist metadata from ${
'expected an array of strings, got %s (%s)').format( this._busName}; expected an array of strings, got ${
this._busName, this._trackArtists, typeof this._trackArtists)); this._trackArtists} (${typeof this._trackArtists})`);
} }
this._trackArtists = [_("Unknown artist")]; this._trackArtists = [_("Unknown artist")];
} }
@@ -202,9 +202,9 @@ var MprisPlayer = class MprisPlayer {
this._trackTitle = metadata['xesam:title']; this._trackTitle = metadata['xesam:title'];
if (typeof this._trackTitle !== 'string') { if (typeof this._trackTitle !== 'string') {
if (typeof this._trackTitle !== 'undefined') { if (typeof this._trackTitle !== 'undefined') {
log(('Received faulty track title metadata from %s; ' + log(`Received faulty track title metadata from ${
'expected a string, got %s (%s)').format( this._busName}; expected a string, got ${
this._busName, this._trackTitle, typeof this._trackTitle)); this._trackTitle} (${typeof this._trackTitle})`);
} }
this._trackTitle = _("Unknown title"); this._trackTitle = _("Unknown title");
} }
@@ -212,9 +212,9 @@ var MprisPlayer = class MprisPlayer {
this._trackCoverUrl = metadata['mpris:artUrl']; this._trackCoverUrl = metadata['mpris:artUrl'];
if (typeof this._trackCoverUrl !== 'string') { if (typeof this._trackCoverUrl !== 'string') {
if (typeof this._trackCoverUrl !== 'undefined') { if (typeof this._trackCoverUrl !== 'undefined') {
log(('Received faulty track cover art metadata from %s; ' + log(`Received faulty track cover art metadata from ${
'expected a string, got %s (%s)').format( this._busName}; expected a string, got ${
this._busName, this._trackCoverUrl, typeof this._trackCoverUrl)); this._trackCoverUrl} (${typeof this._trackCoverUrl})`);
} }
this._trackCoverUrl = ''; this._trackCoverUrl = '';
} }
@@ -251,10 +251,6 @@ class MediaSection extends MessageList.MessageListSection {
return !this.empty && Calendar.isToday(this._date); return !this.empty && Calendar.isToday(this._date);
} }
get allowed() {
return !Main.sessionMode.isGreeter;
}
_addPlayer(busName) { _addPlayer(busName) {
if (this._players.get(busName)) if (this._players.get(busName))
return; return;

View File

@@ -477,7 +477,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
return app; return app;
if (appId) { 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) if (app != null)
return app; return app;
} }
@@ -614,7 +614,7 @@ function objectPathFromAppId(appId) {
} }
function getPlatformData() { 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 }; return { "desktop-startup-id": startupId };
} }
@@ -627,7 +627,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
if (!GLib.Variant.is_object_path(objectPath)) if (!GLib.Variant.is_object_path(objectPath))
throw new InvalidAppError(); 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) if (!app)
throw new InvalidAppError(); throw new InvalidAppError();

View File

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

View File

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

View File

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

View File

@@ -533,9 +533,6 @@ class PanelCorner extends St.DrawingArea {
if (index < 0) if (index < 0)
return null; return null;
if (!(children[index] instanceof St.Widget))
return null;
if (!children[index].has_style_class_name('panel-menu') && if (!children[index].has_style_class_name('panel-menu') &&
!children[index].has_style_class_name('panel-button')) !children[index].has_style_class_name('panel-button'))
return this._findRightmostButton(children[index]); return this._findRightmostButton(children[index]);
@@ -561,9 +558,6 @@ class PanelCorner extends St.DrawingArea {
if (index == children.length) if (index == children.length)
return null; return null;
if (!(children[index] instanceof St.Widget))
return null;
if (!children[index].has_style_class_name('panel-menu') && if (!children[index].has_style_class_name('panel-menu') &&
!children[index].has_style_class_name('panel-button')) !children[index].has_style_class_name('panel-button'))
return this._findLeftmostButton(children[index]); return this._findLeftmostButton(children[index]);
@@ -1105,7 +1099,7 @@ class Panel extends St.Widget {
addToStatusArea(role, indicator, position, box) { addToStatusArea(role, indicator, position, box) {
if (this.statusArea[role]) 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)) if (!(indicator instanceof PanelMenu.Button))
throw new TypeError('Status indicator must be an instance of PanelMenu.Button'); throw new TypeError('Status indicator must be an instance of PanelMenu.Button');

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