Compare commits

..

1 Commits

421 changed files with 33511 additions and 81152 deletions

6
.eslintrc.json Normal file
View File

@ -0,0 +1,6 @@
{
"extends": [
"./lint/eslintrc-gjs.json",
"./lint/eslintrc-shell.json"
]
}

View File

@ -1,3 +0,0 @@
extends:
- ./lint/eslintrc-gjs.yml
- ./lint/eslintrc-shell.yml

2
.gitignore vendored
View File

@ -21,8 +21,6 @@ data/org.gnome.shell.gschema.valid
data/org.gnome.Shell.PortalHelper.desktop
data/org.gnome.Shell.PortalHelper.service
data/theme/.sass-cache
data/theme/gnome-shell*.css.map
data/theme/gnome-shell*.css
docs/reference/*/*.args
docs/reference/*/*.bak
docs/reference/*/*.hierarchy

View File

@ -1,5 +1,6 @@
stages:
- review
- source_check
- build
- test
@ -14,7 +15,7 @@ variables:
- merge_requests
check_commit_log:
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
stage: review
variables:
GIT_DEPTH: "100"
@ -25,36 +26,28 @@ check_commit_log:
js_check:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: review
stage: source_check
script:
- find js -name '*.js' -exec js60 -c -s '{}' ';' 2>&1 | tee $JS_LOG
- (! grep -q . $JS_LOG)
<<: *only_default
only:
changes:
- js/**/*
artifacts:
paths:
- ${JS_LOG}
when: on_failure
eslint:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: review
script:
- ./.gitlab-ci/run-eslint.sh
<<: *only_default
artifacts:
paths:
- reports
when: always
build:
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
stage: build
before_script:
- .gitlab-ci/checkout-mutter.sh
- meson mutter mutter/build --prefix=/usr -Dtests=false
- ninja -C mutter/build install
script:
- meson . build -Dbuiltype=debugoptimized -Dman=false --werror
- meson . build -Dbuiltype=debugoptimized
- ninja -C build
- ninja -C build install
<<: *only_default
@ -65,15 +58,12 @@ build:
- build
test:
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
stage: test
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
NO_AT_BRIDGE: "1"
before_script:
- ninja -C mutter/build install
script:
- dbus-run-session -- xvfb-run meson test -C build --no-rebuild
- xvfb-run meson test -C build --no-rebuild
<<: *only_default
artifacts:
expire_in: 1 day
@ -82,7 +72,7 @@ test:
when: on_failure
test-pot:
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
stage: test
before_script:
- ninja -C mutter/build install

View File

@ -1,7 +1,7 @@
FROM registry.fedoraproject.org/fedora:latest
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(copr)' git && \
dnf install -y 'dnf-command(copr)' && \
# For syntax checks with `find . -name '*.js' -exec js60 -c -s '{}' ';'`
dnf install -y findutils mozjs60-devel && \

View File

@ -1,5 +1,6 @@
#!/usr/bin/bash
shell_branch=$(git describe --contains --all HEAD)
mutter_target=
git clone https://gitlab.gnome.org/GNOME/mutter.git
@ -25,7 +26,8 @@ if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
fi
if [ -z "$mutter_target" ]; then
mutter_target=$(git branch -r -l origin/$CI_COMMIT_REF_NAME)
mutter_target=$(git branch -r -l origin/$shell_branch)
mutter_target=${mutter_target:-$(git branch -r -l ${shell_branch#remotes/})}
mutter_target=${mutter_target:-origin/master}
echo Using $mutter_target instead
fi

View File

@ -1,114 +0,0 @@
#!/usr/bin/env bash
OUTPUT_REGULAR=reports/lint-regular-report.txt
OUTPUT_LEGACY=reports/lint-legacy-report.txt
OUTPUT_FINAL=reports/lint-common-report.txt
OUTPUT_MR=reports/lint-mr-report.txt
LINE_CHANGES=changed-lines.txt
is_empty() {
(! grep -q . $1)
}
run_eslint() {
ARGS_LEGACY='--config lint/eslintrc-legacy.yml'
local extra_args=ARGS_$1
local output_var=OUTPUT_$1
local output=${!output_var}
# ensure output exists even if eslint doesn't report any errors
mkdir -p $(dirname $output)
touch $output
eslint -f unix ${!extra_args} -o $output js
}
list_commit_range_additions() {
# Turn raw context-less git-diff into a list of
# filename:lineno pairs of new (+) lines
git diff -U0 "$@" -- js |
awk '
BEGIN { file=""; }
/^+++ b/ { file=substr($0,7); }
/^@@ / {
len = split($3,a,",")
start=a[1]
count=(len > 1) ? a[2] : 1
for (line=start; line<start+count; line++)
printf "%s/%s:%d:\n",ENVIRON["PWD"],file,line;
}'
}
copy_matched_lines() {
local source=$1
local matches=$2
local target=$3
echo -n > $target
for l in $(<$matches); do
grep $l $source >> $target
done
}
create_common() {
# comm requires sorted input;
# we also strip the error message to make the following a "common" error:
# regular:
# file.js:42:23 Indentation of 55, expected 42
# legacy:
# file.js:42:23 Indentation of 55, extected 24
prepare() {
sed 's: .*::' $1 | sort
}
comm -12 <(prepare $OUTPUT_REGULAR) <(prepare $OUTPUT_LEGACY) >$OUTPUT_FINAL.tmp
# Now add back the stripped error messages
copy_matched_lines $OUTPUT_REGULAR $OUTPUT_FINAL.tmp $OUTPUT_FINAL
rm $OUTPUT_FINAL.tmp
}
# Disable MR handling for now. We aren't ready to enforce
# non-legacy style just yet ...
unset CI_MERGE_REQUEST_TARGET_BRANCH_NAME
REMOTE=${1:-$CI_MERGE_REQUEST_PROJECT_URL.git}
BRANCH_NAME=${2:-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
if [ "$BRANCH_NAME" ]; then
git fetch $REMOTE $BRANCH_NAME
branch_point=$(git merge-base HEAD FETCH_HEAD)
commit_range=$branch_point...HEAD
list_commit_range_additions $commit_range > $LINE_CHANGES
# Don't bother with running lint when no JS changed
if is_empty $LINE_CHANGES; then
exit 0
fi
fi
echo Generating lint report using regular configuration
run_eslint REGULAR
echo Generating lint report using legacy configuration
run_eslint LEGACY
echo Done.
create_common
if ! is_empty $OUTPUT_FINAL; then
cat $OUTPUT_FINAL
exit 1
fi
# Just show the report and succeed when not testing a MR
if [ -z "$BRANCH_NAME" ]; then
exit 0
fi
copy_matched_lines $OUTPUT_REGULAR $LINE_CHANGES $OUTPUT_MR
cat $OUTPUT_MR
is_empty $OUTPUT_MR

View File

@ -1,55 +0,0 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Affected version
<!--
Provide at least the following information:
* Your OS and version
* Affected GNOME Shell version
* Does this issue appear in XOrg and/or Wayland
-->
### Bug summary
<!--
Provide a short summary of the bug you encountered.
-->
### Steps to reproduce
<!--
1. Step one
2. Step two
3. ...
-->
### What happened
<!--
What did GNOME Shell do that was unexpected?
-->
### What did you expect to happen
<!--
What did you expect GNOME Shell to do?
-->
### Relevant logs, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation, logs,
screenshots or screencasts related, please provide them here.
If the bug is a crash, please obtain a stack trace with installed debug
symbols (at least for GNOME Shell and Mutter) and attach it to
this issue following the instructions on
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces.
-->
<!-- Do not remove the following line. -->
/label ~"1. Bug"

View File

@ -1,30 +0,0 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Feature summary
<!--
Describe what you would like to be able to do with GNOME Shell
that you currently cannot do.
-->
### How would you like it to work
<!--
If you can think of a way GNOME Shell might be able to do this,
let us know here.
-->
### Relevant links, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation,
code, mockups or a similar feature in another desktop environments,
please provide them here.
-->
<!-- Do not remove the following line. -->
/label ~"1. Feature"

View File

@ -29,8 +29,9 @@ what to do.
bar = do_thing(b);
if (var == 5) {
for (let i = 0; i < 10; i++)
for (let i = 0; i < 10; i++) {
print(i);
}
} else {
print(20);
}
@ -83,6 +84,7 @@ don't use.
const Main = imports.ui.main;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
```
The alphabetical ordering should be done independently of the location of the
@ -101,8 +103,9 @@ under the imports:
Always use either `const` or `let` when defining a variable.
```javascript
// Iterating over an array
for (let i = 0; i < arr.length; ++i)
for (let i = 0; i < arr.length; ++i) {
let item = arr[i];
}
// Iterating over an object's properties
for (let prop in someobj) {
@ -161,17 +164,11 @@ you to inherit from a type to use it, you can do so:
return [100, 100];
}
vfunc_paint(paintContext) {
let framebuffer = paintContext.get_framebuffer();
let coglContext = framebuffer.get_context();
vfunc_paint() {
let alloc = this.get_allocation_box();
let pipeline = new Cogl.Pipeline(coglContext);
pipeline.set_color4ub(255, 0, 0, 255);
framebuffer.draw_rectangle(pipeline,
alloc.x1, alloc.y1,
alloc.x2, alloc.y2);
Cogl.set_source_color4ub(255, 0, 0, 255);
Cogl.rectangle(alloc.x1, alloc.y1,
alloc.x2, alloc.y2);
}
});
```
@ -190,27 +187,15 @@ and "double quotes" for strings that the user may see. This allows us to
quickly find untranslated or mistranslated strings by grepping through the
sources for double quotes without a gettext call around them.
## `actor` (deprecated) and `_delegate`
## `actor` and `_delegate`
gjs allows us to set so-called "expando properties" on introspected objects,
allowing us to treat them like any other. Because the Shell was built before
you could inherit from GTypes natively in JS, in some cases we have a wrapper
class that has a property called `actor` (now deprecated). We call this
wrapper class the "delegate".
you could inherit from GTypes natively in JS, we usually have a wrapper class
that has a property called `actor`. We call this wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on
the actor itself:
```javascript
var MyActor = GObject.registerClass(
class MyActor extends Clutter.Actor {
_init(params) {
super._init(params);
this._delegate = this;
}
});
```
Or using the deprecated `actor`:
```javascript
var MyClass = class {
constructor() {
@ -231,7 +216,6 @@ delegate object from an associated actor. For instance, the drag and drop
system calls the `handleDragOver` function on the delegate of a "drop target"
when the user drags an item over it. If you do not set the `_delegate`
property, your actor will not be able to be dropped onto.
In case the class is an actor itself, the `_delegate` can be just set to `this`.
## Functional style
@ -250,7 +234,7 @@ variable that can be captured in closures.
All closures should be wrapped with Function.prototype.bind or use arrow
notation.
```javascript
let closure1 = () => this._fnorbate();
let closure1 = () => { this._fnorbate(); };
let closure2 = this._fnorbate.bind(this);
```
@ -293,49 +277,34 @@ If your usage of an object is like a hash table (and thus conceptually the keys
can have special chars in them), don't use quotes, but use brackets: `{ bar: 42
}`, `foo['bar']`.
## Animations
Most objects that are animated are actors, and most properties used in animations
are animatable, which means they can use implicit animations:
## Getters, setters, and Tweener
Getters and setters should be used when you are dealing with an API that is
designed around setting properties, like Tweener. If you want to animate an
arbitrary property, create a getter and setter, and use Tweener to animate the
property.
```javascript
moveActor(actor, x, y) {
actor.ease({
x,
y,
duration: 500, // ms
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
}
```
The above is a convenience wrapper around the actual Clutter API, and should generally
be preferred over the more verbose:
```javascript
moveActor(actor, x, y) {
actor.save_easing_state();
actor.set_easing_duration(500);
actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
actor.set({
x,
y
});
actor.restore_easing_state();
}
```
There is a similar convenience API around Clutter.PropertyTransition to animate
actor (or actor meta) properties that cannot use implicit animations:
```javascript
desaturateActor(actor, desaturate) {
let factor = desaturate ? 1.0 : 0.0;
actor.ease_property('@effects.desaturate.factor', factor, {
duration: 500, // ms
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
}
var ANIMATION_TIME = 2000;
var MyClass = class {
constructor() {
this.actor = new St.BoxLayout();
this._position = 0;
}
get position() {
return this._position;
}
set position(value) {
this._position = value;
this.actor.set_position(value, value);
}
};
let myThing = new MyClass();
Tweener.addTween(myThing,
{ position: 100,
time: ANIMATION_TIME,
transition: 'easeOutQuad' });
```

235
NEWS
View File

@ -1,238 +1,3 @@
3.35.3
======
* Add discrete GPU support for NVidia drivers [Bastien; #1810]
* Fix DND of window previews with tablet devices [Carlos; !897]
* Update pad OSD actions dynamically on mode changes [Carlos; !898]
* st: Add dedicated PasswordEntry widget [Umang; !619]
* Allow stand-alone builds of gnome-extensions tool [Florian; !877]
* extension-tool: Don't treat missing .js handler as error [Chuck; !905]
* Disallow top bar menus without top bar [Florian; #2002]
* Misc. bug fixes and cleanups [Georges, Florian, Robert, Umang; !901,
#789937, !909, !910, !911, !913, !916]
Contributors:
Michael Catanzaro, Chuck, Carlos Garnacho, Umang Jain, Robert Mader,
Florian Müllner, Georges Basile Stavracas Neto, Bastien Nocera
Translators:
Fabio Tomat [fur], Fran Dieguez [gl], Jordi Mas [ca], Daniel Mustieles [es]
3.35.2
======
* Fix unredirection after cancelled animations [Florian; #1788]
* Include shadow in window screenshots [Robert; !762]
* Show indicator when microphone is active [Florian; !729]
* Use inheritance instead of delegate pattern [Marco; !559]
* Use cached coordinates for window sorting in overview [Andrew; !763]
* Wiggle login/unlock password entries on failure [Georges; !769]
* Update window titles in app menu [Florian; #1830]
* Fix window animations getting stuck by workspace switches [Jonas D.; !784]
* Fix not-responding dialog size when using geometry scaling [Jonas D.; !783]
* Handle buggy MPRIS clients more gracefully [Philip; #1362]
* Deprecate StBoxLayout's child properties [Florian; !780]
* Remove StBin's align properties [Florian; !803]
* Use correct timezones for events [Milan, Florian; !806, #1895]
* Reduce overhead of tracking stylesheet changes [Carlos; !779]
* Replace action icons in system menu with regular menu items [Florian; #270]
* Refine polkit dialogs [Jonas D.; !788]
* Fix battery icon glitch in "100% but charging" case [Philip; !814]
* Fix windows getting stuck on screen if closed while animating [Florian; !815]
* Use font from interface settings [Florian; #688288]
* Show polkit confirmation dialog for users with no password
[Joaquim, Jonas D.; !829]
* Use better OSK layout fallback for unsupported variants [Florian; #1907]
* Hide stopped spinner in top bar [Joonas; !832]
* Reuse existing icons when updating the app picker grid [Georges; !841]
* Show switcher popups immediately on second key press [Florian; #1928]
* Add position-based animation to page indicators [Alexander; !843]
* Improve modifier-less keyboard navigation of switcher popups [Florian; #1883]
* Improve weather integration [Florian; #1927, #1926]
* Add back sound feedback when scrolling volume indicator [Florian; #53]
* Fix creating app folders with no pre-existing folders [Jonas D.; #1652]
* Improve DND page switching in app picker [Florian, Jonas D.; #1693]
* Fix disable command of gnome-extensions tool [Florian; #1946]
* Tweak styling of notifications/media constrols [Joonas; !855, !865]
* Enable clean session shutdown after gnome-shell failure [Benjamin; !858]
* Also remove scaled keys when texture cache is cleared [Daniel M.; !567]
* Don't show overflow indicator in switchers that fit screen [Florian; #1834]
* Move libcroco dependency in-tree [Federico; !861]
* Move to app folder location when it is created/renamed [Georges; !883]
* Dismiss switcher popups when a system modal dialogs opens [Florian; #1536]
* Fix weather forecasts for automatic location when Weather is not sandboxed
[Florian; #1823]
* Place launched applications into a systemd scope [Benjamin; !863]
* Fixed crashes [Jonas D., Carlos; !787, !813]
* Misc. bug fixes and cleanups [Marco, Georges, Daniel V., Florian, Robert,
Kalev, Philip, Jonas D., Will, Carlos, Jonas Å., cunidev, Joonas, Federico;
!747, !765, !421, !759, !749, !730, !770, #1799, !774, !773, !776, !777,
!782, !794, !778, !792, !790, !190, !796, !795, !797, !798, !800, !804, !808,
!807, !810, !811, !563, !809, !805, !817, !818, !822, !830, !828, !823, !835,
!840, !842, !833, !845, !846, !847, !851, #1916, !862, !866, #1979, !827,
#1976, !884, !873, !885, !799, !887, !891, !816]
Contributors:
Marco Trevisan (Treviño), Benjamin Berg, Philip Chimento, Milan Crha,
Jonas Dreßler, Carlos Garnacho, Joonas Henriksson, Kalev Lember, Robert Mader,
Alexander Mikhaylenko, Daniel García Moreno, Florian Müllner,
Georges Basile Stavracas Neto, Federico Mena Quintero, Joaquim Rocha,
Will Thompson, Daniel van Vugt, Andrew Watson, cunidev, Jonas Ådahl
Translators:
Daniel Mustieles [es], Goran Vidović [hr], Fabio Tomat [fur],
Danial Behzadi [fa], Andika Triwidada [id], Efstathios Iosifidis [el],
Ricardo Silva Veloso [pt_BR]
3.35.1
======
* Misc. bug fixes and cleanups [Marco; Matthias; !758, #701212]
Contributors:
Marco Trevisan (Treviño)
3.34.1
======
* Fix "Frequent" view icons disappearing on hover [Jonas D.; #1502]
* Allow editing app folder names [Georges, Marco; !675, !720]
* Skip property transitions while hidden [Florian; !708]
* Make menu animations more consistent [Florian, GB_2; #1595, !717]
* Improve performance when enabling/disabling all extensions [Jonas D.; !96]
* Fix extra icons appearing in "Frequent" view animation [Georges; !696]
* Fix fading out desktop icons [Harshula; #1616]
* Fix box-shadow glitch with prerendered resources [Daniel; #1186]
* Fix accidentally skipped animations [Florian; #1572]
* Fix screenshots and window animations when scaled [Robert; !728]
* Don't leak NOTIFY_SOCKET environment variable to applications [Benjamin; !741]
* Fix lock-up on X11 when ibus is already running on startup [Marco; #1712]
* Fix screen dimming on idle [Marco; #1683]
* Do not notify systemd before initialization is complete [Iain; !750]
* Support SAE secrets in network agent [Lubomir; !751]
* Fix various regressions with dynamic workspaces [Florian; #1497]
* Fixed crashes [Florian, Marco; #1678, !746]
* Misc. bug fixes and cleanups [Marco, Jonas D., Florian, Iain, Georges,
Jonas Å., Martin, Takao, Carlos; !700, !705, !709, !711, !707, #1538, !710,
!713, !699, !715, !718, !716, !719, !721, #1243, !725, !731, #1614, !683,
!732, !121, !735, !736, !740, #573, #1641, #1571]
Contributors:
Marco Trevisan (Treviño), Benjamin Berg, Jonas Dreßler, Takao Fujiwara, GB_2,
Carlos Garnacho, Harshula Jayasuriya, Iain Lane, Robert Mader,
Daniel García Moreno, Florian Müllner, Georges Basile Stavracas Neto,
Lubomir Rintel, Martin Zurowietz, Jonas Ådahl
Translators:
Rafael Fontenelle [pt_BR], Fran Dieguez [gl], Balázs Úr [hu],
Milo Casagrande [it], Daniel Șerbănescu [ro], Kukuh Syafaat [id],
Jiri Grönroos [fi], Daniel Mustieles [es], Piotr Drąg [pl],
Anders Jonsson [sv], Marek Černocký [cs], Jordi Mas [ca],
Aurimas Černius [lt], Christian Kirbach [de], Emin Tufan Çetin [tr],
Enrico Nicoletto [pt_BR], Danial Behzadi [fa], Марко Костић [sr],
Alexandre Franke [fr], Charles Monzat [fr], Kjartan Maraas [nb],
Ryuta Fujii [ja], Nathan Follens [nl], Dušan Kazik [sk], Fabio Tomat [fur],
Matej Urbančič [sl], Ask Hjorth Larsen [da], Alan Mortensen [da]
3.34.0
======
* Handle startup/shutdown of misc X11 services [Carlos; !680]
* Fix sound volume mute/unmute [Iain; #1557]
* Correctly terminate pasted text [Carlos; #1570]
Contributors:
Carlos Garnacho, Iain Lane
Translators:
Tom Tryfonidis [el], Milo Casagrande [it], Ryuta Fujii [ja],
Efstathios Iosifidis [el], Carmen Bianca BAKKER [eo], Sabri Ünal [tr],
Dušan Kazik [sk], Balázs Meskó [hu], Claude Paroz [fr]
3.33.92
=======
* Animate pointer a11y pie timer [Jonas D.; !688]
* Fix restarting shell in systemd user session [Benjamin; !690]
* Misc. bug fixes and cleanups [Florian, Jonas D., Jonas Å., Will;
!691, !689, !692, #1552, !698]
Contributors:
Jonas Ådahl, Benjamin Berg, Piotr Drąg, Jonas Dreßler, Florian Müllner,
Will Thompson
Translators:
Daniel Șerbănescu [ro], Danial Behzadi [fa], Daniel Mustieles [es],
Jiri Grönroos [fi], Asier Sarasua Garmendia [eu], Piotr Drąg [pl],
Rūdolfs Mazurs [lv], Anders Jonsson [sv], Fran Dieguez [gl], Jordi Mas [ca],
Matej Urbančič [sl], Zander Brown [en_GB], Ryuta Fujii [ja], Tim Sabsch [de],
Fabio Tomat [fur], Pawan Chitrakar [ne], A S Alam [pa], Changwoo Ryu [ko],
Aurimas Černius [lt], Daniel Rusek [cs], Marek Černocký [cs],
Kukuh Syafaat [id], Goran Vidović [hr], Rafael Fontenelle [pt_BR]
3.33.91
=======
* Fix regression when adjusting brightness [Florian; #1500]
* Fix pointer a11y timeout animation [Jonas D.; #1533]
* Add new extensions CLI tool [Florian; #1234]
* Only track top-level windows [Carlos; #556]
* Misc. bug fixes and cleanups [Jonas D., Jonas Å., Piotr, Florian;
!678, !682, !686]
Contributors:
Jonas Ådahl, Jonas Dreßler, Carlos Garnacho, Florian Müllner
Translators:
Asier Sarasua Garmendia [eu], Sveinn í Felli [is], Anders Jonsson [sv],
Jordi Mas [ca], Kukuh Syafaat [id], Florentina Mușat [ro], Jiri Grönroos [fi],
Aurimas Černius [lt], Daniel Mustieles [es], Piotr Drąg [pl],
Danial Behzadi [fa]
3.33.90
=======
* Implement DND app picker folder management [Georges; !643, !645, !664, !671]
* Make Clocks/Weather integration work with sandboxed apps [Florian; #1158]
* Support startup via systemd user instance [Benjamin; !507]
* Replace Tweener with Clutter animations [Florian; !663, !22, !666, !668, !669]
* Minimize travel distance in overview animation [Sergey; !267]
* Rescan icon theme when installed apps changed [Georges; !661]
* Consistently animate new window actions [Jonas; !662, !673]
* Misc. bug fixes and cleanups [Florian, Daniel, Ray, Bastien, Jonas, Niels,
Marco, Georges; !635, !636, !637, #1462, !628, !640, !641, !627, !644, !647,
!385, #1474, !651, #1144, !646, !653, !652, !655, #1482, !656, $654, !665,
!667, !670, #1357, !672, !657, #1507, !674, !677]
Contributors:
Benjamin Berg, Sergey Bugaev, Jonas Dreßler, Niels De Graef, Florian Müllner,
Georges Basile Stavracas Neto, Bastien Nocera, Ray Strode,
Marco Trevisan (Treviño), verdre, Daniel van Vugt
Translators:
Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR],
Kristjan SCHMIDT [eo], Jor Teron [mjw], Daniel Mustieles [es],
Kukuh Syafaat [id], Jordi Mas [ca], Fabio Tomat [fur], Daniel Șerbănescu [ro],
Anders Jonsson [sv]
3.33.4
======
* Fix unintentional interference between gestures [Jonas; !598]
* Fix unintentional loop while polkit dialog is active [Ray; !602]
* Fix alt-tab icon size on HiDPI [Jonas; !587]
* Style fixes and improvements [Frederik, Jakub; !610, #1446, #1449]
* Fix style updates for non-background CSS properties [Florian; #1212]
* Fix cursor visibility in screen recordings [Illya; #1208]
* Add option for disabling the hot corner [Florian; #688320]
* Use more fine-grained levels in battery indicator [Florian; !561, #1442]
* Fix the calculation of the maximum number of app search results [Jonas; !110]
* Handle horizontal workspace layout with gestures/animations [Florian; !575]
* Improve handling of session mode extensions [Florian, Didier; #789852]
* Misc. bug fixes and cleanups [Jonas, Florian, Sonny, Carlos, Mario, Benjamin,
Marco, Ting-Wei; !599, !600, !591, !606, !152, !607, !604, !495, !608, !611,
!614, !612, !615, !618, #369, !620, #774, !621, !616, #1065, !609, !626,
!491, !631, !632, !633, #1457]
Contributors:
Benjamin Berg, Jonas Dreßler, Frederik Feichtmeier, Carlos Garnacho,
Illya Klymov, Ting-Wei Lan, Florian Müllner, Sonny Piers, Mario Sanchez Prada,
Didier Roche, Jakub Steiner, Ray Strode, Jor Teron, Marco Trevisan (Treviño)
Translators:
Jordi Mas [ca], Jor Teron [mjw]
3.33.3
======
* Prepare for optional X11 [Carlos; !378]

View File

@ -1,46 +1,5 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<!--
net.hadess.SwitcherooControl:
@short_description: D-Bus proxy to access dual-GPU controls.
After checking the availability of two switchable GPUs in the machine,
check the value of net.hadess.SwitcherooControl.HasDualGpu to see
if running applications on the discrete GPU should be offered.
The object path will be "/net/hadess/SwitcherooControl".
-->
<interface name="net.hadess.SwitcherooControl">
<!--
HasDualGpu:
Whether two switchable GPUs are present on the system. This property
has been obsoleted in favour of the "NumGPUs" property.
-->
<property name="HasDualGpu" type="b" access="read"/>
<!--
NumGPUs:
The number of GPUs available on the system. Note that while having no
GPUs is unlikely, consumers of this API should probably not throw errors
if that were the case.
-->
<property name="NumGPUs" type="u" access="read"/>
<!--
GPUs:
An array of key-pair values representing each GPU. The key named "Name" (s)
will contain a user-facing name for the GPU, the "Environment" (as) key will
contain an array of even number of strings, each being an environment
variable to set to use the GPU, followed by its value, the "Default" (b) key
will tag the default (usually integrated) GPU.
-->
<property name="GPUs" type="aa{sv}" access="read"/>
</interface>
</node>

View File

@ -0,0 +1,15 @@
<node>
<interface name="org.freedesktop.impl.portal.Access">
<method name="AccessDialog">
<arg type="o" name="handle" direction="in"/>
<arg type="s" name="app_id" direction="in"/>
<arg type="s" name="parent_window" direction="in"/>
<arg type="s" name="title" direction="in"/>
<arg type="s" name="subtitle" direction="in"/>
<arg type="s" name="body" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="u" name="response" direction="out"/>
<arg type="a{sv}" name="results" direction="out"/>
</method>
</interface>
</node>

View File

@ -1,15 +0,0 @@
<node>
<!--
org.gnome.Shell.ClocksIntegration:
@short_description: Clocks integration interface
The interface used for exporting location settings to GNOME Shell's
world clocks integration.
-->
<interface name="org.gnome.Shell.ClocksIntegration">
<property name="Locations" type="av" access="read"/>
</interface>
</node>

View File

@ -173,30 +173,6 @@
<arg type="s" direction="in" name="uuid"/>
</method>
<!--
EnableExtension:
@uuid: The UUID of the extension
@success: Whether the operation was successful
Enable an extension.
-->
<method name="EnableExtension"> \
<arg type="s" direction="in" name="uuid"/> \
<arg type="b" direction="out" name="success"/> \
</method> \
<!--
DisableExtension:
@uuid: The UUID of the extension
@success: Whether the operation was successful
Disable an extension.
-->
<method name="DisableExtension"> \
<arg type="s" direction="in" name="uuid"/> \
<arg type="b" direction="out" name="success"/> \
</method> \
<!--
LaunchExtensionPrefs:
@uuid: The UUID of the extension
@ -213,15 +189,6 @@
-->
<method name="CheckForUpdates"/>
<signal name="ExtensionStateChanged">
<arg type="s" name="uuid"/>
<arg type="a{sv}" name="state"/>
</signal>
<!--
ExtensionStatusChanged:
Deprecated for ExtensionStateChanged
-->
<signal name="ExtensionStatusChanged">
<arg type="s" name="uuid"/>
<arg type="i" name="state"/>

View File

@ -1,16 +0,0 @@
<node>
<!--
org.gnome.Shell.WeatherIntegration:
@short_description: Weather integration interface
The interface used for exporting location settings to GNOME Shell's
weather integration.
-->
<interface name="org.gnome.Shell.WeatherIntegration">
<property name="AutomaticLocation" type="b" access="read"/>
<property name="Locations" type="av" access="read"/>
</interface>
</node>

View File

@ -9,6 +9,7 @@
<file preprocess="xml-stripblanks">org.freedesktop.DBus.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.GeoClue2.Agent.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.GeoClue2.Manager.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.impl.portal.Access.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.impl.portal.PermissionStore.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.impl.portal.Request.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.login1.Manager.xml</file>
@ -39,7 +40,6 @@
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.CalendarServer.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.ClocksIntegration.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file>
@ -48,7 +48,6 @@
<file preprocess="xml-stripblanks">org.gnome.Shell.Screencast.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Screenshot.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Wacom.PadOsd.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.WeatherIntegration.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.xml</file>
<file preprocess="xml-stripblanks">org.Gtk.MountOperationHandler.xml</file>
<file preprocess="xml-stripblanks">org.gtk.Notifications.xml</file>

View File

@ -1,15 +0,0 @@
[Unit]
Description=Disable GNOME Shell extensions after failure
# Note that this unit must not conflict with anything, and must
# be able to run in parallel with the gnome-session-shutdown.target.
DefaultDependencies=no
# We want to disable extensions only if gnome-shell has flagged the extensions
# to be a likely cause of trouble.
ConditionPathExists=%t/gnome-shell-disable-extensions
[Service]
Type=simple
# Disable extensions
ExecStart=gsettings set org.gnome.shell disable-user-extensions true
Restart=no

View File

@ -3,6 +3,10 @@ Type=Application
Name=Shell Extensions
Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=extensions
X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;
OnlyShowIn=GNOME;
NoDisplay=true

View File

@ -20,8 +20,6 @@
<file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>pad-osd.css</file>
<file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
<file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
<file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-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>

View File

@ -1,27 +0,0 @@
[Unit]
Description=GNOME Shell on Wayland
# On wayland, force a session shutdown
OnFailure=gnome-shell-disable-extensions.service gnome-session-shutdown.target
OnFailureJobMode=replace-irreversibly
CollectMode=inactive-or-failed
RefuseManualStart=on
RefuseManualStop=on
After=gnome-session-manager.target
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
# The units already conflict because they use the same BusName
#Conflicts=gnome-shell-x11.service
[Service]
Type=notify
ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# On wayland we cannot restart
Restart=no
# Kill any stubborn child processes after this long
TimeoutStopSec=5

View File

@ -1,10 +1,5 @@
[Unit]
Description=GNOME Shell on Wayland
DefaultDependencies=no
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
Requires=gnome-shell-wayland.service
After=gnome-shell-wayland.service
Description=GNOME Shell (wayland sync point)
After=gnome-shell.service
BindsTo=gnome-shell.service
Conflicts=gnome-shell-x11.target

View File

@ -1,33 +0,0 @@
[Unit]
Description=GNOME Shell on X11
# On X11, try to show the GNOME Session Failed screen
OnFailure=gnome-shell-disable-extensions.service gnome-session-failed.target
OnFailureJobMode=replace
CollectMode=inactive-or-failed
RefuseManualStart=on
RefuseManualStop=on
After=gnome-session-manager.target
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
# The units already conflict because they use the same BusName
#Conflicts=gnome-shell-wayland.service
# Limit startup frequency more than the default
StartLimitIntervalSec=15s
StartLimitBurst=3
[Service]
Type=notify
ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# On X11 we want to restart on-success (Alt+F2 + r) and on-failure.
Restart=always
# Do not wait before restarting the shell
RestartSec=0ms
# Kill any stubborn child processes after this long
TimeoutStopSec=5

View File

@ -1,10 +1,5 @@
[Unit]
Description=GNOME Shell on X11
DefaultDependencies=no
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
Requires=gnome-shell-x11.service
After=gnome-shell-x11.service
Description=GNOME Shell (x11 sync point)
After=gnome-shell.service
BindsTo=gnome-shell.service
Conflicts=gnome-shell-wayland.target

4
data/gnome-shell.portal Normal file
View File

@ -0,0 +1,4 @@
[portal]
DBusName=org.freedesktop.impl.portal.desktop.gnome
Interfaces=org.freedesktop.impl.portal.Access
UseIn=gnome

View File

@ -0,0 +1,11 @@
[Unit]
Description=GNOME Shell
Wants=gnome-session.service
After=graphical-session-pre.target gnome-session-bus.target
PartOf=graphical-session.target
[Service]
Type=dbus
ExecStart=@bindir@/gnome-shell
Restart=on-failure
BusName=org.gnome.Shell

View File

@ -13,8 +13,7 @@ desktopconf = configuration_data()
# We substitute in bindir so it works as an autostart
# file when built in a non-system prefix
desktopconf.set('bindir', bindir)
desktopconf.set('systemd_hidden', have_systemd ? 'true' : 'false')
desktopconf.set('VERSION', meson.project_version())
foreach desktop_file : desktop_files
i18n.merge_file('desktop',
input: configure_file(
@ -23,7 +22,7 @@ foreach desktop_file : desktop_files
configuration: desktopconf
),
output: desktop_file,
po_dir: po_dir,
po_dir: '../po',
install: true,
install_dir: desktopdir,
type: 'desktop'
@ -72,6 +71,7 @@ configure_file(
)
install_data('gnome-shell.portal', install_dir: portaldir)
install_data('50-gnome-shell-system.xml', install_dir: keysdir)
@ -98,23 +98,15 @@ if have_systemd
unitconf = configuration_data()
unitconf.set('bindir', bindir)
configure_file(
input: 'gnome-shell-x11.service.in',
output: 'gnome-shell-x11.service',
unit = configure_file(
input: 'gnome-shell.service.in',
output: 'gnome-shell.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
configure_file(
input: 'gnome-shell-wayland.service.in',
output: 'gnome-shell-wayland.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
units = files('gnome-shell-x11.target',
'gnome-shell-wayland.target',
'gnome-shell-disable-extensions.service')
units = files('gnome-shell-wayland.target',
'gnome-shell-x11.target')
install_data(units, install_dir: systemduserunitdir)
endif

View File

@ -3,6 +3,10 @@ Type=Application
Name=GNOME Shell
Comment=Window management and application launching
Exec=@bindir@/gnome-shell
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;Core;
OnlyShowIn=GNOME;
NoDisplay=true
@ -10,4 +14,3 @@ X-GNOME-Autostart-Phase=DisplayServer
X-GNOME-Provides=panel;windowmanager;
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=false
X-GNOME-HiddenUnderSystemd=@systemd_hidden@

View File

@ -21,17 +21,6 @@
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
</description>
</key>
<key name="disabled-extensions" type="as">
<default>[]</default>
<summary>UUIDs of extensions to force disabling</summary>
<description>
GNOME Shell extensions have a UUID property; this key lists extensions
which should be disabled, even if loaded as part of the current mode.
You can also manipulate this list with the EnableExtension and
DisableExtension D-Bus methods on org.gnome.Shell.
This key takes precedence over the “enabled-extensions” setting.
</description>
</key>
<key name="disable-user-extensions" type="b">
<default>false</default>
<summary>Disable user extensions</summary>
@ -50,7 +39,7 @@
</description>
</key>
<key name="favorite-apps" type="as">
<default>[ 'org.gnome.Epiphany.desktop', 'org.gnome.Geary.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<summary>List of desktop file IDs for favorite applications</summary>
<description>
The applications corresponding to these identifiers
@ -150,6 +139,11 @@
Keybinding to focus the active notification.
</description>
</key>
<key name="pause-resume-tweens" type="as">
<default>[]</default>
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
<description></description>
</key>
<key name="switch-to-application-1" type="as">
<default>["&lt;Super&gt;1"]</default>
<summary>Switch to application 1</summary>
@ -228,36 +222,6 @@
</key>
</schema>
<schema id="org.gnome.shell.world-clocks" path="/org/gnome/shell/world-clocks/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="locations" type="av">
<summary>Locations</summary>
<description>
The locations to show in world clocks
</description>
<default>[]</default>
</key>
</schema>
<schema id="org.gnome.shell.weather" path="/org/gnome/shell/weather/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="automatic-location" type="b">
<summary>Automatic location</summary>
<description>
Whether to fetch the current location or not
</description>
<default>false</default>
</key>
<key name="locations" type="av">
<summary>Location</summary>
<description>
The location for which to show a forecast
</description>
<default>[]</default>
</key>
</schema>
<!-- unused, change 00_org.gnome.shell.gschema.override instead -->
<schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/"
gettext-domain="@GETTEXT_PACKAGE@">

View File

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<path d="M13.98 1.99a1 1 0 0 0-.687.303l-.984.984A8 8 0 0 0 8 2 8 8 0 0 0 .262 8.01a8 8 0 0 0 2.943 4.37l-.912.913a1 1 0 1 0 1.414 1.414l11-11a1 1 0 0 0-.727-1.717zM8 4a4 4 0 0 1 2.611.974l-1.42 1.42A2 2 0 0 0 8 6a2 2 0 0 0-2 2 2 2 0 0 0 .396 1.19l-1.42 1.42A4 4 0 0 1 4 8a4 4 0 0 1 4-4zm7.03 2.209l-3.344 3.343a4 4 0 0 1-2.127 2.127l-2.28 2.28a8 8 0 0 0 .721.04 8 8 0 0 0 7.738-6.01 8 8 0 0 0-.709-1.78zm-7.53.79a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#2e3436"/>
</svg>

Before

Width:  |  Height:  |  Size: 572 B

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="16" viewBox="0 0 16 16" version="1.1" id="svg7384" height="16">
<metadata id="metadata90">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title id="title9167">Gnome Symbolic Icon Theme</title>
<defs id="defs7386">
<linearGradient osb:paint="solid" id="linearGradient7212">
<stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7214"/>
</linearGradient>
</defs>
<g transform="translate(-341.0002,-13.000323)" style="display:inline" id="layer9"/>
<g transform="translate(-100,-380.00032)" id="layer1"/>
<g transform="translate(-100,-380.00032)" style="display:inline" id="layer10">
<path d="m 108,382 a 8,8 0 0 0 -7.73828,6.00977 A 8,8 0 0 0 108,394 8,8 0 0 0 115.73828,387.99023 8,8 0 0 0 108,382 Z m 0,2 a 4,4 0 0 1 4,4 4,4 0 0 1 -4,4 4,4 0 0 1 -4,-4 4,4 0 0 1 4,-4 z" id="path2314" style="opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"/>
<path id="path2318" d="m 110,388.00003 a 2,2 0 0 1 -2,2 2,2 0 0 1 -2,-2 2,2 0 0 1 2,-2 2,2 0 0 1 2,2 z" style="vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
</g>
<g transform="translate(-100,-380.00032)" id="g6387"/>
<g transform="translate(-100,-380.00032)" id="layer11"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,17 +1,16 @@
$variant: 'dark';
$variant: 'light';
@import "gnome-shell-sass/_high-contrast-colors"; //use gtk colors
@import "gnome-shell-sass/_drawing";
@import "gnome-shell-sass/_common";
@import "gnome-shell-sass/_widgets";
//force symbolic icons
stage {
-st-icon-style: symbolic;
-st-icon-style: symbolic;
}
.toggle-switch { width: 48px; }
.toggle-switch-us, .toggle-switch-intl {
background-image: url("resource:///org/gnome/shell/theme/toggle-off-hc.svg");
&:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-hc.svg"); }
background-image: url("resource:///org/gnome/shell/theme/toggle-off-hc.svg");
&:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-hc.svg"); }
}

View File

@ -1,15 +1,16 @@
// When color definition differs for dark and light variant,
// it gets @if ed depending on $variant
$base_color: if($variant == 'light', #fff, lighten(desaturate(#241f31, 20%), 2%));
$base_color: if($variant == 'light', #ffffff, lighten(desaturate(#241f31, 20%), 2%));
$bg_color: if($variant == 'light', #f6f5f4, darken(desaturate(#3d3846, 100%), 4%));
$fg_color: if($variant == 'light', #2e3436, #eeeeec);
$selected_fg_color: #fff;
$selected_fg_color: #ffffff;
$selected_bg_color: if($variant == 'light', #3584e4, darken(#3584e4, 10%));
$selected_borders_color: if($variant== 'light', darken($selected_bg_color, 15%), darken($selected_bg_color, 30%));
$borders_color: if($variant == 'light', darken($bg_color, 18%), darken($bg_color, 8%));
$borders_edge: if($variant == 'light', rgba(255,255,255,0.8), transparentize($fg_color, 0.93));
$borders_color: if($variant == 'light', darken($bg_color, 18%), darken($bg_color, 10%));
$borders_edge: if($variant == 'light', transparentize(white, 0.2), transparentize($fg_color, 0.93));
$link_color: if($variant == 'light', darken($selected_bg_color, 10%), lighten($selected_bg_color, 20%));
$link_visited_color: if($variant == 'light', darken($selected_bg_color, 20%), lighten($selected_bg_color, 10%));
$top_hilight: $borders_edge;
@ -19,20 +20,21 @@ $error_color: #ff8080;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$osd_fg_color: $fg_color;
$osd_text_color: if($variant == 'light', #000, #fff);
$osd_bg_color: if($variant == 'light', rgba(255,255,255,0.9), transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04));
$osd_fg_color: #eeeeec;
$osd_text_color: white;
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04);
$osd_insensitive_bg_color: transparentize(mix($osd_fg_color, opacify($osd_bg_color, 1), 10%), 0.5);
$osd_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
$osd_borders_color: if($variant == 'light', rgba(255,255,255,0.1), rgba(0,0,0,0.7));
$osd_outer_borders_color: if($variant == 'light', rgba(0,0,0,0.1), lighten($osd_bg_color, 7%));
$osd_borders_color: transparentize(black, 0.3);
$osd_outer_borders_color: transparentize(white, 0.84);
$shadow_color: if($variant == 'light', rgba(0,0,0,0.1), rgba(0,0,0,0.2));
$tooltip_borders_color: $osd_outer_borders_color;
$shadow_color: transparentize(black, 0.9);
//insensitive state derived colors
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
$insensitive_bg_color: mix($bg_color, $base_color, 60%);
$insensitive_borders_color: mix($borders_color, $base_color, 60%);
$insensitive_borders_color: $borders_color;
//colors for the backdrop state, derived from the main colors.
$backdrop_base_color: if($variant =='light', darken($base_color,1%), lighten($base_color,1%));
@ -40,4 +42,4 @@ $backdrop_bg_color: $bg_color;
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
$backdrop_insensitive_color: if($variant =='light', darken($backdrop_bg_color,15%), lighten($backdrop_bg_color,15%));
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
// generic drawing of more complex things
@function draw_widget_edge($c:$borders_edge) {
@function _widget_edge($c:$borders_edge) {
// outer highlight "used" on most widgets
@return 0 1px $c;
}
@ -13,7 +13,7 @@
//font-size: ($size / $base) * 1rem;
}
@mixin draw_shadows($shadow1, $shadow2:none, $shadow3:none, $shadow4:none) {
@mixin _shadows($shadow1, $shadow2:none, $shadow3:none, $shadow4:none) {
//
// Helper function to stack up to 4 box-shadows;
//
@ -31,7 +31,8 @@
//
// $t: entry type
// $fc: focus color
// $edge: set to none to not draw the bottom edge or specify a color to not use the default one
// $edge: set to none to not draw the bottom edge or specify a color to not
// use the default one
//
// possible $t values:
// normal, focus, insensitive
@ -44,9 +45,8 @@
}
@if $t==focus {
border-color: if($fc==$selected_bg_color,
$selected_borders_color,
darken($fc,35%));
box-shadow: inset 0 0 0 1px $fc;
$selected_borders_color,
darken($fc,35%));
}
@if $t==hover { }
@if $t==insensitive {
@ -58,39 +58,36 @@
// buttons
@function draw_border_color ($c) {
//
// colored buttons want the border form the base color
//
@return if($variant == 'light', darken($c, 18%), darken($c, 4%));
}
@function _border_color ($c) { @return darken($c,25%); } // colored buttons want
// the border form the
// base color
@function draw_text_shadow_color ($tc:$fg_color, $bg:$bg_color) {
@function _text_shadow_color ($tc:$fg_color, $bg:$bg_color) {
//
// calculate the color of text shadows
//
// $tc is the text color
// $bg is the background color
//
$lbg: lightness($bg)/100%;
@if lightness($tc)<50% { @return rgba(255,255,255,$lbg/($lbg*1.3)); }
@else { @return rgba(0,0,0,1-$lbg*0.8); }
$_lbg: lightness($bg)/100%;
@if lightness($tc)<50% { @return transparentize(white,1-$_lbg/($_lbg*1.3)); }
@else { @return transparentize(black,$_lbg*0.8); }
}
@function draw_button_hilight_color($c) {
@function _button_hilight_color($c) {
//
// calculate the right top hilight color for buttons
//
// $c: base color;
//
@if lightness($c)>90% { @return white; }
@else if lightness($c)>80% { @return rgba(255,255,255, 0.7); }
@else if lightness($c)>50% { @return rgba(255,255,255, 0.5); }
@else if lightness($c)>40% { @return rgba(255,255,255, 0.3); }
@else { @return rgba(255,255,255, 0.1); }
@else if lightness($c)>80% { @return transparentize(white, 0.3); }
@else if lightness($c)>50% { @return transparentize(white, 0.5); }
@else if lightness($c)>40% { @return transparentize(white, 0.7); }
@else { @return transparentize(white, 0.9); }
}
@mixin draw_button_text_shadow ($tc:$fg_color, $bg:$bg_color) {
@mixin _button_text_shadow ($tc:$fg_color, $bg:$bg_color) {
//
// helper function for the text emboss effect
//
@ -99,19 +96,19 @@
// TODO: this functions needs a way to deal with special cases
//
$shadow: draw_text_shadow_color($tc, $bg);
$_shadow: _text_shadow_color($tc, $bg);
@if lightness($tc)<50% {
text-shadow: 0 1px $shadow;
icon-shadow: 0 1px $shadow;
text-shadow: 0 1px $_shadow;
icon-shadow: 0 1px $_shadow;
}
@else {
text-shadow: 0 -1px $shadow;
icon-shadow: 0 -1px $shadow;
text-shadow: 0 -1px $_shadow;
icon-shadow: 0 -1px $_shadow;
}
}
@mixin button($t, $c:$bg_color, $tc:$fg_color, $edge: $borders_edge, $shadow: $shadow_color) {
@mixin button($t, $c:$bg_color, $tc:$fg_color, $edge: $borders_edge) {
//
// Button drawing function
//
@ -120,8 +117,6 @@
// $tc: optional text color for colored* types
// $edge: set to none to not draw the bottom edge or specify a color to not
// use the default one
// $shadow: set to none to not draw the drop shadow or specify a color to not
// use the default one
//
// possible $t values:
// normal, hover, active, insensitive, insensitive-active,
@ -129,68 +124,79 @@
// osd, osd-hover, osd-active, osd-insensitive, osd-backdrop, undecorated
//
$hilight_color: draw_button_hilight_color($c);
$button_edge: if($edge == none, none, draw_widget_edge($edge));
$blank_edge: if($edge == none, none, draw_widget_edge(transparentize($edge,1)));
$button_shadow: if($shadow == none, none, 0 1px 1px 0 $shadow);
$_hilight_color: _button_hilight_color($c);
$_button_edge: if($edge == none, none, _widget_edge($edge));
$_blank_edge: if($edge == none, none, _widget_edge(transparentize($edge,1)));
$_button_shadow: 0 1px 2px transparentize($shadow_color, 0.03);
// normal button
@if $t==normal {
color: $tc;
background-color: lighten($c, 3%) !important;
border-color: draw_border_color($c);
@include draw_shadows($button_shadow);
// box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
}
//
// normal button
//
// focused button
@if $t==focus {
color: $tc;
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
box-shadow: inset 0 0 0 2px transparentize($selected_bg_color, 0.7);
background-color: $c;
border-color: $borders_color;
box-shadow: $_button_shadow;
text-shadow: 0 1px black;
icon-shadow: 0 1px black;
}
@if $t==focus {
//
// focused button
//
color: $tc;
text-shadow: 0 1px black;
icon-shadow: 0 1px black;
box-shadow: inset 0px 0px 0px 2px $selected_bg_color;
//border-color: $selected_bg_color;
}
// hover button
@else if $t==hover {
//
// active osd button
//
color: $tc;
background-color: lighten($c, if($variant == 'light', 8%, 5%)) !important;
border-color: if($variant == 'light', draw_border_color(lighten($c, 7%)), draw_border_color($c));
@include draw_shadows($button_shadow);
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
}
border-color: $borders_color;
background-color: $c;
box-shadow: $_button_shadow;
text-shadow: 0 1px black;
icon-shadow: 0 1px black;
// active button
}
@else if $t==active {
//
// active osd button
//
color: $tc;
background-color: darken($c,3%) !important;
border-color: draw_border_color(if($variant == 'light', $c, darken($c,7%)));
border-color: $borders_color;
background-color: $c;
text-shadow: none;
icon-shadow: none;
box-shadow: none;
}
// insensitive button
@else if $t==insensitive {
color: $insensitive_fg_color;
border-color: $insensitive_borders_color;
background-color: $insensitive_bg_color !important;
background-color: $insensitive_bg_color;
box-shadow: none;
text-shadow: none;
icon-shadow: none;
}
// reset
@else if $t==undecorated {
//
// reset
//
border-color: transparent;
background-color: transparent;
background-image: none;
@include draw_shadows(inset 0 1px rgba(255,255,255,0),$blank_edge);
@include _shadows(inset 0 1px transparentize(white,1),
$_blank_edge);
text-shadow: none;
icon-shadow: none;
}
}

View File

@ -22,10 +22,11 @@ $destructive_color: darken(#ef2929,10%);
$osd_fg_color: #eeeeec;
$osd_bg_color: #2e3436;
$osd_borders_color: rgba(0,0,0, 0.7);
$osd_outer_borders_color: rgba(255,255,255, 0.1);
$osd_borders_color: transparentize(black, 0.3);
$osd_outer_borders_color: transparentize(white, 0.9);
$shadow_color: rgba(0,0,0, 0.1);
$tooltip_borders_color: $osd_outer_borders_color;
$shadow_color: transparentize(black, 0.9);
//insensitive state derived colors
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);

View File

@ -1,39 +0,0 @@
//
// Shell widgets stylesheets are placed in separate .scss files
// in 'widgets' and imported into the main stylesheet in this file.
// To create or update a widget for the shell modify the list below.
//
/* WIDGETS */
@import 'widgets/app-grid';
@import 'widgets/app-switcher';
@import 'widgets/buttons';
@import 'widgets/calendar';
@import 'widgets/check-box';
@import 'widgets/corner-ripple';
@import 'widgets/dash';
@import 'widgets/dialogs';
@import 'widgets/end-session-dialog';
@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/panel';
@import 'widgets/popovers';
@import 'widgets/screen-shield';
@import 'widgets/scrollbars';
@import 'widgets/search-entry';
@import 'widgets/search-results';
@import 'widgets/slider';
@import 'widgets/switches';
@import 'widgets/tiled-previews';
@import 'widgets/window-picker';
@import 'widgets/workspace-switcher';

View File

@ -1,208 +0,0 @@
/* App Grid */
$app_icon_size: 96px;
$app_icon_padding: 24px;
// app icons
.icon-grid {
-shell-grid-horizontal-item-size: $app_icon_size + $app_icon_padding * 2;
-shell-grid-vertical-item-size: $app_icon_size + $app_icon_padding * 2;
spacing: $base_spacing * 6;
.overview-icon {
icon-size: $app_icon_size;
StIcon { margin-bottom: $base_margin; } // margin on icon so label isn't close
}
}
//.app-display { spacing: 20px; }
/* App Icons */
$app_grid_fg_color: #fff;
// Outline for low res icons
.lowres-icon {
icon-shadow: 0 1px 2px rgba(0,0,0,0.3);
}
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 2px rgba(0,0,0,0.4);
}
// Icon tiles in the app grid
.app-well-app,
.app-folder {
.overview-icon {
@extend %icon_tile;
color: $app_grid_fg_color !important;
}
&:selected {
.overview-icon {
background-color: transparentize($osd_bg_color,0.7);
color: $app_grid_fg_color;
}
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_fg_color,0.9);
color: $osd_fg_color;
}
}
&:focus {
.overview-icon {
background-color: transparentize($osd_fg_color,0.7 );
// border-color: $selected_bg_color;
color: $app_grid_fg_color;
}
}
&:drop {
.overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
}
&:active,
&:checked {
.overview-icon {
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
}
}
}
/* App Folders */
.app-folder {
.overview-icon {
@extend %icon_tile;
}
}
// expanded folder
.app-folder-popup {
-arrow-border-radius: 8px;
-arrow-background-color: transparentize(darken($osd_bg_color,10%), 0.5);
-arrow-base: 24px;
-arrow-rise: 11px;
}
.app-folder-popup-bin { padding: $base_padding - 1px; }
.app-folder-icon {
padding: $base_padding;
spacing-rows: $base_spacing;
spacing-columns: $base_spacing;
}
// Running app indicator (also shown in dash)
.app-well-app-running-dot {
height: 5px;
width: 5px;
border-radius:5px;
background-color: $osd_fg_color;
margin-bottom: 1px;
}
// Rename popup for app folders
.rename-folder-popup {
.rename-folder-popup-item {
spacing: $base_spacing;
&:ltr, &:rtl { padding: 0 $base_padding * 2; }
}
}
// right-click app menu
.app-menu,
.app-well-menu {
max-width: 27.25em;
}
// App Grid pagination indicators
.page-indicator {
padding: 15px 20px;
.page-indicator-icon {
width: 10px;
height: 10px;
border-radius: 10px; // the same as height&width
background-color: white;
}
}
// Some hacks I don't even know
.all-apps,
.frequent-apps > StBoxLayout {
// horizontal padding to make sure scrollbars or dash don't overlap content
padding: 0px 88px 10px 88px;
}
.app-well-app > .overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
spacing: $base_spacing;
}
// Label when no frequent apps
.no-frequent-applications-label { @extend %status_text; }
// shutdown and other actions in the grid
.system-action-icon {
background-color: rgba(0,0,0,0.8);
color: #fff;
border-radius: 99px;
icon-size: $app_icon_size * 0.5;
}
/* Frequent | All toggle */
// container
.app-view-controls {
padding-bottom: 32px;
}
// buttons
.app-view-control {
padding: $base_padding $base_padding*5;
margin: 0;
background-color: transparentize($osd_bg_color, 0.5);
border-width: 1px;
color: darken($osd_fg_color, 25%);
&:hover {
background-color: transparentize($osd_bg_color, 0.5) !important;
box-shadow:none !important;
color: darken($osd_fg_color, 25%);
}
&:active {
box-shadow: none;
background-color: $selected_bg_color !important;
&:hover {
background-color: lighten($selected_bg_color, 11%) !important;
}
}
&:checked {
background-color: $selected_bg_color !important;
color: $selected_fg_color;
box-shadow: none;
&:active { background-color: darken($selected_bg_color, 4%) !important; }
&:hover { background-color: lighten($selected_bg_color, 7%) !important; }
}
&:first-child {
border-right-width: 0 !important;
border-radius: $base_border_radius 0 0 $base_border_radius;
}
&:last-child {
border-radius: 0 $base_border_radius $base_border_radius 0;
}
}

View File

@ -1,55 +0,0 @@
/* App Switcher */
.switcher-popup {
padding: 8px;
spacing: $base_spacing * 4;
}
// switcher onscreen panel
.switcher-list {
@extend %osd_panel;
.item-box {
padding: 8px;
border-radius: $base_border_radius + 1px;
border: 1px solid transparent;
&:outlined {
border: 1px solid darken($borders_color,5%);
background-color: transparentize($osd_fg_color, 0.9);
box-shadow: inset 0 2px 2px 0 rgba(0,0,0,0.4);
}
&:selected {
background-color: transparentize($osd_fg_color, 0.9);
color: $osd_fg_color;
}
}
// window thumbnails
.thumbnail-box {
padding: 2px;
spacing: $base_spacing;
}
.thumbnail {
width: 256px;
}
.separator {
width: 1px;
background: $borders_color;
}
.switcher-list-item-container {
spacing: $base_spacing * 2;
}
}
.switcher-arrow {
border-color: rgba(0,0,0,0);
color: transparentize($fg_color,0.2);
&:highlighted {
color: $fg_color;
}
}

View File

@ -1,5 +0,0 @@
/* Buttons */
.button {
@extend %button; // that's it
}

View File

@ -1,266 +0,0 @@
/* Date/Time Menu */
// overall menu
#calendarArea {
padding:0;
margin:0;
}
// Calendar menu side column
.datemenu-calendar-column {
spacing: 0;
border: 0 solid $bubble_borders_color;
padding: $base_padding * 2;
padding-bottom: 3em; // account for the notifications clear button
padding-top:0;
&:ltr {margin-right: $base_margin * 2; border-left-width: 1px; }
&:rtl {margin-left: $base_margin * 2; border-right-width: 1px; }
// today button (the date)
.datemenu-today-button {
padding: $base_padding * 1.5;
margin: $base_margin;
border: 1px solid transparent;
border-radius: $base_border_radius + 2px;
&:hover { @include button(hover);}
&:focus { @include button(focus);}
&:active {
@include button(active);
}
// weekday label
.day-label {
@include fontsize($base_font_size+1);
font-weight: bold;
}
// date label
.date-label {
@include fontsize($base_font_size+7);
font-weight: 1000;
}
}
// calendar
.calendar {
@extend %notification_bubble;
margin:$base_margin !important;
margin-bottom: $base_padding + $base_margin !important;
padding:$base_padding !important;
// more below for sub-elements
}
.datemenu-displays-section {
margin:0;
}
.datemenu-displays-box {
spacing: $base_spacing;
margin:0;
// world clocks and weather
.world-clocks-button,
.weather-button {
@extend %notification_bubble;
padding:$base_padding !important;
}
}
}
.events-section-title {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
border-radius: 4px;
padding: .4em;
}
/* Calendar */
.calendar {
// month
.calendar-month-label {
color: lighten($fg_color,5%);
font-weight: bold;
padding: 8px 0;
&:focus {}
}
// prev/next month icons
.calendar-change-month-back StIcon,
.calendar-change-month-forward StIcon {
icon-size: $base_icon_size;
}
.pager-button {
background-color: transparent;
height: 32px;
width: 32px;
border-radius: $base_border_radius;
&:hover, &:focus { background-color: lighten($hover_bg_color, 5%); }
&:active { background-color: $active_bg_color; }
}
$calendar_day_size: 32px;
.calendar-day-base {
@include fontsize($base_font_size - 3);
text-align: center;
width: $calendar_day_size;
height: $calendar_day_size;
padding: 0;
margin: 2px;
border-radius: $calendar_day_size * 0.5 + 2px;
border: 1px solid transparent; //avoid jumparound due to today
font-feature-settings: "tnum";
&:hover, &:focus { background-color: $hover_bg_color; }
&:active,&:selected {
color: lighten($fg_color,10%);
background-color: darken($bg_color,5%);
}
// day of week heading
&.calendar-day-heading {
color: lighten($fg_color,10%);
margin-top: 1em;
@include fontsize($base_font_size - 4);
}
}
.calendar-day { //border collapse hack - see calendar.js
border-width: 0;
}
.calendar-day-top {
border-top-width: 1px;
}
.calendar-day-left { border-left-width: 1px; }
.calendar-work-day {}
.calendar-nonwork-day {
color: $insensitive_fg_color;
}
// Today
.calendar-today {
font-weight: bold;
border: 1px solid transparent;
background-color: $selected_bg_color;
color: $selected_fg_color;
&:hover,&:focus {
background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color;
}
&:active,&:selected {
background-color: $selected_bg_color;
color: $selected_fg_color;
&:hover,&:focus {
background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color;
}
}
}
.calendar-day-with-events {
color: lighten($fg_color,10%);
font-weight: bold;
background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg");
}
.calendar-other-month-day {
color: transparentize($fg_color ,0.5);
opacity: 0.5;
}
.calendar-week-number {
@include fontsize($base_font_size - 4);
font-weight: bold;
height: 1.8em;
width: 2.3em;
border-radius: 2px;
padding: 0.5em 0 0;
margin: 6px;
background-color: darken($bg_color, 2%);
color: lighten($fg_color, 5%);
}
}
/* Weather */
.weather-box {
spacing: $base_spacing;
padding:$base_padding;
.weather-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
&.location {
font-weight: normal;
@include fontsize($base_font_size - 1);
}
}
.weather-grid {
margin-top: $base_margin;
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
.weather-forecast-time {
color: darken($fg_color,30%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 2);
font-weight: normal;
padding-top: 0.2em;
padding-bottom: 0.4em;
}
.weather-forecast-icon {
icon-size: $base_icon_size * 2;
}
.weather-forecast-temp {
font-weight: bold;
}
}
/* World clocks */
.world-clocks-grid {
padding:$base_padding;
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
// title
.world-clocks-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
}
// city label
.world-clocks-city {
color: $fg_color;
@include fontsize($base_font_size);
font-weight: normal;
}
// timezone time
.world-clocks-time {
font-weight: bold;
color: $fg_color;
font-feature-settings: "lnum";
@include fontsize($base_font_size);
text-align: right;
}
// timezone offset label
.world-clocks-timezone {
color: darken($fg_color,20%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 1);
}
}

View File

@ -1,18 +0,0 @@
/* Check Boxes */
// these are equal to the size of the SVG assets
$check_height: 22px;
$check_width: 24px;
.check-box {
StBoxLayout { spacing: .8em; }
StBin {
width: $check_width;
height: $check_height;
background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg");
}
&:focus StBin { background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); }
&:checked StBin { background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); }
&:focus:checked StBin { background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); }
}

View File

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

View File

@ -1,86 +0,0 @@
/* Dash */
$dash_placeholder_size: 32px;
$dash_spacing: $base_padding + 4px;
$dash_border_radius: $modal_radius * 1.5;
#dash {
@extend %overview_panel;
@include fontsize($base_font_size - 2);
padding: ($dash_spacing / 2) 0;
//fixme: can't have non uniform borders :(
border-radius: 0 $dash_border_radius $dash_border_radius 0;
border-left-width: 0 !important;
&:rtl {
border-radius: $dash_border_radius 0 0 $dash_border_radius;
border-right-width: 0 !important;
}
.placeholder {
// background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
background-image:none;
background-size: contain;
height: $dash_placeholder_size;
}
.empty-dash-drop-target {
width: $dash_placeholder_size;
height: $dash_placeholder_size;
}
}
// Dash Items
.dash-item-container > StWidget {
padding: ($dash_spacing / 2) $dash_spacing;
}
// OSD Tooltip
.dash-label {
background-color: transparentize($osd_bg_color,0.05);
border-radius: $base_border_radius + 2px;
border:none;
box-shadow:0 0 0 1px $osd_outer_borders_color;
color: $osd_fg_color;
margin-top: $base_margin + 4px;
padding: $base_padding $base_padding + 2px;
text-align: center;
-x-offset: $base_margin * 2; // distance from the dash edge
}
// Show apps button
.show-apps {
color: $osd_fg_color;
& .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_fg_color,0.9);
color: $osd_fg_color;
}
}
&:drop .overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
&:active, &:checked {
.overview-icon {
background-color: darken($osd_bg_color,10%);
}
}
&:checked, &:focus {
.show-apps-icon {
color: $fg_color;
transition-duration: 100ms;
}
}
}

View File

@ -1,283 +0,0 @@
/* Modal Dialogs */
.modal-dialog {
border-radius: $modal_radius;
@extend %bubble_panel;
.modal-dialog-content-box {
margin: 32px 40px;
spacing: 32px;
max-width: 28em;
}
.modal-dialog-linked-button {
@extend %bubble_button;
}
}
.mount-dialog-subject {
@include fontsize($base_font_size + 3);
}
/* Message Dialog */
.message-dialog-content {
spacing: 18px;
.message-dialog-title {
text-align: center;
font-size: 18pt;
font-weight: 800;
}
.message-dialog-description { text-align: center; }
}
/* Dialog List */
.dialog-list {
spacing: 18px;
.dialog-list-title {
text-align: center;
font-weight: bold;
}
.dialog-list-scrollview { max-height: 200px; }
.dialog-list-box {
spacing: 1em;
.dialog-list-item {
spacing: 1em;
.dialog-list-item-title { font-weight: bold; }
.dialog-list-item-description {
color: darken($fg_color,5%);
@include fontsize($base_font_size - 1);
}
}
}
}
/* Run Dialog */
.run-dialog {
.run-dialog-entry { width: 20em; margin-bottom: 6px; }
.run-dialog-error-box {
padding-top: 16px;
spacing: 6px;
}
.run-dialog-label {
@include fontsize($base_font_size + 1.1);
font-weight: normal;
color: $fg_color;
padding-bottom: .4em;
}
}
/* ShellMountOperation Dialogs */
.shell-mount-operation-icon {
icon-size: $base_icon_size * 3;
}
.mount-dialog {
spacing: 24px;
.message-dialog-title {
padding-top: 10px;
padding-left: 17px;
padding-bottom: 6px;
max-width: 34em;
}
.message-dialog-title:rtl {
padding-left: 0px;
padding-right: 17px;
}
.message-dialog-description {
padding-left: 17px;
width: 28em;
}
.message-dialog-description:rtl {
padding-left: 0px;
padding-right: 17px;
}
}
.mount-dialog-app-list {
max-height: 200px;
padding-top: 24px;
padding-left: 49px;
padding-right: 32px;
}
.mount-dialog-app-list:rtl {
padding-right: 49px;
padding-left: 32px;
}
.mount-dialog-app-list-item {
color: lighten($fg_color,10%);
&:hover { color: $fg_color; }
&:ltr { padding-right: 1em; }
&:rtl { padding-left: 1em; }
}
.mount-dialog-app-list-item-icon {
&:ltr { padding-right: 17px; }
&:rtl { padding-left: 17px; }
}
.mount-dialog-app-list-item-name {
@include fontsize($base_font_size - 1);
}
/* Password or Authentication Dialog */
.prompt-dialog {
//this is the width of the entire modal popup
width: 34em;
.message-dialog-content { spacing: $base_spacing * 4; }
.message-dialog-title { color: lighten($fg_color,15%); }
}
.prompt-dialog-description:rtl {
text-align: right;
}
.prompt-dialog-password-box {
spacing: 1em;
padding-bottom: 1em;
}
.prompt-dialog-error-label {
@include fontsize($base_font_size - 1);
color: $warning_color;
padding-bottom: 8px;
}
.prompt-dialog-info-label {
@include fontsize($base_font_size - 1);
padding-bottom: 8px;
}
.prompt-dialog-null-label {
@include fontsize($base_font_size - 1);
padding-bottom: 8px;
}
.prompt-dialog-pim-box {
spacing: 1em;
}
.prompt-dialog-grid {
spacing-rows: 15px;
spacing-columns: 1em;
}
.prompt-dialog-keyfiles-box {
spacing: 1em;
}
.prompt-dialog-button.button {
padding: 8px;
}
.prompt-dialog-caps-lock-warning {
@extend .prompt-dialog-error-label;
padding-left: 6.2em;
}
/* Polkit Dialog */
.polkit-dialog-user-layout {
padding-left: 10px;
spacing: 10px;
&:rtl {
padding-left: 0px;
padding-right: 10px;
}
}
.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-device-selection-dialog {
spacing: 30px;
}
.audio-selection-content {
spacing: 20px;
padding: 24px;
}
.audio-selection-title {
font-weight: bold;
text-align: center;
}
.audio-selection-box {
spacing: 20px;
}
.audio-selection-device {
border: 1px solid $bubble_borders_color;
border-radius: 12px;
&:hover,&:focus { background-color: $hover_bg_color; }
&:active {
background-color: $selected_bg_color;
color: $selected_fg_color;
}
}
.audio-selection-device-box {
padding: 20px;
spacing: 20px;
}
.audio-selection-device-icon {
icon-size: $base_icon_size * 4;
}
/* Access Dialog */
.access-dialog {
spacing: 30px;
}
/* Geolocation Dialog */
.geolocation-dialog {
spacing: 30px;
}
/* Extension Dialog */
.extension-dialog {
.message-dialog-title { font-weight: normal; color: $fg_color; }
}
/* Inhibit-Shortcuts Dialog */
.inhibit-shortcuts-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,12 +0,0 @@
/* End Session Dialog */
$end_session_dialog_width: 28em;
.end-session-dialog-battery-warning {
width: $end_session_dialog_width;
color: $warning_color;
}
.end-session-dialog .dialog-list-title {
color: $warning_color;
}

View File

@ -1,23 +0,0 @@
/* Entries */
StEntry {
border-radius: $base_border_radius;
padding: 4px;
border-width: 1px;
color: $fg_color;
@include entry(normal);
//&:hover { @include entry(hover);}
&:focus { @include entry(focus);}
&:insensitive { @include entry(insensitive);}
selection-background-color: $selected_bg_color;
selected-color: $selected_fg_color;
StIcon.capslock-warning {
icon-size: 16px;
warning-color: $warning_color;
padding: 0 4px;
}
StIcon.peek-password {
icon-size: $base_icon_size;
padding: 0 4px;
}
}

View File

@ -1,10 +0,0 @@
// hotplug
.hotplug-notification-item {
@extend %bubble_button;
}
.hotplug-notification-item-icon {
icon-size: 24px;
padding: 0 4px;
}

View File

@ -1,30 +0,0 @@
// IBus Candidate Popup
.candidate-popup-content {
padding: 0.5em;
spacing: 0.3em;
}
.candidate-index {
padding: 0 0.5em 0 0;
color: darken($fg_color,10%);
}
.candidate-box {
padding: 0.3em 0.5em 0.3em 0.5em;
border-radius: $base_border_radius;
&:selected,&:hover { background-color: $selected_bg_color; color: $selected_fg_color; }
}
.candidate-page-button-box {
height: 2em;
.vertical & { padding-top: 0.5em; }
.horizontal & { padding-left: 0.5em; }
}
.candidate-page-button {
padding: 4px;
}
.candidate-page-button-previous { border-radius: $base_border_radius 0px 0px $base_border_radius; border-right-width: 0; }
.candidate-page-button-next { border-radius: 0px $base_border_radius $base_border_radius 0px; }
.candidate-page-button-icon { icon-size: 1em; }

View File

@ -1,124 +0,0 @@
/* On-screen Keyboard */
$key_size: 1.2em;
$key_border_radius: $base_border_radius + 3px;
$key_bg_color: $bg_color;
// $default_key_bg_color: darken($key_bg_color, 4%);
$default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten($osd_bg_color, 2%));
// draw keys using button function
#keyboard {
background-color: transparentize(if($variant=='light', darken($bg_color, 5%), darken($bg_color, 8%)), 0.1);
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color !important;
.page-indicator {
padding: $base_padding;
.page-indicator-icon {
width: 8px;
height: 8px;
}
}
}
// the container for individual keys
.key-container {
padding: $base_margin;
spacing: $base_margin;
}
// the keys
.keyboard-key {
@include button(normal, $c:$key_bg_color);
&:focus { @include button(focus);}
&:hover, &:checked { @include button(hover, $c: $key_bg_color);}
&:active { @include button(active, $c: $key_bg_color); }
@include fontsize($base_font_size + 5);
min-height: $key_size;
min-width: $key_size;
border-width: 1px;
border-style: solid;
border-radius: $key_border_radius;
&:grayed { //FIXMEy
background-color: darken($bg_color, 3%);
color: $osd_fg_color;
border-color: $osd_borders_color;
}
// non-character keys
&.default-key {
// size of the icon asset
background-size: 24px;
@include button(normal, $c:$default_key_bg_color);
&:hover, &:checked {@include button(hover, $c: $default_key_bg_color);}
&:active { @include button(active, $c: $default_key_bg_color);}
}
// enter key is suggested-action
&.enter-key {
background-image: url("resource:///org/gnome/shell/theme/key-enter.svg");
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
&:hover, &:checked { @include button(hover, $c: lighten($selected_bg_color, 3%));}
&:active {@include button(active, $c: darken($selected_bg_color, 2%));}
}
// key assets
&.shift-key-lowercase {background-image: url("resource:///org/gnome/shell/theme/key-shift.svg");}
&.shift-key-uppercase {background-image: url("resource:///org/gnome/shell/theme/key-shift-uppercase.svg");}
&.shift-key-uppercase:latched {background-image: url("resource:///org/gnome/shell/theme/key-shift-latched-uppercase.svg");}
&.hide-key {background-image: url("resource:///org/gnome/shell/theme/key-hide.svg");}
&.layout-key {background-image: url("resource:///org/gnome/shell/theme/key-layout.svg");}
}
// long press on a key popup
.keyboard-subkeys {
color: $osd_fg_color;
-arrow-border-radius: $modal_radius;
-arrow-background-color: $osd_bg_color;
-arrow-border-width: 1px;
-arrow-border-color: lighten($osd_bg_color, 9%);
-arrow-base: 20px;
-arrow-rise: 10px;
-boxpointer-gap: $base_spacing;
.keyboard-key {
@include button(normal, $c:$key_bg_color);
&:focus { @include button(focus);}
&:hover, &:checked { @include button(hover, $c: $key_bg_color);}
&:active { @include button(active, $c: $key_bg_color); }
border-radius:$base_border_radius;
}
}
// emoji
.emoji-page {
.keyboard-key {
background-color: transparent;
border: none;
color: initial;
}
}
.emoji-panel {
.keyboard-key:latched {
border-color: lighten($selected_bg_color, 5%);
background-color: $selected_bg_color;
}
}
// suggestions
.word-suggestions {
@include fontsize($base_font_size + 3);
spacing: 12px;
min-height: 20pt;
}

View File

@ -1,151 +0,0 @@
/* Login Dialog */
.login-dialog-banner-view {
padding-top: 24px;
max-width: 23em;
}
.login-dialog {
//reset
border: none;
background-color: transparent;
$_gdm_bg: lighten(#2e3436, 19%);
StEntry {
@if $variant=='dark' {
$_gdm_entry_bg: transparentize(lighten(desaturate(#241f31, 20%), 2%), 0.5);
background-color: $_gdm_entry_bg;
color: $osd_fg_color;
}
}
.modal-dialog-button-box { spacing: 3px; }
.modal-dialog-button {
padding: 4px 18px;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
background-color: $_gdm_bg;
border-color: $_gdm_bg;
color: $fg_color;
$_hover_c: lighten($_gdm_bg, 5%);
&:hover, &:focus {
background-color: $_hover_c;
border-color: $_hover_c;
}
&:active {
$_active_c: darken($_gdm_bg, 5%);
box-shadow: none;
background-color: $_active_c;
border-color: $_active_c;
}
&:insensitive {
@include button(insensitive);
border-color: darken($_gdm_bg, 5%);
background-color: darken($_gdm_bg, 5%);
color: transparentize($fg_color, 0.3);
}
&:default {
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
border-color: $selected_bg_color;
&:hover, &:focus {
@include button(hover,$c:$selected_bg_color, $tc:$selected_fg_color);
$_def_hover_c: lighten($selected_bg_color, 5%);
background-color: $_def_hover_c;
border-color: $_def_hover_c;
}
&:active {
@include button(active,$c:$selected_bg_color, $tc:$selected_fg_color);
$_def_active_c: darken($selected_bg_color, 5%);
background-color: $_def_active_c;
border-color: $_def_active_c;
}
&:insensitive {
@include button(insensitive);
border-color: darken($selected_bg_color, 10%);
background-color: darken($selected_bg_color, 10%);
color: transparentize($selected_fg_color, 0.3);
}
}
}
}
.login-dialog-logo-bin { padding: 24px 0px; }
.login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { spacing: 5px; }
.login-dialog-message-warning { color: $warning_color; }
.login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
.login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label {
padding-left: 2px;
.login-dialog-not-listed-button:focus &,
.login-dialog-not-listed-button:hover & {
color: $osd_fg_color;
}
}
.login-dialog-not-listed-label {
@include fontsize($base_font_size - 1);
font-weight: bold;
color: darken($osd_fg_color,30%);
padding-top: 1em;
}
.login-dialog-user-list-view { -st-vfade-offset: 1em; }
.login-dialog-user-list {
spacing: 12px;
width: 23em;
&:expanded .login-dialog-user-list-item:selected { background-color: $selected_bg_color; color: $selected_fg_color; }
&:expanded .login-dialog-user-list-item:logged-in { border-right: 2px solid $selected_bg_color; }
}
.login-dialog-user-list-item {
border-radius: 5px;
padding: 6px;
color: darken($osd_fg_color,30%);
&:ltr .user-widget { padding-right: 1em; }
&:rtl .user-widget { padding-left: 1em; }
.login-dialog-timed-login-indicator {
height: 2px;
margin-top: 6px;
background-color: $osd_fg_color;
}
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
}
.login-dialog-username,
.user-widget-label {
color: $osd_fg_color;
@include fontsize($base_font_size + 2);
font-weight: bold;
text-align: left;
padding-left: 15px;
}
.user-widget-label {
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.login-dialog-prompt-layout {
padding-top: 24px;
padding-bottom: 12px;
spacing: $base_spacing * 2;
width: 23em;
}
.login-dialog-prompt-label {
color: darken($osd_fg_color, 20%);
@include fontsize($base_font_size + 1);
padding-top: 1em;
}
.login-dialog-session-list-button StIcon {
icon-size: 1.25em;
}
.login-dialog-session-list-button {
color: darken($osd_fg_color,30%);
&:hover,&:focus { color: $osd_fg_color; }
&:active { color: darken($osd_fg_color, 50%); }
}

View File

@ -1,97 +0,0 @@
/* Looking Glass */
// Dialog
#LookingGlassDialog {
background-color: $osd_bg_color;
spacing: $base_spacing;
padding: 4px;
border: 2px solid transparentize($osd_fg_color, 0.8);
border-top-width:0;
border-radius: 0 0 $base_border_radius $base_border_radius;
& > #Toolbar {
border: none;
border-radius: $base_border_radius;
background-color: darken($osd_bg_color, 10%);
}
.labels { spacing: $base_spacing; }
.notebook-tab {
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: 6px;
font-weight: bold;
color: $fg_color;
transition-duration: 100ms;
padding-left: .3em;
padding-right: .3em;
&:hover {
color: white;
text-shadow: black 0px 2px 2px;
}
&:selected {
border-bottom-width: 2px;
border-color: lighten($selected_bg_color,5%);
color: white;
text-shadow: black 0px 2px 2px;
}
}
StBoxLayout#EvalBox { padding: 4px; spacing: $base_spacing; }
StBoxLayout#ResultsArea { spacing: $base_spacing; }
}
.lg-dialog {
StEntry {
selection-background-color: #bbbbbb;
selected-color: $osd_bg_color;
}
.shell-link {
color: #999999;
&:hover { color: #dddddd; }
}
}
.lg-completions-text {
font-size: .9em;
font-style: italic;
}
.lg-obj-inspector-title {
spacing: $base_spacing;
}
.lg-obj-inspector-button {
border: 1px solid gray;
padding: 4px;
border-radius: $base_border_radius;
&:hover { border: 1px solid #ffffff; }
}
// Extensions
#lookingGlassExtensions { padding: 4px; }
.lg-extensions-list {
padding: 4px;
spacing: 6px;
}
.lg-extension {
border: 1px solid $osd_borders_color;
border-radius: $base_border_radius;
padding: 4px;
}
.lg-extension-name {
font-weight: bold;
}
.lg-extension-meta {
spacing: 6px;
}
// Inspector
#LookingGlassPropertyInspector {
background: $osd_bg_color;
border: 1px solid $osd_borders_color;
border-radius: $base_border_radius;
padding: 6px;
}

View File

@ -1,146 +0,0 @@
/* Message List */
// a.k.a. notifications in the menu
// main list
.message-list {
width: 31.5em;
padding: 0 $base_padding * 2;
.message-list-placeholder { spacing: 12px; }
}
.message-list-sections {
spacing: $base_spacing;
margin: $base_margin * 4; // to account for scrollbar
}
.message-list-section,
.message-list-section-list {
spacing: $base_spacing;
}
.message-list-section-list {
&:ltr {padding:0;}
&:rtl {padding:0;}
}
// clear button
.message-list-clear-button.button {
margin:$base_margin $base_margin*2;
}
// message bubbles
.message {
@extend %notification_bubble;
// title
.message-title {
color: $fg_color;
font-weight: bold;
margin-bottom:4px;
}
// content
.message-content {
color: darken($fg_color, 10%);
padding: $base_padding 0;
margin:$base_margin * 2;
&:ltr {
margin-left: $base_margin;
padding-right:$base_padding;
}
&:rtl {
margin-right: $base_margin;
padding-left:$base_padding;
}
}
// close button
.message-close-button {
color: lighten($fg_color, 15%);
&:hover { color: if($variant=='light', lighten($fg_color, 30%), darken($fg_color, 10%)); }
&:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); }
}
// icon container
.message-icon-bin {
padding: $base_padding;
margin:$base_padding 0;
&:rtl {
// padding: $base_padding;
}
// icon size and color
> StIcon {
color: $fg_color;
icon-size: $base_icon_size*2; // 32px
-st-icon-style: symbolic;
padding:0;
margin:$base_padding;
}
// fallback
> .fallback-window-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 */
.message-media-control {
padding: $base_padding * 2 $base_padding * 4;
color: darken($fg_color, 15%);
// uses $hover_bg_color since the media controls are in a notification_bubble
&:hover {
background-color: lighten($hover_bg_color, 5%);
color: $fg_color;
}
&:active {
background-color: darken($hover_bg_color, 2%);
color: $fg_color;
}
&:insensitive { color: darken($fg_color,40%); }
// fix border-radius for last button on hover
&:last-child:ltr { &:hover {border-radius: 0 $base_border_radius+2 $base_border_radius+2 0;} }
&:last-child:rtl { &:hover {border-radius: $base_border_radius+2 0 0 $base_border_radius+2;} }
}
// album-art
.media-message-cover-icon {
icon-size: $base_icon_size*2 !important; // 48px
border-radius: $base_border_radius;
// when there is no artwork
&.fallback {
color: darken($fg_color, 17%);
background-color: $bg_color;
border: 1px solid transparent;
border-radius: $base_border_radius;
icon-size: $base_icon_size * 2 !important;
padding: $base_padding * 2;
}
}

View File

@ -1,59 +0,0 @@
// Links/URLs
.shell-link {
color: $link_color;
&:hover { color: lighten($link_color,10%); }
}
.url-highlighter { link-color: $link_color; }
// Rubberband for select-area screenshots
.select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color;
}
// Pointer accessibility notifications
.pie-timer {
width: 60px;
height: 60px;
-pie-border-width: 3px;
-pie-border-color: $selected_bg_color;
-pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
}
// Screen zoom/Magnifier
.magnifier-zoom-region {
border: 2px solid $selected_bg_color;
&.full-screen { border-width: 0; }
}
// User icon
.user-icon {
background-size: contain;
color: $osd_fg_color;
border-radius: 99px;
&:hover {
color: lighten($osd_fg_color,30%);
}
}
// 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;
}
// Text
.headline { @include fontsize($base_font_size + 1); }
.lightbox { background-color: black; }
.flashspot { background-color: white; }
// Hidden
.hidden { color: rgba(0,0,0,0);}

View File

@ -1,56 +0,0 @@
/* Network Dialogs */
.nm-dialog {
max-height: 34em;
min-height: 31em;
min-width: 32em;
}
.nm-dialog-content {
spacing: 20px;
padding: 24px;
}
.nm-dialog-airplane-box { spacing: 12px; }
.nm-dialog-airplane-headline {
font-weight: bold;
text-align: center;
}
.nm-dialog-airplane-text { color: $fg_color; }
// header
.nm-dialog-header {
font-weight: bold;
}
.nm-dialog-header-icon {
icon-size: $base_icon_size * 2;
}
.nm-dialog-header-hbox { spacing: 10px; }
// list of networks
.nm-dialog-scroll-view {
border: 1px solid $borders_color;
padding:0;
background-color: darken($bg_color, 3%);
}
// list item
.nm-dialog-item {
@include fontsize($base_font_size);
border-bottom: 1px solid $borders_color;
padding: $base_padding * 2;
spacing: 0px;
&:selected {
background-color: $selected_bg_color;
color: $selected_fg_color;
}
}
// icons in list
.nm-dialog-icon { icon-size: $base_icon_size; }
.nm-dialog-icons { spacing: $base_spacing * 2; }
// no networks
.no-networks-label { color: $insensitive_fg_color; }
.no-networks-box { spacing: $base_padding; }

View File

@ -1,90 +0,0 @@
/* Notifications & Mesage Tray */
$notification_banner_height: 64px;
$notification_banner_width: 34em;
// Banner notifications
.notification-banner {
min-height: $notification_banner_height;
width: $notification_banner_width;
@include fontsize($base_font_size);
margin: $base_margin;
border-radius: $modal_radius;
.message-title { color: $fg_color }
.message-content { color: $fg_color; }
&:hover { background: $bg_color; }
&, &:focus, &:active {
background-color: $bg_color;
.message-title { color: $fg_color }
.message-content { color: $fg_color; }
}
// icon
.message-icon-bin > StIcon {
icon-size: $base_icon_size * 2;
color: $fg_color;
}
.notification-icon {
padding: 5px;
}
.notification-content {
padding: 5px;
spacing: 5px;
}
.secondary-icon { icon-size: $base_icon_size; }
.notification-actions {
padding-top: 0;
spacing: 0;
}
.notification-button {
@extend %bubble_button;
}
}
// counter
.summary-source-counter {
font-size: $base_font_size - 1pt;
font-weight: bold;
height: 1.6em;
width: 1.6em;
-shell-counter-overlap-x: 3px;
-shell-counter-overlap-y: 3px;
background-color: $selected_bg_color;
color: $selected_fg_color;
border: 2px solid $fg_color;
box-shadow: 0 2px 2px rgba(0,0,0,0.5);
border-radius: 0.9em; // should be 0.8 but whatever; wish I could do 50%;
}
.secondary-icon { icon-size: $base_icon_size; }
// chat bubbles
.chat-body { spacing: 5px; }
.chat-response { margin: 5px; }
.chat-log-message { color: darken($fg_color,10%); }
.chat-new-group { padding-top: 1em; }
.chat-received {
padding-left: 4px;
&:rtl { padding-left: 0px; padding-right: 4px; }
}
.chat-sent {
padding-left: 18pt;
color: lighten($fg_color, 15%);
&:rtl { padding-left: 0; padding-right: 18pt; }
}
.chat-meta-message {
padding-left: 4px;
@include fontsize($base_font_size - 2);
font-weight: bold;
color: lighten($fg_color,18%);
&:rtl { padding-left: 0; padding-right: 4px; }
}

View File

@ -1,45 +0,0 @@
/* OSD */
$osd_levelbar_height:8px;
.osd-window {
@extend %osd_panel;
text-align: center;
font-weight: bold;
spacing: $base_spacing * 2; // 12px
margin: $base_margin * 8; // 32px
min-width: 64px;
min-height: 64px;
StIcon {
icon-size:$base_icon_size * 6;
}
.osd-monitor-label { font-size: 3em; }
.level {
height: $osd_levelbar_height;
-barlevel-height: $osd_levelbar_height;
-barlevel-background-color: transparentize($osd_fg_color, if($variant=='light', 0.7, 0.9));
-barlevel-active-background-color: $osd_fg_color;
-barlevel-overdrive-color: $destructive_color;
-barlevel-overdrive-separator-width: 3px;
}
}
/* Pad OSD */
.pad-osd-window {
padding: 32px;
background-color: transparentize(#000, 0.2);
.pad-osd-title-box { spacing: 12px; }
.pad-osd-title-menu-box { spacing: 6px; }
}
.combo-box-label {
width: 15em;
}
.resize-popup {
@extend %osd_panel;
}

View File

@ -1,10 +0,0 @@
/* OVERVIEW */
#overview {
spacing: 24px;
background-color: transparent;
}
.overview-controls {
padding-bottom: 32px;
}

View File

@ -1,106 +0,0 @@
/* Top Bar */
// a.k.a. the panel
$panel_corner_radius: $base_border_radius+1;
$panel_bg_color: if($variant == 'light', rgba(0,0,0,0.9), #000);
$panel_fg_color: if($variant == 'light', darken($fg_color, 15%), darken($fg_color, 10%));
$panel_height: 1.86em;
#panel {
background-color: $panel_bg_color;
font-weight: bold;
height: $panel_height;
font-feature-settings: "tnum";
// transparent panel on lock & login screens
&.unlock-screen,
&.login-screen,
&.lock-screen {
background-color: transparent;
.panel-corner {
-panel-corner-radius: 0;
-panel-corner-background-color: transparent;
-panel-corner-border-color: transparent;
}
}
// spacing between activities, app menu and such
#panelLeft, #panelCenter {
spacing: $base_spacing;
}
// the rounded outset corners
.panel-corner {
-panel-corner-radius: $panel_corner_radius;
-panel-corner-background-color: $panel_bg_color;
-panel-corner-border-width: 2px;
-panel-corner-border-color: transparent;
&:active, &:overview, &:focus {
-panel-corner-border-color: lighten($selected_bg_color,5%);
}
}
// panel menus
.panel-button {
font-weight: bold;
color: $panel_fg_color;
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: $base_padding;
&:hover {
color: lighten($panel_fg_color, 20%);
}
&: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%);
}
// status area icons
.system-status-icon {
icon-size: $base_icon_size;
padding: $base_padding - 1px;
}
// app menu icon
.app-menu-icon {
margin-left: $base_margin;
margin-right: $base_margin;
-st-icon-style: symbolic;
// dimensions of the icon are hardcoded
}
// lock & login screen styles
.unlock-screen &,
.login-screen &,
.lock-screen & {
color: lighten($fg_color, 10%);
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
}
}
.panel-status-indicators-box,
.panel-status-menu-box {
spacing: 2px;
}
// spacing between power icon and (optional) percentage label
.power-status.panel-status-indicators-box {
spacing: 0;
}
// indicator for active
.screencast-indicator,
.remote-access-indicator { color: $warning_color; }
}
// App Menu
#appMenu {
spacing: $base_spacing;
.label-shadow { color: transparent; }
}

View File

@ -1,121 +0,0 @@
/* Popovers/Menus */
$popover_arrow_height: 12px;
//.the popover itself
.popup-menu-boxpointer,
.candidate-popup-boxpointer {
-arrow-border-radius: $base_border_radius+4;
-arrow-background-color: $bg_color;
-arrow-border-width: 1px;
-arrow-border-color: $borders_color;
-arrow-base: $popover_arrow_height * 2;
-arrow-rise: $popover_arrow_height;
-arrow-box-shadow: 0 1px 3px rgba(0,0,0,0.5); // dreaming bugzilla #689995
}
// container of the popover menu
.popup-menu {
min-width: 15em;
color: $fg_color;
//.popup-status-menu-item { font-weight: normal; color: pink; } //dunno what that is
&.panel-menu {
-boxpointer-gap: $base_margin; // distance from the panel
margin-bottom: 1.75em;
}
}
.popup-menu-content {
padding: $base_padding * 2 + $base_margin 0;
}
// menu items
.popup-menu-item {
spacing: $base_padding;
padding: $base_padding;
&:ltr { padding-right:1.75em; padding-left: 0; }
&:rtl { padding-right: 0; padding-left:1.75em; }
&:checked {
background-color: lighten($bg_color, 2%);
box-shadow: none;
}
&.selected {
background-color: transparentize(white, if($variant=='light', 0.2, 0.9));
color: $fg_color;
}
&:active {
background-color: $selected_bg_color;
color: $selected_fg_color;
}
&:insensitive { color: transparentize($fg_color,0.5);}
}
// all icons and other graphical elements
.popup-inactive-menu-item {
color: $fg_color;
&:insensitive { color: transparentize($fg_color,0.5); }
}
// symbolic icons in popover
.popup-menu-arrow,
.popup-menu-icon { icon-size: $base_icon_size; }
// popover submenus
.popup-sub-menu {
background-color: darken($bg_color, 3%);
box-shadow: none;
border-top: 1px solid transparentize($borders_color, 0.2);
border-bottom: 1px solid transparentize($borders_color, 0.2);
}
// container for radio and check boxes
.popup-menu-ornament {
text-align: right;
width: 1.2em;
}
// separator
.popup-separator-menu-item {
//-margin-horizontal: 24px;
height: 1px; //not really the whole box
margin: 6px 64px;
background-color: lighten($borders_color, 2%);
border: none !important;
}
// desktop background menu
.background-menu {
-boxpointer-gap: $base_margin;
-arrow-rise: 0px; // hide the beak on the menu
}
// system status menu
.aggregate-menu {
min-width: 21em;
// lock screen, shutdown, etc. buttons
.popup-menu-icon {
padding:0;
margin: 0 $base_margin;
-st-icon-style: symbolic;
}
.popup-sub-menu .popup-menu-item > :first-child {
// account for icons in submenus with padding
&:ltr {
padding-left: $base_padding + $base_margin * 2;
margin-left: $base_icon_size;
}
&:rtl {
padding-right: $base_padding + $base_margin * 2; ;
margin-right: $base_icon_size;
}
}
}

View File

@ -1,83 +0,0 @@
/* Screen Shield */
$_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
.screen-shield-arrows {
padding-bottom: 3em;
}
.screen-shield-arrows Gjs_Arrow {
color: white;
width: 80px;
height: 48px;
-arrow-thickness: 12px;
-arrow-shadow: $_screenshield_shadow;
}
.screen-shield-clock {
color: white;
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";
}
.screen-shield-clock-date {
font-size: 28pt;
font-weight: normal;
}
.screen-shield-notifications-container {
spacing: 6px;
width: 30em;
background-color: transparent;
max-height: 500px;
.summary-notification-stack-scrollview {
padding-top: 0;
padding-bottom: 0;
}
.notification,
.screen-shield-notification-source {
padding: 12px 6px;
border: 1px solid $osd_outer_borders_color;
background-color: transparentize($osd_bg_color,0.5);
color: $osd_fg_color;
border-radius: 4px;
}
.notification { margin-right: 15px; } //compensate for space allocated to the scrollbar
}
.screen-shield-notification-label {
font-weight: bold;
padding: 0px 0px 0px 12px;
}
.screen-shield-notification-count-text { padding: 0px 0px 0px 12px; }
#panel.lock-screen { background-color: transparentize($osd_bg_color, 0.5); }
.screen-shield-background { //just the shadow, really
background: black;
box-shadow: 0px 2px 4px rgba(0,0,0,0.6);
}
#lockDialogGroup {
background: lighten(#2e3436, 8%) url(resource:///org/gnome/shell/theme/noise-texture.png);
background-repeat: repeat;
}
#screenShieldNotifications {
StButton#vhandle, StButton#hhandle {
background-color: transparentize($bg_color,0.7);
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
&:active { background-color: transparentize($selected_bg_color,0.5); }
}
}

View File

@ -1,29 +0,0 @@
/* Scrollbars */
StScrollView {
&.vfade { -st-vfade-offset: 68px; }
&.hfade { -st-hfade-offset: 68px; }
}
StScrollBar {
padding: 0;
StScrollView & {
min-width: 14px;
min-height: 14px;
}
StBin#trough {
border-radius: 0;
background-color: transparent;
}
StButton#vhandle, StButton#hhandle {
border-radius: 8px;
background-color: mix($fg_color, $bg_color, 60%);
//border: 3px solid transparent; //would be nice to margin or at least to transparent
margin: 3px;
&:hover { background-color: mix($fg_color, $bg_color, 80%); }
&:active { background-color: $selected_bg_color; }
}
}

View File

@ -1,35 +0,0 @@
// Search entry
$search_entry_width: 320px;
$search_entry_height: 36px;
%search_entry,
.search-entry {
width: $search_entry_width;
padding: $base_padding+1 $base_padding+3;
border-radius: $search_entry_height * 0.5; // half the height
color: transparentize($fg_color,0.3);
background-color: $bg_color;
border-color: $borders_color;
&:hover {
background-color: $hover_bg_color;
border-color: $hover_borders_color;
color: $hover_fg_color;
}
&:focus {
padding: $base_padding $base_padding+2; // 1px less to account for wider border
border-width: 2px;
border-style: solid;
border-color: $selected_bg_color;
color: $fg_color;
box-shadow: inset 0 1px 2px 1px rgba(0,0,0,0.2);
}
.search-entry-icon {
icon-size: $base_icon_size;
padding: 0 4px;
color: inherit;
}
}

View File

@ -1,151 +0,0 @@
/* Search */
// search overview container
#searchResultsContent {
max-width: 1024px;
}
// search results sections "the boxes"
.search-section {
spacing: $base_margin * 2;
padding:0 !important;
margin:0 !important;
background-color:transparent;
box-shadow:none;
border:none;
// separator
.search-section-separator {
// margin-top: $base_padding * 2;
// height: 1px;
// background-color: $osd_outer_borders_color;
height: 0;
background-color: transparent;
}
}
// content
.search-section-content {
background-color: transparentize(lighten($osd_bg_color, 5%), 0.2);
border-radius: $modal_radius+3;
border: 1px solid $osd_outer_borders_color;
box-shadow: 0 2px 4px 0 $shadow_color;
text-shadow: 0 1px if($variant == 'light', rgba(255,255,255,0.2), rgba(0,0,0,0.2));
color: $osd_fg_color;
padding: $base_padding * 3;
margin: $base_margin 0;
spacing: 0;
}
// "no results" text
.search-statustext {
@extend %status_text;
}
// Search results with icons
.grid-search-result {
> .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
> .overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
spacing: $base_spacing;
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_bg_color,0.8);
color: $osd_fg_color;
}
}
&:drop .overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
&:active .overview-icon,
&:checked .overview-icon {
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
}
}
// search result provider
.search-provider-icon {
@extend %icon_tile;
padding: $base_padding;
spacing: 0;
margin-right: $base_margin * 2;
&:focus,
&:selected,
&:hover {
background-color: transparentize($osd_fg_color,.9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color,10%),.1);
}
// content
.list-search-provider-content {
spacing: $base_spacing * 2;
// provider labels
.list-search-provider-details {
width: 120px;
margin-top: 0;
color: darken($osd_fg_color, 8%);
// font-weight: bold;
}
}
}
// search results list
.list-search-results {
spacing: $base_spacing;
}
// search result listitem
.list-search-result {
@extend %icon_tile;
spacing: 0;
padding: $base_padding;
color: $osd_fg_color;
border-radius: $base_border_radius + 2px !important;
&:focus,
&:selected,
&:hover {
background-color: transparentize($osd_fg_color,.9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color,10%),.1);
}
// content
.list-search-result-content {
spacing: 0;
}
// list item title
.list-search-result-title {
color: $osd_fg_color;
spacing: $base_spacing * 2;
padding-right: $base_padding;
// font-weight: bold;
}
// list item description
.list-search-result-description {
color: darken($osd_fg_color, 30%);
}
}

View File

@ -1,27 +0,0 @@
/* Slider */
$slider_size: 15px;
.slider {
height: $slider_size;
// slider trough
-barlevel-height: 3px; // has to be an odd number
-barlevel-background-color: $borders_color; //background of the trough
-barlevel-border-width: 1px;
-barlevel-border-color: $borders_color; // trough border color
// fill style
-barlevel-active-background-color: $selected_bg_color; //active trough fill
-barlevel-active-border-color: if($variant == 'light', darken($selected_bg_color, 4%), lighten($selected_bg_color, 2%)); //active trough border
// overfill style (red in this case)
-barlevel-overdrive-color: $destructive_color;
-barlevel-overdrive-border-color: if($variant == 'light', darken($destructive_color, 4%), lighten($destructive_color, 2%)); //trough border when red;
-barlevel-overdrive-separator-width:1px;
// slider hander
-slider-handle-radius: $slider_size * 0.5; // half the size of the size
-slider-handle-border-width: 1px;
-slider-handle-border-color: if($variant == 'light', $borders_color, $fg_color);
color: if($variant == 'light', lighten($bg_color, 10%), $fg_color);
&:hover { color: $hover_bg_color; }
&:active { color: $active_bg_color; }
}

View File

@ -1,16 +0,0 @@
/* Switches */
// these are equal to the size of the SVG assets
$switch_height: 22px;
$switch_width: 46px;
.toggle-switch {
color: $fg_color;
height: $switch_height;
width: $switch_width;
background-size: contain;
background-image: if($variant == 'light', url("resource:///org/gnome/shell/theme/toggle-off.svg"),url("resource:///org/gnome/shell/theme/toggle-off-dark.svg"));
&:checked {
background-image: if($variant == 'light', url("resource:///org/gnome/shell/theme/toggle-on.svg"),url("resource:///org/gnome/shell/theme/toggle-on-dark.svg"));
}
}

View File

@ -1,19 +0,0 @@
/* Tiled window previews */
$tile_corner_radius: $base_border_radius + 1px;
.tile-preview {
background-color: transparentize($selected_bg_color,0.5);
border: 1px solid $selected_bg_color;
}
.tile-preview-left.on-primary {
border-radius: $tile_corner_radius 0 0 0;
}
.tile-preview-right.on-primary {
border-radius: 0 $tile_corner_radius 0 0;
}
.tile-preview-left.tile-preview-right.on-primary {
border-radius: $tile_corner_radius $tile_corner_radius 0 0;
}

View File

@ -1,66 +0,0 @@
/* Window Picker */
$window_picker_spacing: $base_spacing * 8; // 48px
$window_picker_padding: $base_padding * 10; // 60px
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
$window_close_button_size: 24px;
$window_close_button_padding: 3px;
// Window picker
.window-picker {
// Space between window thumbnails
-horizontal-spacing: $window_picker_spacing;
-vertical-spacing: $window_picker_spacing;
// Padding for container around window thumbnails
padding: $window_picker_padding;
&.external-monitor { padding: $window_picker_padding; }
}
// Borders on window thumbnails
.window-clone-border {
border-width: 6px;
border-style: solid;
border-color: $window_thumbnail_border_color;
border-radius: $base_border_radius + 2;
// For window decorations with round corners we can't match
// the exact shape when the window is scaled. So apply a shadow
// to fix that case
box-shadow: inset 0 0 0 1px transparentize($borders_color, 0.8);
}
// Window titles
.window-caption {
color: $osd_fg_color;
background-color: $osd_bg_color;
border:1px solid $osd_outer_borders_color;
border-radius: $base_border_radius + 1;
padding: $base_padding $base_padding * 2;
font-weight: bold;
@include fontsize($base_font_size + 1);
}
// Close button
.window-close {
background-color: $selected_bg_color;
color: $selected_fg_color;
border: none;
border-radius: $window_close_button_size * 0.5 + $window_close_button_padding * 2;
padding: $window_close_button_padding;
height: $window_close_button_size;
width: $window_close_button_size;
box-shadow: -1px 1px 5px 0px rgba(0,0,0,0.5);
-shell-close-overlap: $window_close_button_size * 0.5;
&:hover {
background-color: lighten($selected_bg_color, 5%);
}
&:active {
background-color: darken($selected_bg_color, 5%);
}
}

View File

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

View File

@ -3,4 +3,3 @@ $variant: 'dark';
@import "gnome-shell-sass/_colors"; //use gtk colors
@import "gnome-shell-sass/_drawing";
@import "gnome-shell-sass/_common";
@import "gnome-shell-sass/_widgets";

View File

@ -1,4 +1,109 @@
<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"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
viewBox="0 0 32 32"
version="1.1"
id="svg7384"
height="32"
sodipodi:docname="key-enter.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1744"
inkscape:window-height="866"
id="namedview19"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="7.9322034"
inkscape:cy="14.554666"
inkscape:window-x="0"
inkscape:window-y="55"
inkscape:window-maximized="0"
inkscape:current-layer="svg7384" />
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient19282"
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
<stop
style="stop-color:#666666;stop-opacity:1;"
offset="0"
id="stop19284" />
</linearGradient>
</defs>
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer9" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer10" />
<g
transform="translate(-141.0002,-791)"
id="layer11" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer13" />
<g
transform="translate(-141.0002,-791)"
id="layer14" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer15" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g71291" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g4953" />
<g
transform="matrix(2,0,0,2,-281.56285,-1615.0002)"
style="display:inline"
id="layer12">
<path
id="path16589"
d="m 148.00015,821.0002 h -1 c -0.26528,0 -0.53057,-0.093 -0.71875,-0.2812 l -3.71875,-3.7188 c 0,0 2.47917,-2.4792 3.71875,-3.7187 0.18817,-0.1882 0.45344,-0.2813 0.71875,-0.2813 h 1 v 1 c 0,0.2653 -0.0931,0.5306 -0.28125,0.7188 l -2.28125,2.2812 2.28125,2.2813 c 0.18811,0.1881 0.28129,0.4534 0.28125,0.7187 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#bebebe;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m 154.0002,810 v 4.5 c 0,1.3807 -1.11929,2.5 -2.5,2.5 h -6.50005"
id="path16591"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 676 B

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,3 +1,114 @@
<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"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
viewBox="0 0 32 32"
version="1.1"
id="svg7384"
height="32"
sodipodi:docname="key-hide.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1919"
inkscape:window-height="1011"
id="namedview19"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="-12.338983"
inkscape:cy="14.554666"
inkscape:window-x="0"
inkscape:window-y="55"
inkscape:window-maximized="0"
inkscape:current-layer="svg7384" />
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient19282"
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
<stop
style="stop-color:#666666;stop-opacity:1;"
offset="0"
id="stop19284" />
</linearGradient>
</defs>
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer9" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer10" />
<g
transform="translate(-141.0002,-791)"
id="layer11" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer13" />
<g
transform="translate(-141.0002,-791)"
id="layer14" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer15" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g71291" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g4953" />
<g
style="display:inline"
inkscape:label="go-down"
id="g11722"
transform="matrix(2,0,0,2,-362.0004,-1494)">
<rect
transform="rotate(90)"
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none;enable-background:new"
id="rect11718"
y="-197.0002"
x="747"
height="16"
width="16" />
<path
style="display:inline;fill:#e5e5e5;fill-opacity:1;stroke:none"
d="m 189.0002,759.4375 -5.71875,-5.7187 C 183.08558,753.5229 183.0002,753.2556 183.0002,753 v -1 h 1 c 0.25562,0 0.52288,0.085 0.71875,0.2813 l 4.28125,4.2812 4.28125,-4.2812 C 193.47732,752.0854 193.74458,752 194.0002,752 h 1 v 1 c 0,0.2556 -0.0854,0.5229 -0.28125,0.7188 z"
id="path11720"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscsccsscscc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1,5 +1,129 @@
<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"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
viewBox="0 0 32 32"
version="1.1"
id="svg7384"
height="32"
sodipodi:docname="key-layout.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3440"
inkscape:window-height="1376"
id="namedview19"
showgrid="false"
inkscape:zoom="1"
inkscape:cx="46.246852"
inkscape:cy="17.474578"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg7384">
<inkscape:grid
type="xygrid"
id="grid861" />
</sodipodi:namedview>
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient19282"
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
<stop
style="stop-color:#666666;stop-opacity:1;"
offset="0"
id="stop19284" />
</linearGradient>
</defs>
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer9" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer10" />
<g
transform="translate(-141.0002,-791)"
id="layer11" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer13" />
<g
transform="translate(-141.0002,-791)"
id="layer14" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer15" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g71291" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g4953" />
<g
style="stroke-width:0.5;enable-background:new"
id="g3561"
inkscape:label="preferences-desktop-locale"
transform="matrix(2,0,0,2,135.99464,-895.9793)">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3535"
d="m -65,450 v 12"
style="fill:#e5e5e5;fill-opacity:1;fill-rule:evenodd;stroke:#e5e5e5;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path3537"
d="m -65,456 h 4 l 1,2 h 5 v -6 h -4 l -1,-2 h -5 z"
style="fill:none;fill-rule:evenodd;stroke:#e5e5e5;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="opacity:1;vector-effect:none;fill:#e5e5e5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m -65,456 h 4 l 1,2 h 5 v -6 h -4 l -1,-2 h -5 z"
id="path3539"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:0.89050001;marker:none;enable-background:new"
id="rect3543"
y="448"
x="-68"
height="16"
width="16" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,3 +1,109 @@
<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"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
viewBox="0 0 32 32"
version="1.1"
id="svg7384"
height="32"
sodipodi:docname="key-shift-latched-uppercase.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1791"
inkscape:window-height="984"
id="namedview19"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="-0.77966097"
inkscape:cy="18.847458"
inkscape:window-x="0"
inkscape:window-y="55"
inkscape:window-maximized="0"
inkscape:current-layer="svg7384" />
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient19282"
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
<stop
style="stop-color:#666666;stop-opacity:1;"
offset="0"
id="stop19284" />
</linearGradient>
</defs>
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer9" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer10" />
<g
transform="translate(-141.0002,-791)"
id="layer11" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer13" />
<g
transform="translate(-141.0002,-791)"
id="layer14" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer15" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g71291" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g4953" />
<g
transform="matrix(2,0,0,2,-282.0004,-1614.2187)"
style="display:inline;fill:#006098;fill-opacity:1"
id="layer12">
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#006098;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
d="m 147,818 v -4 h -3.1248 l 5.125,-5.7813 5.125,5.7813 h -3.1875 v 4 z"
id="path16532"
inkscape:connector-curvature="0" />
<path
id="path16534"
d="m 147,822 v -2 h 3.9377 v 2 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#006098;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 211 B

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,3 +1,104 @@
<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"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
viewBox="0 0 32 32"
version="1.1"
id="svg7384"
height="32"
sodipodi:docname="key-shift-uppercase.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2160"
inkscape:window-height="1311"
id="namedview18"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="-27.898305"
inkscape:cy="8"
inkscape:window-x="0"
inkscape:window-y="55"
inkscape:window-maximized="1"
inkscape:current-layer="svg7384" />
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient19282"
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
<stop
style="stop-color:#666666;stop-opacity:1;"
offset="0"
id="stop19284" />
</linearGradient>
</defs>
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer9" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer10" />
<g
transform="translate(-141.0002,-791)"
id="layer11" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer13" />
<g
transform="translate(-141.0002,-791)"
id="layer14" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="layer15" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g71291" />
<g
transform="translate(-141.0002,-791)"
style="display:inline"
id="g4953" />
<g
transform="matrix(2,0,0,2,-282.0008,-1614.2187)"
style="display:inline;fill:#006098;fill-opacity:1"
id="layer12">
<path
id="path16548"
d="m 147.0002,820 v -4 h -3.1248 l 5.125,-5.7813 5.125,5.7813 h -3.1875 v 4 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#006098;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -1,3 +1,108 @@
<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"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
viewBox="0 0 32 32"
version="1.1"
id="svg7384"
height="32"
sodipodi:docname="key-shift.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1400"
inkscape:window-height="1034"
id="namedview4569"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="14.75"
inkscape:cx="1.5993763"
inkscape:cy="5"
inkscape:window-x="0"
inkscape:window-y="55"
inkscape:window-maximized="0"
inkscape:current-layer="svg7384" />
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient19282"
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
<stop
style="stop-color:#666666;stop-opacity:1;"
offset="0"
id="stop19284" />
</linearGradient>
</defs>
<g
transform="translate(-143.8754,-788)"
style="display:inline"
id="layer9" />
<g
transform="translate(-143.8754,-788)"
style="display:inline"
id="layer10" />
<g
transform="translate(-143.8754,-788)"
id="layer11" />
<g
transform="translate(-143.8754,-788)"
style="display:inline"
id="layer13" />
<g
transform="translate(-143.8754,-788)"
id="layer14" />
<g
transform="translate(-143.8754,-788)"
style="display:inline"
id="layer15" />
<g
transform="translate(-143.8754,-788)"
style="display:inline"
id="g71291" />
<g
transform="translate(-143.8754,-788)"
style="display:inline"
id="g4953" />
<g
transform="matrix(2,0,0,2,-282.0008,-1614.2187)"
style="display:inline"
id="layer12">
<path
id="path16548"
d="m 147.0002,820 v -4 h -3.1248 l 5.125,-5.7813 5.125,5.7813 h -3.1875 v 4 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -4,40 +4,7 @@ theme_sources = files([
'gnome-shell-sass/_colors.scss',
'gnome-shell-sass/_common.scss',
'gnome-shell-sass/_drawing.scss',
'gnome-shell-sass/_high-contrast-colors.scss',
'gnome-shell-sass/_widgets.scss',
'gnome-shell-sass/widgets/_app-grid.scss',
'gnome-shell-sass/widgets/_app-switcher.scss',
'gnome-shell-sass/widgets/_buttons.scss',
'gnome-shell-sass/widgets/_calendar.scss',
'gnome-shell-sass/widgets/_check-box.scss',
'gnome-shell-sass/widgets/_corner-ripple.scss',
'gnome-shell-sass/widgets/_dash.scss',
'gnome-shell-sass/widgets/_dialogs.scss',
'gnome-shell-sass/widgets/_end-session-dialog.scss',
'gnome-shell-sass/widgets/_entries.scss',
'gnome-shell-sass/widgets/_hotplug.scss',
'gnome-shell-sass/widgets/_ibus-popup.scss',
'gnome-shell-sass/widgets/_keyboard.scss',
'gnome-shell-sass/widgets/_login-dialog.scss',
'gnome-shell-sass/widgets/_looking-glass.scss',
'gnome-shell-sass/widgets/_message-list.scss',
'gnome-shell-sass/widgets/_misc.scss',
'gnome-shell-sass/widgets/_network-dialog.scss',
'gnome-shell-sass/widgets/_notifications.scss',
'gnome-shell-sass/widgets/_osd.scss',
'gnome-shell-sass/widgets/_overview.scss',
'gnome-shell-sass/widgets/_panel.scss',
'gnome-shell-sass/widgets/_popovers.scss',
'gnome-shell-sass/widgets/_screen-shield.scss',
'gnome-shell-sass/widgets/_scrollbars.scss',
'gnome-shell-sass/widgets/_search-entry.scss',
'gnome-shell-sass/widgets/_search-results.scss',
'gnome-shell-sass/widgets/_slider.scss',
'gnome-shell-sass/widgets/_switches.scss',
'gnome-shell-sass/widgets/_tiled-previews.scss',
'gnome-shell-sass/widgets/_window-picker.scss',
'gnome-shell-sass/widgets/_workspace-switcher.scss'
'gnome-shell-sass/_high-contrast-colors.scss'
])
styles = [
@ -56,4 +23,3 @@ foreach style: styles
],
depend_files: theme_sources)
endforeach

View File

@ -28,7 +28,7 @@ foreach iface : ifaces
output: 'doc-gen-' + iface[1],
command: [
'gdbus-codegen',
'--interface-prefix=@0@.'.format(iface[0]),
'--interface-prefix=@0@.'.format(iface),
'--generate-docbook', 'doc-gen',
'--output-directory', '@OUTDIR@',
'@INPUT@'

View File

@ -31,34 +31,34 @@ its dependencies to build from tarballs.</description>
<programming-language>JavaScript</programming-language>
<programming-language>C</programming-language>
<author>
<maintainer>
<foaf:Person>
<foaf:name>William Jon McCann</foaf:name>
<foaf:mbox rdf:resource="mailto:jmccann@redhat.com" />
<gnome:userid>mccann</gnome:userid>
</foaf:Person>
</author>
<author>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Owen Taylor</foaf:name>
<foaf:mbox rdf:resource="mailto:otaylor@redhat.com" />
<gnome:userid>otaylor</gnome:userid>
</foaf:Person>
</author>
<author>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Colin Walters</foaf:name>
<foaf:mbox rdf:resource="mailto:walters@verbum.org" />
<gnome:userid>walters</gnome:userid>
</foaf:Person>
</author>
<author>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Marina Zhurakhinskaya</foaf:name>
<foaf:mbox rdf:resource="mailto:marinaz@redhat.com" />
<gnome:userid>marinaz</gnome:userid>
</foaf:Person>
</author>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Florian Müllner</foaf:name>
@ -66,11 +66,4 @@ its dependencies to build from tarballs.</description>
<gnome:userid>fmuellner</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Georges Basile Stavracas Neto</foaf:name>
<foaf:mbox rdf:resource="mailto:gbsneto@gnome.org" />
<gnome:userid>gbsneto</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@ -1,18 +1,13 @@
/* exported main */
imports.gi.versions.Gdk = '3.0';
imports.gi.versions.Gtk = '3.0';
const Gettext = imports.gettext;
const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
const Format = imports.format;
const _ = Gettext.gettext;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils;
const { ExtensionState } = ExtensionUtils;
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions');
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
@ -22,53 +17,74 @@ function stripPrefix(string, prefix) {
return string;
}
var Application = GObject.registerClass(
class Application extends Gtk.Application {
_init() {
var Application = class {
constructor() {
GLib.set_prgname('gnome-shell-extension-prefs');
super._init({
this.application = new Gtk.Application({
application_id: 'org.gnome.shell.ExtensionPrefs',
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE
});
this.application.connect('activate', this._onActivate.bind(this));
this.application.connect('command-line', this._onCommandLine.bind(this));
this.application.connect('startup', this._onStartup.bind(this));
this._extensionPrefsModules = {};
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
this._shellProxy = null;
}
get shellProxy() {
return this._shellProxy;
}
_extensionAvailable(uuid) {
let extension = ExtensionUtils.extensions[uuid];
_showPrefs(uuid) {
let row = this._extensionSelector.get_children().find(c => {
return c.uuid === uuid && c.hasPrefs;
});
if (!row)
if (!extension)
return false;
if (!extension.dir.get_child('prefs.js').query_exists(null))
return false;
return true;
}
_getExtensionPrefsModule(extension) {
let uuid = extension.metadata.uuid;
if (this._extensionPrefsModules.hasOwnProperty(uuid))
return this._extensionPrefsModules[uuid];
ExtensionUtils.installImporter(extension);
let prefsModule = extension.imports.prefs;
prefsModule.init(extension.metadata);
this._extensionPrefsModules[uuid] = prefsModule;
return prefsModule;
}
_selectExtension(uuid) {
if (!this._extensionAvailable(uuid))
return;
let extension = ExtensionUtils.extensions[uuid];
let widget;
try {
widget = row.prefsModule.buildPrefsWidget();
let prefsModule = this._getExtensionPrefsModule(extension);
widget = prefsModule.buildPrefsWidget();
} catch (e) {
widget = this._buildErrorUI(row, e);
widget = this._buildErrorUI(extension, e);
}
let dialog = new Gtk.Window({
modal: !this._skipMainWindow,
type_hint: Gdk.WindowTypeHint.DIALOG,
});
dialog.set_titlebar(new Gtk.HeaderBar({
show_close_button: true,
title: row.name,
visible: true,
}));
let dialog = new Gtk.Window({ modal: !this._skipMainWindow,
type_hint: Gdk.WindowTypeHint.DIALOG });
dialog.set_titlebar(new Gtk.HeaderBar({ show_close_button: true,
title: extension.metadata.name,
visible: true }));
if (this._skipMainWindow) {
this.add_window(dialog);
this.application.add_window(dialog);
if (this._window)
this._window.destroy();
this._window = dialog;
@ -80,27 +96,25 @@ class Application extends Gtk.Application {
dialog.set_default_size(600, 400);
dialog.add(widget);
dialog.show();
return true;
}
_buildErrorUI(row, exc) {
_buildErrorUI(extension, exc) {
let scroll = new Gtk.ScrolledWindow({
hscrollbar_policy: Gtk.PolicyType.NEVER,
propagate_natural_height: true,
propagate_natural_height: true
});
let box = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
spacing: 12,
margin: 100,
margin_bottom: 60,
margin_bottom: 60
});
scroll.add(box);
let label = new Gtk.Label({
label: '<span size="x-large">%s</span>'.format(_("Somethings gone wrong")),
use_markup: true,
use_markup: true
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
box.add(label);
@ -108,13 +122,13 @@ class Application extends Gtk.Application {
label = new Gtk.Label({
label: _("Were very sorry, but theres been a problem: the settings for this extension cant be displayed. We recommend that you report the issue to the extension authors."),
justify: Gtk.Justification.CENTER,
wrap: true,
wrap: true
});
box.add(label);
let expander = new Expander({
label: _("Technical Details"),
margin_top: 12,
margin_top: 12
});
box.add(expander);
@ -125,14 +139,14 @@ class Application extends Gtk.Application {
let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({
buffer,
buffer: buffer,
wrap_mode: Gtk.WrapMode.WORD,
monospace: true,
editable: false,
top_margin: 12,
bottom_margin: 12,
left_margin: 12,
right_margin: 12,
right_margin: 12
});
let toolbar = new Gtk.Toolbar();
@ -148,7 +162,7 @@ class Application extends Gtk.Application {
let copyButton = new Gtk.ToolButton({
icon_name: 'edit-copy-symbolic',
tooltip_text: _("Copy Error"),
tooltip_text: _("Copy Error")
});
toolbar.add(copyButton);
@ -156,16 +170,16 @@ class Application extends Gtk.Application {
let clipboard = Gtk.Clipboard.get_default(w.get_display());
// markdown for pasting in gitlab issues
let lines = [
`The settings of extension ${row.uuid} had an error:`,
'```', // '`' (xgettext throws up on odd number of backticks)
`The settings of extension ${extension.uuid} had an error:`,
'```',
`${exc}`,
'```', // '`'
'```',
'',
'Stack trace:',
'```', // '`'
'```',
exc.stack.replace(/\n$/, ''), // stack without trailing newline
'```', // '`'
'',
'```',
''
];
clipboard.set_text(lines.join('\n'), -1);
});
@ -178,17 +192,17 @@ class Application extends Gtk.Application {
label: _("Homepage"),
tooltip_text: _("Visit extension homepage"),
no_show_all: true,
visible: row.url != null,
visible: extension.metadata.url != null
});
toolbar.add(urlButton);
urlButton.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
Gio.AppInfo.launch_default_for_uri(row.url, context);
Gio.AppInfo.launch_default_for_uri(extension.metadata.url, context);
});
let expandedBox = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
orientation: Gtk.Orientation.VERTICAL
});
expandedBox.add(textview);
expandedBox.add(toolbar);
@ -199,8 +213,8 @@ class Application extends Gtk.Application {
return scroll;
}
_buildUI() {
this._window = new Gtk.ApplicationWindow({ application: this,
_buildUI(app) {
this._window = new Gtk.ApplicationWindow({ application: app,
window_position: Gtk.WindowPosition.CENTER });
this._window.set_default_size(800, 500);
@ -218,7 +232,7 @@ class Application extends Gtk.Application {
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._mainStack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE,
transition_type: Gtk.StackTransitionType.CROSSFADE
});
this._window.add(this._mainStack);
@ -234,14 +248,18 @@ class Application extends Gtk.Application {
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._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => {
if (ExtensionUtils.extensions[uuid] !== undefined)
this._scanExtensions();
});
this._window.show_all();
}
_sortList(row1, row2) {
return row1.name.localeCompare(row2.name);
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
return name1.localeCompare(name2);
}
_updateHeader(row, before) {
@ -252,48 +270,19 @@ class Application extends Gtk.Application {
row.set_header(sep);
}
_findExtensionRow(uuid) {
return this._extensionSelector.get_children().find(c => c.uuid === uuid);
}
_onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
let extension = ExtensionUtils.deserializeExtension(newState);
let row = this._findExtensionRow(uuid);
if (row) {
if (extension.state === ExtensionState.UNINSTALLED)
row.destroy();
return; // we only deal with new and deleted extensions here
}
this._addExtensionRow(extension);
}
_scanExtensions() {
this._shellProxy.ListExtensionsRemote(([extensionsMap], e) => {
if (e) {
if (e instanceof Gio.DBusError) {
log(`Failed to connect to shell proxy: ${e}`);
this._mainStack.add_named(new NoShellPlaceholder(), 'noshell');
this._mainStack.visible_child_name = 'noshell';
} else {
throw e;
}
return;
}
for (let uuid in extensionsMap) {
let extension = ExtensionUtils.deserializeExtension(extensionsMap[uuid]);
this._addExtensionRow(extension);
}
this._extensionsLoaded();
});
let finder = new ExtensionUtils.ExtensionFinder();
finder.connect('extension-found', this._extensionFound.bind(this));
finder.scanExtensions();
this._extensionsLoaded();
}
_addExtensionRow(extension) {
let row = new ExtensionRow(extension);
_extensionFound(finder, extension) {
let row = new ExtensionRow(extension.uuid);
row.prefsButton.visible = this._extensionAvailable(row.uuid);
row.prefsButton.connect('clicked', () => {
this._showPrefs(row.uuid);
this._selectExtension(row.uuid);
});
row.show_all();
@ -306,26 +295,24 @@ class Application extends Gtk.Application {
else
this._mainStack.visible_child_name = 'placeholder';
if (this._startupUuid)
this._showPrefs(this._startupUuid);
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
this._selectExtension(this._startupUuid);
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
}
vfunc_activate() {
_onActivate() {
this._window.present();
}
vfunc_startup() {
super.vfunc_startup();
this._buildUI();
_onStartup(app) {
this._buildUI(app);
this._scanExtensions();
}
vfunc_command_line(commandLine) {
this.activate();
_onCommandLine(app, commandLine) {
app.activate();
let args = commandLine.get_arguments();
if (args.length) {
@ -336,14 +323,16 @@ class Application extends Gtk.Application {
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, "extension:///");
if (!this._loaded)
if (this._extensionAvailable(uuid))
this._selectExtension(uuid);
else if (!this._loaded)
this._startupUuid = uuid;
else if (!this._showPrefs(uuid))
else
this._skipMainWindow = false;
}
return 0;
}
});
};
var Expander = GObject.registerClass({
Properties: {
@ -351,20 +340,20 @@ var Expander = GObject.registerClass({
'label', 'label', 'label',
GObject.ParamFlags.READWRITE,
null
),
},
)
}
}, class Expander extends Gtk.Box {
_init(params = {}) {
this._labelText = null;
super._init(Object.assign(params, {
orientation: Gtk.Orientation.VERTICAL,
spacing: 0,
spacing: 0
}));
this._frame = new Gtk.Frame({
shadow_type: Gtk.ShadowType.IN,
hexpand: true,
hexpand: true
});
let eventBox = new Gtk.EventBox();
@ -372,12 +361,12 @@ var Expander = GObject.registerClass({
let hbox = new Gtk.Box({
spacing: 6,
margin: 12,
margin: 12
});
eventBox.add(hbox);
this._arrow = new Gtk.Image({
icon_name: 'pan-end-symbolic',
icon_name: 'pan-end-symbolic'
});
hbox.add(this._arrow);
@ -387,7 +376,7 @@ var Expander = GObject.registerClass({
this._revealer = new Gtk.Revealer();
this._childBin = new Gtk.Frame({
shadow_type: Gtk.ShadowType.IN,
shadow_type: Gtk.ShadowType.IN
});
this._revealer.add(this._childBin);
@ -405,7 +394,7 @@ var Expander = GObject.registerClass({
this._gesture = new Gtk.GestureMultiPress({
widget: this._frame,
button: 0,
exclusive: true,
exclusive: true
});
this._gesture.connect('released', (gesture, nPress) => {
if (nPress == 1)
@ -450,7 +439,7 @@ class EmptyPlaceholder extends Gtk.Box {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 6,
margin: 32,
margin: 32
});
let image = new Gtk.Image({
@ -458,15 +447,15 @@ class EmptyPlaceholder extends Gtk.Box {
pixel_size: 96,
visible: true,
vexpand: true,
valign: Gtk.Align.END,
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>`,
label: `<b><span size="x-large">${_("No Extensions Installed" )}</span></b>`,
use_markup: true,
visible: true,
visible: true
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
@ -481,9 +470,9 @@ class EmptyPlaceholder extends Gtk.Box {
visible: true,
max_width_chars: 50,
hexpand: true,
vexpand: appInfo == null,
vexpand: (appInfo == null),
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
valign: Gtk.Align.START
});
this.add(desc);
@ -491,14 +480,14 @@ class EmptyPlaceholder extends Gtk.Box {
let button = new Gtk.Button({
label: _("Browse in Software"),
image: new Gtk.Image({
icon_name: "org.gnome.Software-symbolic",
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,
vexpand: true
});
this.add(button);
@ -510,35 +499,6 @@ class EmptyPlaceholder extends Gtk.Box {
}
});
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) {
@ -551,59 +511,30 @@ class DescriptionLabel extends Gtk.Label {
var ExtensionRow = GObject.registerClass(
class ExtensionRow extends Gtk.ListBoxRow {
_init(extension) {
_init(uuid) {
super._init();
this._app = Gio.Application.get_default();
this._extension = extension;
this._prefsModule = null;
this.uuid = uuid;
this.connect('destroy', this._onDestroy.bind(this));
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
this._settings.connect('changed::enabled-extensions', () => {
this._switch.state = this._isEnabled();
});
this._settings.connect('changed::disable-extension-version-validation',
() => {
this._switch.sensitive = this._canEnable();
});
this._settings.connect('changed::disable-user-extensions',
() => {
this._switch.sensitive = this._canEnable();
});
this._buildUI();
this._extensionStateChangedId = this._app.shellProxy.connectSignal(
'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
if (this.uuid !== uuid)
return;
this._extension = ExtensionUtils.deserializeExtension(newState);
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();
});
}
get uuid() {
return this._extension.uuid;
}
get name() {
return this._extension.metadata.name;
}
get hasPrefs() {
return this._extension.hasPrefs;
}
get url() {
return this._extension.metadata.url;
}
_onDestroy() {
if (!this._app.shellProxy)
return;
if (this._extensionStateChangedId)
this._app.shellProxy.disconnectSignal(this._extensionStateChangedId);
this._extensionStateChangedId = 0;
}
_buildUI() {
let extension = ExtensionUtils.extensions[this.uuid];
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
hexpand: true, margin_end: 24, spacing: 24,
margin: 12 });
@ -613,20 +544,19 @@ class ExtensionRow extends Gtk.ListBoxRow {
spacing: 6, hexpand: true });
hbox.add(vbox);
let name = GLib.markup_escape_text(this.name, -1);
let name = GLib.markup_escape_text(extension.metadata.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];
let desc = 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,
@ -636,37 +566,51 @@ class ExtensionRow extends Gtk.ListBoxRow {
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', () => {
this._switch = new Gtk.Switch({ valign: Gtk.Align.CENTER,
sensitive: this._canEnable(),
state: this._isEnabled() });
this._switch.connect('notify::active', () => {
if (this._switch.active)
this._app.shellProxy.EnableExtensionRemote(this.uuid);
this._enable();
else
this._app.shellProxy.DisableExtensionRemote(this.uuid);
this._disable();
});
this._switch.connect('state-set', () => true);
hbox.add(this._switch);
}
_canToggle() {
return this._extension.canChange;
_canEnable() {
let extension = ExtensionUtils.extensions[this.uuid];
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
return !this._settings.get_boolean('disable-user-extensions') &&
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
}
get prefsModule() {
// give extension prefs access to their own extension object
ExtensionUtils.getCurrentExtension = () => this._extension;
_isEnabled() {
let extensions = this._settings.get_strv('enabled-extensions');
return extensions.includes(this.uuid);
}
if (!this._prefsModule) {
ExtensionUtils.installImporter(this._extension);
_enable() {
let extensions = this._settings.get_strv('enabled-extensions');
if (extensions.includes(this.uuid))
return;
this._prefsModule = this._extension.imports.prefs;
this._prefsModule.init(this._extension.metadata);
}
extensions.push(this.uuid);
this._settings.set_strv('enabled-extensions', extensions);
}
return this._prefsModule;
_disable() {
let extensions = this._settings.get_strv('enabled-extensions');
let pos = extensions.indexOf(this.uuid);
if (pos == -1)
return;
do {
extensions.splice(pos, 1);
pos = extensions.indexOf(this.uuid);
} while (pos != -1);
this._settings.set_strv('enabled-extensions', extensions);
}
});
@ -682,7 +626,7 @@ function initEnvironment() {
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'])
};
String.prototype.format = Format.format;
@ -691,5 +635,9 @@ function initEnvironment() {
function main(argv) {
initEnvironment();
new Application().run(argv);
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
Gettext.textdomain(Config.GETTEXT_PACKAGE);
let app = new Application();
app.application.run(argv);
}

View File

@ -1,58 +1,41 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported AuthPrompt */
const { Clutter, GObject, Pango, Shell, St } = imports.gi;
const { Clutter, Pango, Shell, St } = imports.gi;
const Signals = imports.signals;
const Animation = imports.ui.animation;
const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util;
const Util = imports.misc.util;
const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
var DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
const WIGGLE_OFFSET = 6;
const WIGGLE_DURATION = 65;
const N_WIGGLES = 3;
var MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5;
var AuthPromptMode = {
UNLOCK_ONLY: 0,
UNLOCK_OR_LOG_IN: 1,
UNLOCK_OR_LOG_IN: 1
};
var AuthPromptStatus = {
NOT_VERIFYING: 0,
VERIFYING: 1,
VERIFICATION_FAILED: 2,
VERIFICATION_SUCCEEDED: 3,
VERIFICATION_SUCCEEDED: 3
};
var BeginRequestType = {
PROVIDE_USERNAME: 0,
DONT_PROVIDE_USERNAME: 1,
DONT_PROVIDE_USERNAME: 1
};
var AuthPrompt = GObject.registerClass({
Signals: {
'cancelled': {},
'failed': {},
'next': {},
'prompted': {},
'reset': { param_types: [GObject.TYPE_UINT] },
},
}, class AuthPrompt extends St.BoxLayout {
_init(gdmClient, mode) {
super._init({
style_class: 'login-dialog-prompt-layout',
vertical: true,
});
var AuthPrompt = class {
constructor(gdmClient, mode) {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient;
@ -64,7 +47,7 @@ var AuthPrompt = GObject.registerClass({
else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN)
reauthenticationOnly = false;
this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly });
this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly });
this._userVerifier.connect('ask-question', this._onAskQuestion.bind(this));
this._userVerifier.connect('show-message', this._onShowMessage.bind(this));
@ -78,80 +61,70 @@ var AuthPrompt = GObject.registerClass({
this.connect('next', () => {
this.updateSensitivity(false);
this.startSpinning();
if (this._queryingService)
if (this._queryingService) {
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
else
} else {
this._preemptiveAnswer = this._entry.text;
}
});
this.connect('destroy', this._onDestroy.bind(this));
this._userWell = new St.Bin({
x_expand: true,
y_expand: true,
});
this.add_child(this._userWell);
this._label = new St.Label({
style_class: 'login-dialog-prompt-label',
x_expand: false,
y_expand: true,
this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
vertical: true });
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('key-press-event', (actor, event) => {
if (event.get_key_symbol() == Clutter.KEY_Escape)
this.cancel();
return Clutter.EVENT_PROPAGATE;
});
this.add_child(this._label);
this._userWell = new St.Bin({ x_fill: true,
x_align: St.Align.START });
this.actor.add(this._userWell,
{ x_align: St.Align.START,
x_fill: true,
y_fill: true,
expand: true });
this._label = new St.Label({ style_class: 'login-dialog-prompt-label' });
let entryParams = {
style_class: 'login-dialog-prompt-entry',
can_focus: true,
x_expand: false,
y_expand: true,
};
this.actor.add(this._label,
{ expand: true,
x_fill: false,
y_fill: true,
x_align: St.Align.START });
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
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.actor.add(this._entry,
{ expand: true,
x_fill: true,
y_fill: false,
x_align: St.Align.START });
this._entry.grab_key_focus();
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
this.add_child(this._capsLockWarningLabel);
this._message = new St.Label({
opacity: 0,
styleClass: 'login-dialog-message',
x_expand: false,
y_expand: true,
y_align: Clutter.ActorAlign.START,
});
this._message = new St.Label({ opacity: 0,
styleClass: 'login-dialog-message' });
this._message.clutter_text.line_wrap = true;
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.add_child(this._message);
this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
this._buttonBox = new St.BoxLayout({
style_class: 'login-dialog-button-box',
vertical: false,
y_align: Clutter.ActorAlign.END,
});
this.add_child(this._buttonBox);
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
vertical: false });
this.actor.add(this._buttonBox,
{ expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END });
this._defaultButtonWell = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
});
this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._defaultButtonWellActor = null;
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);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
this._defaultButtonWell.add_child(this._spinner.actor);
}
_onDestroy() {
@ -159,39 +132,39 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier = null;
}
vfunc_key_press_event(keyPressEvent) {
if (keyPressEvent.keyval == Clutter.KEY_Escape)
this.cancel();
return Clutter.EVENT_PROPAGATE;
}
_initButtons() {
this.cancelButton = new St.Button({
style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Cancel"),
x_expand: true,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END,
});
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Cancel") });
this.cancelButton.connect('clicked', () => this.cancel());
this._buttonBox.add_child(this.cancelButton);
this._buttonBox.add(this.cancelButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.END });
this._buttonBox.add_child(this._defaultButtonWell);
this.nextButton = new St.Button({
style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Next"),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.END,
});
this._buttonBox.add(this._defaultButtonWell,
{ expand: true,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
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") });
this.nextButton.connect('clicked', () => this.emit('next'));
this.nextButton.add_style_pseudo_class('default');
this._buttonBox.add_child(this.nextButton);
this._buttonBox.add(this.nextButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.END });
this._updateNextButtonSensitivity(this._entry.text.length > 0);
@ -207,18 +180,7 @@ var AuthPrompt = GObject.registerClass({
});
}
_updateEntry(secret) {
if (secret && (this._entry != this._passwordEntry)) {
this.replace_child(this._entry, this._passwordEntry);
this._entry = this._passwordEntry;
} else if (!secret && (this._entry != this._textEntry)) {
this.replace_child(this._entry, this._textEntry);
this._entry = this._textEntry;
}
this._capsLockWarningLabel.visible = secret;
}
_onAskQuestion(verifier, serviceName, question, secret) {
_onAskQuestion(verifier, serviceName, question, passwordChar) {
if (this._queryingService)
this.clear();
@ -228,11 +190,10 @@ var AuthPrompt = GObject.registerClass({
this._preemptiveAnswer = null;
return;
}
this._updateEntry(secret);
this.setPasswordChar(passwordChar);
this.setQuestion(question);
if (secret) {
if (passwordChar) {
if (this._userVerifier.reauthenticating)
this.nextButton.label = _("Unlock");
else
@ -281,12 +242,6 @@ var AuthPrompt = GObject.registerClass({
this.updateSensitivity(canRetry);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
Util.wiggle(this._entry, {
offset: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES,
});
}
_onVerificationComplete() {
@ -312,16 +267,16 @@ var AuthPrompt = GObject.registerClass({
let oldActor = this._defaultButtonWellActor;
if (oldActor)
oldActor.remove_all_transitions();
Tweener.removeTweens(oldActor);
let wasSpinner;
if (oldActor == this._spinner)
if (oldActor == this._spinner.actor)
wasSpinner = true;
else
wasSpinner = false;
let isSpinner;
if (actor == this._spinner)
if (actor == this._spinner.actor)
isSpinner = true;
else
isSpinner = false;
@ -335,18 +290,18 @@ var AuthPrompt = GObject.registerClass({
this._spinner.stop();
}
} else {
oldActor.ease({
opacity: 0,
duration: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
mode: Clutter.AnimationMode.LINEAR,
onComplete: () => {
if (wasSpinner) {
if (this._spinner)
this._spinner.stop();
}
},
});
Tweener.addTween(oldActor,
{ opacity: 0,
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
transition: 'linear',
onComplete: () => {
if (wasSpinner) {
if (this._spinner)
this._spinner.stop();
}
}
});
}
}
@ -354,23 +309,21 @@ var AuthPrompt = GObject.registerClass({
if (isSpinner)
this._spinner.play();
if (!animate) {
if (!animate)
actor.opacity = 255;
} else {
actor.ease({
opacity: 255,
duration: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
mode: Clutter.AnimationMode.LINEAR,
});
}
else
Tweener.addTween(actor,
{ opacity: 255,
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
transition: 'linear' });
}
this._defaultButtonWellActor = actor;
}
startSpinning() {
this.setActorInDefaultButtonWell(this._spinner, true);
this.setActorInDefaultButtonWell(this._spinner.actor, true);
}
stopSpinning() {
@ -382,6 +335,11 @@ var AuthPrompt = GObject.registerClass({
this.stopSpinning();
}
setPasswordChar(passwordChar) {
this._entry.clutter_text.set_password_char(passwordChar);
this._entry.menu.isPassword = passwordChar != '';
}
setQuestion(question) {
this._label.set_text(question);
@ -407,12 +365,12 @@ var AuthPrompt = GObject.registerClass({
_fadeOutMessage() {
if (this._message.opacity == 0)
return;
this._message.remove_all_transitions();
this._message.ease({
opacity: 0,
duration: MESSAGE_FADE_OUT_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
Tweener.removeTweens(this._message);
Tweener.addTween(this._message,
{ opacity: 0,
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
setMessage(message, type) {
@ -427,7 +385,7 @@ var AuthPrompt = GObject.registerClass({
this._message.remove_style_class_name('login-dialog-message-hint');
if (message) {
this._message.remove_all_transitions();
Tweener.removeTweens(this._message);
this._message.text = message;
this._message.opacity = 255;
} else {
@ -446,9 +404,9 @@ var AuthPrompt = GObject.registerClass({
this._entry.clutter_text.editable = sensitive;
}
vfunc_hide() {
hide() {
this.setActorInDefaultButtonWell(null, true);
super.vfunc_hide();
this.actor.hide();
this._message.opacity = 0;
this.setUser(null);
@ -464,8 +422,7 @@ var AuthPrompt = GObject.registerClass({
if (user) {
let userWidget = new UserWidget.UserWidget(user);
userWidget.x_align = Clutter.ActorAlign.START;
this._userWell.set_child(userWidget);
this._userWell.set_child(userWidget.actor);
}
}
@ -544,10 +501,11 @@ var AuthPrompt = GObject.registerClass({
}
cancel() {
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED)
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
return;
}
this.reset();
this.emit('cancelled');
}
});
};
Signals.addSignalMethods(AuthPrompt.prototype);

View File

@ -20,7 +20,7 @@
* In order for transformation animations to look good, they need to be
* incremental and have some order to them (e.g., fade out hidden items,
* then shrink to close the void left over). Chaining animations in this way can
* be error-prone and wordy using just ease() callbacks.
* be error-prone and wordy using just Tweener callbacks.
*
* The classes in this file help with this:
*
@ -112,12 +112,13 @@ var Batch = class extends Task {
for (let i = 0; i < tasks.length; i++) {
let task;
if (tasks[i] instanceof Task)
if (tasks[i] instanceof Task) {
task = tasks[i];
else if (typeof tasks[i] == 'function')
} else if (typeof tasks[i] == 'function') {
task = new Task(scope, tasks[i]);
else
} else {
throw new Error('Batch tasks must be functions or Task, Hold or Batch objects');
}
this.tasks.push(task);
}
@ -128,8 +129,9 @@ var Batch = class extends Task {
}
runTask() {
if (!(this._currentTaskIndex in this.tasks))
if (!(this._currentTaskIndex in this.tasks)) {
return null;
}
return this.tasks[this._currentTaskIndex].run();
}
@ -177,8 +179,9 @@ var ConcurrentBatch = class extends Batch {
process() {
let hold = this.runTask();
if (hold)
if (hold) {
this.hold.acquireUntilAfter(hold);
}
// Regardless of the state of the just run task,
// fire off the next one, so all the tasks can run
@ -199,6 +202,7 @@ var ConsecutiveBatch = class extends Batch {
hold.disconnect(signalId);
this.nextTask();
});
return;
} else {
// This task finished, process the next one
this.nextTask();

View File

@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported FprintManager */
const Gio = imports.gi.Gio;
@ -20,7 +19,7 @@ function FprintManager() {
g_interface_info: FprintManagerInfo,
g_name: 'net.reactivated.Fprint',
g_object_path: '/net/reactivated/Fprint/Manager',
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
try {
self.init(null);

View File

@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported LoginDialog */
/*
* Copyright 2011 Red Hat, Inc
*
@ -19,6 +18,7 @@
const { AccountsService, Atk, Clutter, Gdm, Gio,
GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
const Signals = imports.signals;
const AuthPrompt = imports.gdm.authPrompt;
const Batch = imports.gdm.batch;
@ -30,89 +30,81 @@ const LoginManager = imports.misc.loginManager;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const Realmd = imports.gdm.realmd;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
const _FADE_ANIMATION_TIME = 250;
const _SCROLL_ANIMATION_TIME = 500;
const _FADE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = GObject.registerClass({
Signals: { 'activate': {} },
}, class UserListItem extends St.Button {
_init(user) {
let layout = new St.BoxLayout({
vertical: true,
x_align: Clutter.ActorAlign.START,
});
super._init({
style_class: 'login-dialog-user-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
x_expand: true,
child: layout,
reactive: true,
});
var UserListItem = class {
constructor(user) {
this.user = user;
this._userChangedId = this.user.connect('changed',
this._onUserChanged.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
this.connect('notify::hover', () => {
this._setSelected(this.hover);
let layout = new St.BoxLayout({ vertical: true });
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true });
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('key-focus-in', () => {
this._setSelected(true);
});
this.actor.connect('key-focus-out', () => {
this._setSelected(false);
});
this.actor.connect('notify::hover', () => {
this._setSelected(this.actor.hover);
});
this._userWidget = new UserWidget.UserWidget(this.user);
layout.add(this._userWidget);
layout.add(this._userWidget.actor);
this._userWidget.bind_property('label-actor', this, 'label-actor',
GObject.BindingFlags.SYNC_CREATE);
this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE);
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0,
visible: false });
layout.add(this._timedLoginIndicator);
this.actor.connect('clicked', this._onClicked.bind(this));
this._onUserChanged();
}
vfunc_key_focus_in() {
super.vfunc_key_focus_in();
this._setSelected(true);
}
vfunc_key_focus_out() {
super.vfunc_key_focus_out();
this._setSelected(false);
}
_onUserChanged() {
this._updateLoggedIn();
}
_updateLoggedIn() {
if (this.user.is_logged_in())
this.add_style_pseudo_class('logged-in');
this.actor.add_style_pseudo_class('logged-in');
else
this.remove_style_pseudo_class('logged-in');
this.actor.remove_style_pseudo_class('logged-in');
}
_onDestroy() {
this.user.disconnect(this._userChangedId);
}
vfunc_clicked() {
_onClicked() {
this.emit('activate');
}
_setSelected(selected) {
if (selected) {
this.add_style_pseudo_class('selected');
this.grab_key_focus();
this.actor.add_style_pseudo_class('selected');
this.actor.grab_key_focus();
} else {
this.remove_style_pseudo_class('selected');
this.actor.remove_style_pseudo_class('selected');
}
}
@ -125,7 +117,7 @@ var UserListItem = GObject.registerClass({
let startTime = GLib.get_monotonic_time();
this._timedLoginTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 33,
this._timedLoginTimeoutId = GLib.timeout_add (GLib.PRIORITY_DEFAULT, 33,
() => {
let currentTime = GLib.get_monotonic_time();
let elapsedTime = (currentTime - startTime) / GLib.USEC_PER_SEC;
@ -153,33 +145,23 @@ var UserListItem = GObject.registerClass({
this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.;
}
});
};
Signals.addSignalMethods(UserListItem.prototype);
var UserList = GObject.registerClass({
Signals: {
'activate': { param_types: [UserListItem.$gtype] },
'item-added': { param_types: [UserListItem.$gtype] },
},
}, class UserList extends St.ScrollView {
_init() {
super._init({
style_class: 'login-dialog-user-list-view',
x_expand: true,
y_expand: true,
});
this.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
var UserList = class {
constructor() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view' });
this.actor.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
this._box = new St.BoxLayout({ vertical: true,
style_class: 'login-dialog-user-list',
pseudo_class: 'expanded' });
this.add_actor(this._box);
this.actor.add_actor(this._box);
this._items = {};
}
vfunc_key_focus_in() {
this._moveFocusToItems();
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
}
_moveFocusToItems() {
@ -188,10 +170,10 @@ var UserList = GObject.registerClass({
if (!hasItems)
return;
if (global.stage.get_key_focus() != this)
if (global.stage.get_key_focus() != this.actor)
return;
let focusSet = this.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
if (!focusSet) {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._moveFocusToItems();
@ -212,26 +194,27 @@ var UserList = GObject.registerClass({
for (let userName in this._items) {
let item = this._items[userName];
item.sync_hover();
item.actor.sync_hover();
}
}
scrollToItem(item) {
let box = item.get_allocation_box();
let box = item.actor.get_allocation_box();
let adjustment = this.get_vscroll_bar().get_adjustment();
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
adjustment.ease(value, {
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: _SCROLL_ANIMATION_TIME,
});
Tweener.removeTweens(adjustment);
Tweener.addTween (adjustment,
{ value: value,
time: _SCROLL_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
jumpToItem(item) {
let box = item.get_allocation_box();
let box = item.actor.get_allocation_box();
let adjustment = this.get_vscroll_bar().get_adjustment();
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
@ -269,14 +252,14 @@ var UserList = GObject.registerClass({
this.removeUser(user);
let item = new UserListItem(user);
this._box.add_child(item);
this._box.add(item.actor, { x_fill: true });
this._items[userName] = item;
item.connect('activate', this._onItemActivated.bind(this));
// Try to keep the focused item front-and-center
item.connect('key-focus-in', () => this.scrollToItem(item));
item.actor.connect('key-focus-in', () => this.scrollToItem(item));
this._moveFocusToItems();
@ -297,37 +280,33 @@ var UserList = GObject.registerClass({
if (!item)
return;
item.destroy();
item.actor.destroy();
delete this._items[userName];
}
numItems() {
return Object.keys(this._items).length;
}
});
};
Signals.addSignalMethods(UserList.prototype);
var SessionMenuButton = GObject.registerClass({
Signals: { 'session-activated': { param_types: [GObject.TYPE_STRING] } },
}, class SessionMenuButton extends St.Bin {
_init() {
var SessionMenuButton = class {
constructor() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
let button = new St.Button({
style_class: 'login-dialog-session-list-button',
reactive: true,
track_hover: true,
can_focus: true,
accessible_name: _("Choose Session"),
accessible_role: Atk.Role.MENU,
child: gearIcon,
});
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
reactive: true,
track_hover: true,
can_focus: true,
accessible_name: _("Choose Session"),
accessible_role: Atk.Role.MENU,
child: gearIcon });
super._init({ child: button });
this._button = button;
this.actor = new St.Bin({ child: this._button });
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)
if (this.actor.text_direction == Clutter.TextDirection.RTL)
side = St.Side.RIGHT;
else
side = St.Side.LEFT;
@ -393,7 +372,7 @@ var SessionMenuButton = GObject.registerClass({
}
for (let i = 0; i < ids.length; i++) {
let [sessionName, sessionDescription_] = Gdm.get_session_name_and_description(ids[i]);
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
let id = ids[i];
let item = new PopupMenu.PopupMenuItem(sessionName);
@ -406,13 +385,15 @@ var SessionMenuButton = GObject.registerClass({
});
}
}
});
};
Signals.addSignalMethods(SessionMenuButton.prototype);
var LoginDialog = GObject.registerClass({
Signals: { 'failed': {} },
}, class LoginDialog extends St.Widget {
_init(parentActor) {
super._init({ style_class: 'login-dialog', visible: false });
super._init({ style_class: 'login-dialog',
visible: false });
this.get_accessible().set_role(Atk.Role.WINDOW);
@ -446,35 +427,38 @@ var LoginDialog = GObject.registerClass({
this.add_child(this._userSelectionBox);
this._userList = new UserList();
this._userSelectionBox.add_child(this._userList);
this._userSelectionBox.add(this._userList.actor,
{ expand: true,
x_fill: true,
y_fill: true });
this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
this._authPrompt.connect('prompted', this._onPrompted.bind(this));
this._authPrompt.connect('reset', this._onReset.bind(this));
this._authPrompt.hide();
this.add_child(this._authPrompt);
this.add_child(this._authPrompt.actor);
// translators: this message is shown below the user list on the
// login screen. It can be activated to reveal an entry for
// manually entering the username.
let notListedLabel = new St.Label({
text: _("Not listed?"),
style_class: 'login-dialog-not-listed-label',
x_align: Clutter.ActorAlign.START,
});
this._notListedButton = new St.Button({
style_class: 'login-dialog-not-listed-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
child: notListedLabel,
reactive: true,
});
let notListedLabel = new St.Label({ text: _("Not listed?"),
style_class: 'login-dialog-not-listed-label' });
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
child: notListedLabel,
reactive: true,
x_align: St.Align.START,
x_fill: true });
this._notListedButton.connect('clicked', this._hideUserListAskForUsernameAndBeginVerification.bind(this));
this._notListedButton.hide();
this._userSelectionBox.add_child(this._notListedButton);
this._userSelectionBox.add(this._notListedButton,
{ expand: false,
x_align: St.Align.START,
x_fill: true });
this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
opacity: 0,
@ -509,11 +493,11 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton = new SessionMenuButton();
this._sessionMenuButton.connect('session-activated',
(list, sessionId) => {
this._greeter.call_select_session_sync(sessionId, null);
this._greeter.call_select_session_sync (sessionId, null);
});
this._sessionMenuButton.opacity = 0;
this._sessionMenuButton.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton);
this._sessionMenuButton.actor.opacity = 0;
this._sessionMenuButton.actor.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
this._disableUserList = undefined;
this._userListLoaded = false;
@ -534,7 +518,7 @@ var LoginDialog = GObject.registerClass({
_getBannerAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
let [, , natWidth, natHeight] = this._bannerView.get_preferred_size();
let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size();
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
actorBox.x1 = Math.floor(centerX - natWidth / 2);
@ -548,7 +532,7 @@ var LoginDialog = GObject.registerClass({
_getLogoBinAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
let [, , natWidth, natHeight] = this._logoBin.get_preferred_size();
let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
actorBox.x1 = Math.floor(centerX - natWidth / 2);
@ -562,7 +546,7 @@ var LoginDialog = GObject.registerClass({
_getCenterActorAllocation(dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
let [, , natWidth, natHeight] = actor.get_preferred_size();
let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
@ -596,8 +580,8 @@ var LoginDialog = GObject.registerClass({
let authPromptAllocation = null;
let authPromptWidth = 0;
if (this._authPrompt.visible) {
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt);
if (this._authPrompt.actor.visible) {
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
}
@ -664,7 +648,7 @@ var LoginDialog = GObject.registerClass({
// figure out how tall it would like to be and try to accommodate
// but don't let it get too close to the logo
let [, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
let maxWideHeight = dialogHeight - 3 * logoHeight;
wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
@ -702,11 +686,12 @@ var LoginDialog = GObject.registerClass({
}
// Finally hand out the allocations
if (bannerAllocation)
if (bannerAllocation) {
this._bannerView.allocate(bannerAllocation, flags);
}
if (authPromptAllocation)
this._authPrompt.allocate(authPromptAllocation, flags);
this._authPrompt.actor.allocate(authPromptAllocation, flags);
if (userSelectionAllocation)
this._userSelectionBox.allocate(userSelectionAllocation, flags);
@ -773,15 +758,14 @@ var LoginDialog = GObject.registerClass({
_fadeInBannerView() {
this._bannerView.show();
this._bannerView.ease({
opacity: 255,
duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
Tweener.addTween(this._bannerView,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
_hideBannerView() {
this._bannerView.remove_all_transitions();
Tweener.removeTweens(this._bannerView);
this._bannerView.opacity = 0;
this._bannerView.hide();
}
@ -810,7 +794,7 @@ var LoginDialog = GObject.registerClass({
_onPrompted() {
if (this._shouldShowSessionMenuButton()) {
this._sessionMenuButton.updateSensitivity(true);
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton);
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
} else {
this._sessionMenuButton.updateSensitivity(false);
}
@ -819,9 +803,9 @@ var LoginDialog = GObject.registerClass({
_resetGreeterProxy() {
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
if (this._greeter)
if (this._greeter) {
this._greeter.run_dispose();
}
this._greeter = this._gdmClient.get_greeter_sync(null);
this._defaultSessionChangedId = this._greeter.connect('default-session-name-changed',
@ -870,15 +854,14 @@ var LoginDialog = GObject.registerClass({
}
_showPrompt() {
if (this._authPrompt.visible)
if (this._authPrompt.actor.visible)
return;
this._authPrompt.opacity = 0;
this._authPrompt.show();
this._authPrompt.ease({
opacity: 255,
duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
this._authPrompt.actor.opacity = 0;
this._authPrompt.actor.show();
Tweener.addTween(this._authPrompt.actor,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
this._fadeInBannerView();
}
@ -896,6 +879,7 @@ var LoginDialog = GObject.registerClass({
}
_askForUsernameAndBeginVerification() {
this._authPrompt.setPasswordChar('');
this._authPrompt.setQuestion(_("Username: "));
this._showRealmLoginHint(this._realmManager.loginFormat);
@ -921,31 +905,26 @@ var LoginDialog = GObject.registerClass({
this._showPrompt();
}
_bindOpacity() {
this._bindings = Main.layoutManager.uiGroup.get_children()
.filter(c => c != Main.layoutManager.screenShieldGroup)
.map(c => this.bind_property('opacity', c, 'opacity', 0));
}
_unbindOpacity() {
this._bindings.forEach(b => b.unbind());
}
_loginScreenSessionActivated() {
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
return;
this._bindOpacity();
this.ease({
opacity: 255,
duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._unbindOpacity();
},
});
Tweener.addTween(this,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onUpdate: () => {
let children = Main.layoutManager.uiGroup.get_children();
for (let i = 0; i < children.length; i++) {
if (children[i] != Main.layoutManager.screenShieldGroup)
children[i].opacity = this.opacity;
}
},
onComplete: () => {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
} });
}
_gotGreeterSessionProxy(proxy) {
@ -958,16 +937,21 @@ var LoginDialog = GObject.registerClass({
}
_startSession(serviceName) {
this._bindOpacity();
this.ease({
opacity: 0,
duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
this._unbindOpacity();
},
});
Tweener.addTween(this,
{ opacity: 0,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onUpdate: () => {
let children = Main.layoutManager.uiGroup.get_children();
for (let i = 0; i < children.length; i++) {
if (children[i] != Main.layoutManager.screenShieldGroup)
children[i].opacity = this.opacity;
}
},
onComplete: () => {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
} });
}
_onSessionOpened(client, serviceName) {
@ -983,7 +967,7 @@ var LoginDialog = GObject.registerClass({
let hold = new Batch.Hold();
let signalId = this._userList.connect('item-added',
() => {
item = this._userList.getItemFromUserName(userName);
let item = this._userList.getItemFromUserName(userName);
if (item)
hold.release();
@ -1037,8 +1021,9 @@ var LoginDialog = GObject.registerClass({
() => {
// If we're just starting out, start on the right item.
if (!this._userManager.is_loaded)
if (!this._userManager.is_loaded) {
this._userList.jumpToItem(loginItem);
}
},
() => {
@ -1059,12 +1044,12 @@ var LoginDialog = GObject.registerClass({
() => {
// If idle timeout is done, make sure the timed login indicator is shown
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
this._authPrompt.visible)
this._authPrompt.actor.visible)
this._authPrompt.cancel();
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
this._userList.scrollToItem(loginItem);
loginItem.grab_key_focus();
loginItem.actor.grab_key_focus();
}
},
@ -1089,8 +1074,9 @@ var LoginDialog = GObject.registerClass({
// Restart timed login on user interaction
global.stage.connect('captured-event', (actor, event) => {
if (event.type() == Clutter.EventType.KEY_PRESS ||
event.type() == Clutter.EventType.BUTTON_PRESS)
event.type() == Clutter.EventType.BUTTON_PRESS) {
this._startTimedLogin(userName, seconds);
}
return Clutter.EVENT_PROPAGATE;
});
@ -1124,7 +1110,7 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton.close();
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.grab_key_focus();
this._userList.actor.grab_key_focus();
}
_beginVerificationForItem(item) {
@ -1133,7 +1119,8 @@ var LoginDialog = GObject.registerClass({
let userName = item.user.get_user_name();
let hold = new Batch.Hold();
this._authPrompt.begin({ userName, hold });
this._authPrompt.begin({ userName: userName,
hold: hold });
return hold;
}
@ -1196,8 +1183,9 @@ var LoginDialog = GObject.registerClass({
let users = this._userManager.list_users();
for (let i = 0; i < users.length; i++)
for (let i = 0; i < users.length; i++) {
this._userList.addUser(users[i]);
}
this._updateDisableUserList();
@ -1230,17 +1218,16 @@ var LoginDialog = GObject.registerClass({
_("Login Window"),
'dialog-password-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
this._userList.grab_key_focus();
this._userList.actor.grab_key_focus();
this.show();
this.opacity = 0;
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
this.ease({
opacity: 255,
duration: 1000,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
});
Tweener.addTween(this,
{ opacity: 255,
time: 1,
transition: 'easeInQuad' });
return true;
}
@ -1254,7 +1241,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.cancel();
}
addCharacter(_unichar) {
addCharacter(unichar) {
// Don't allow type ahead at the login screen
}

View File

@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported getOVirtCredentialsManager */
const Gio = imports.gi.Gio;
const Signals = imports.signals;
@ -23,7 +22,7 @@ function OVirtCredentials() {
g_interface_info: OVirtCredentialsInfo,
g_name: 'org.ovirt.vdsm.Credentials',
g_object_path: '/org/ovirt/vdsm/Credentials',
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
self.init(null);
return self;
}

View File

@ -15,13 +15,12 @@ const RealmIface = loadInterfaceXML("org.freedesktop.realmd.Realm");
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
var Manager = class {
constructor() {
constructor(parentActor) {
this._aggregateProvider = Provider(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
this._reloadRealms.bind(this));
this._realms = {};
this._loginFormat = null;
this._signalId = this._aggregateProvider.connect('g-properties-changed',
(proxy, properties) => {
@ -87,7 +86,7 @@ var Manager = class {
}
get loginFormat() {
if (this._loginFormat)
if (this._loginFormat !== undefined)
return this._loginFormat;
this._updateLoginFormat();

View File

@ -1,6 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY,
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */
const { Clutter, Gio, GLib } = imports.gi;
const Signals = imports.signals;
@ -11,13 +9,14 @@ const OVirt = imports.gdm.oVirt;
const Main = imports.ui.main;
const Params = imports.misc.params;
const SmartcardManager = imports.misc.smartcardManager;
const Tweener = imports.ui.tweener;
var PASSWORD_SERVICE_NAME = 'gdm-password';
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
var OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
var FADE_ANIMATION_TIME = 160;
var CLONE_FADE_ANIMATION_TIME = 250;
var FADE_ANIMATION_TIME = 0.16;
var CLONE_FADE_ANIMATION_TIME = 0.25;
var LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
var PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication';
@ -37,7 +36,7 @@ var MessageType = {
NONE: 0,
ERROR: 1,
INFO: 2,
HINT: 3,
HINT: 3
};
function fadeInActor(actor) {
@ -46,20 +45,20 @@ function fadeInActor(actor) {
let hold = new Batch.Hold();
actor.show();
let [, naturalHeight] = actor.get_preferred_height(-1);
let [minHeight, naturalHeight] = actor.get_preferred_height(-1);
actor.opacity = 0;
actor.set_height(0);
actor.ease({
opacity: 255,
height: naturalHeight,
duration: FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this.set_height(-1);
hold.release();
},
});
Tweener.addTween(actor,
{ opacity: 255,
height: naturalHeight,
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete() {
this.set_height(-1);
hold.release();
},
});
return hold;
}
@ -72,17 +71,17 @@ function fadeOutActor(actor) {
}
let hold = new Batch.Hold();
actor.ease({
opacity: 0,
height: 0,
duration: FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this.hide();
this.set_height(-1);
hold.release();
},
});
Tweener.addTween(actor,
{ opacity: 0,
height: 0,
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete() {
this.hide();
this.set_height(-1);
hold.release();
},
});
return hold;
}
@ -102,15 +101,15 @@ function cloneAndFadeOutActor(actor) {
clone.set_position(x, y);
let hold = new Batch.Hold();
clone.ease({
opacity: 0,
duration: CLONE_FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
clone.destroy();
hold.release();
},
});
Tweener.addTween(clone,
{ opacity: 0,
time: CLONE_FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete() {
clone.destroy();
hold.release();
}
});
return hold;
}
@ -272,7 +271,7 @@ var ShellUserVerifier = class {
let interval = this._getIntervalForMessage(message);
this.hasPendingMessages = true;
this._messageQueue.push({ text: message, type: messageType, interval });
this._messageQueue.push({ text: message, type: messageType, interval: interval });
this._queueMessageTimeout();
}
@ -304,7 +303,7 @@ var ShellUserVerifier = class {
});
}
_oVirtUserAuthenticated(_token) {
_oVirtUserAuthenticated(token) {
this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('ovirt-user-authenticated');
}
@ -485,7 +484,7 @@ var ShellUserVerifier = class {
if (!this.serviceIsForeground(serviceName))
return;
this.emit('ask-question', serviceName, question, false);
this.emit('ask-question', serviceName, question, '');
}
_onSecretInfoQuery(client, serviceName, secretQuestion) {
@ -498,7 +497,7 @@ var ShellUserVerifier = class {
return;
}
this.emit('ask-question', serviceName, secretQuestion, true);
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
}
_onReset() {
@ -544,7 +543,6 @@ var ShellUserVerifier = class {
});
}
} else {
// eslint-disable-next-line no-lonely-if
if (!this.hasPendingMessages) {
this._cancelAndReset();
} else {
@ -572,8 +570,9 @@ var ShellUserVerifier = class {
// if the password service fails, then cancel everything.
// But if, e.g., fingerprint fails, still give
// password authentication a chance to succeed
if (this.serviceIsForeground(serviceName))
if (this.serviceIsForeground(serviceName)) {
this._verificationFailed(true);
}
}
};
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@ -32,6 +32,7 @@
<file>perf/core.js</file>
<file>perf/hwtest.js</file>
<file>ui/accessDialog.js</file>
<file>ui/altTab.js</file>
<file>ui/animation.js</file>
<file>ui/appDisplay.js</file>
@ -97,7 +98,6 @@
<file>ui/shellEntry.js</file>
<file>ui/shellMountOperation.js</file>
<file>ui/slider.js</file>
<file>ui/swipeTracker.js</file>
<file>ui/switcherPopup.js</file>
<file>ui/switchMonitor.js</file>
<file>ui/tweener.js</file>

View File

@ -1,46 +1,31 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ExtensionState, ExtensionType, getCurrentExtension,
getSettings, initTranslations, isOutOfDate, installImporter,
serializeExtension, deserializeExtension */
// Common utils for the extension system and the extension
// preferences tool
const { Gio, GLib } = imports.gi;
const Gettext = imports.gettext;
const Lang = imports.lang;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
const Config = imports.misc.config;
const FileUtils = imports.misc.fileUtils;
var ExtensionType = {
SYSTEM: 1,
PER_USER: 2,
PER_USER: 2
};
var ExtensionState = {
ENABLED: 1,
DISABLED: 2,
ERROR: 3,
OUT_OF_DATE: 4,
DOWNLOADING: 5,
INITIALIZED: 6,
// Used as an error state for operations on unknown extensions,
// should never be in a real extensionMeta object.
UNINSTALLED: 99,
};
const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs', 'canChange'];
// Maps uuid -> metadata object
var extensions = {};
/**
* getCurrentExtension:
*
* @returns {?object} - The current extension, or null if not called from
* an extension.
* Returns the current extension, or null if not called from an extension.
*/
function getCurrentExtension() {
let stack = new Error().stack.split('\n');
let stack = (new Error()).stack.split('\n');
let extensionStackLine;
// Search for an occurrence of an extension stack frame
@ -64,17 +49,13 @@ function getCurrentExtension() {
if (!match)
return null;
// local import, as the module is used from outside the gnome-shell process
// as well (not this function though)
let extensionManager = imports.ui.main.extensionManager;
let path = match[1];
let file = Gio.File.new_for_path(path);
// Walk up the directory tree, looking for an extension with
// the same UUID as a directory name.
while (file != null) {
let extension = extensionManager.lookup(file.get_basename());
let extension = extensions[file.get_basename()];
if (extension !== undefined)
return extension;
file = file.get_parent();
@ -85,7 +66,7 @@ function getCurrentExtension() {
/**
* initTranslations:
* @param {string=} domain - the gettext domain to use
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
@ -109,8 +90,7 @@ function initTranslations(domain) {
/**
* getSettings:
* @param {string=} schema - the GSettings schema id
* @returns {Gio.Settings} - a new settings object for @schema
* @schema: (optional): the GSettings schema id
*
* Builds and returns a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is omitted, it is taken from
@ -130,13 +110,12 @@ function getSettings(schema) {
// SYSTEM extension that has been installed in the same prefix as the shell
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null)) {
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
} else {
else
schemaSource = GioSSS.get_default();
}
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
@ -147,9 +126,8 @@ function getSettings(schema) {
/**
* versionCheck:
* @param {string[]} required - an array of versions we're compatible with
* @param {string} current - the version we have
* @returns {bool} - true if @current is compatible with @required
* @required: an array of versions we're compatible with
* @current: the version we have
*
* Check if a component is compatible for an extension.
* @required is an array, and at least one version must match.
@ -169,8 +147,8 @@ function versionCheck(required, current) {
let requiredArray = required[i].split('.');
if (requiredArray[0] == major &&
requiredArray[1] == minor &&
((requiredArray[2] === undefined && parseInt(minor) % 2 == 0) ||
requiredArray[2] == point))
(requiredArray[2] == point ||
(requiredArray[2] == undefined && parseInt(minor) % 2 == 0)))
return true;
}
return false;
@ -183,50 +161,52 @@ function isOutOfDate(extension) {
return false;
}
function serializeExtension(extension) {
let obj = {};
Lang.copyProperties(extension.metadata, obj);
function createExtensionObject(uuid, dir, type) {
let metadataFile = dir.get_child('metadata.json');
if (!metadataFile.query_exists(null)) {
throw new Error('Missing metadata.json');
}
SERIALIZED_PROPERTIES.forEach(prop => {
obj[prop] = extension[prop];
});
let metadataContents, success, tag;
try {
[success, metadataContents, tag] = metadataFile.load_contents(null);
if (metadataContents instanceof Uint8Array)
metadataContents = imports.byteArray.toString(metadataContents);
} catch (e) {
throw new Error(`Failed to load metadata.json: ${e}`);
}
let meta;
try {
meta = JSON.parse(metadataContents);
} catch (e) {
throw new Error(`Failed to parse metadata.json: ${e}`);
}
let res = {};
for (let key in obj) {
let val = obj[key];
let type;
switch (typeof val) {
case 'string':
type = 's';
break;
case 'number':
type = 'd';
break;
case 'boolean':
type = 'b';
break;
default:
continue;
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
for (let i = 0; i < requiredProperties.length; i++) {
let prop = requiredProperties[i];
if (!meta[prop]) {
throw new Error(`missing "${prop}" property in metadata.json`);
}
res[key] = GLib.Variant.new(type, val);
}
return res;
}
function deserializeExtension(variant) {
let res = { metadata: {} };
for (let prop in variant) {
let val = variant[prop].unpack();
if (SERIALIZED_PROPERTIES.includes(prop))
res[prop] = val;
else
res.metadata[prop] = val;
if (uuid != meta.uuid) {
throw new Error(`uuid "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
}
// add the 2 additional properties to create a valid extension object, as createExtensionObject()
res.uuid = res.metadata.uuid;
res.dir = Gio.File.new_for_path(res.path);
return res;
let extension = {};
extension.metadata = meta;
extension.uuid = meta.uuid;
extension.type = type;
extension.dir = dir;
extension.path = dir.get_path();
extension.error = '';
extension.hasPrefs = dir.get_child('prefs.js').query_exists(null);
extensions[uuid] = extension;
return extension;
}
function installImporter(extension) {
@ -237,3 +217,36 @@ function installImporter(extension) {
extension.imports = imports[extension.uuid];
imports.searchPath = oldSearchPath;
}
var ExtensionFinder = class {
_loadExtension(extensionDir, info, perUserDir) {
let fileType = info.get_file_type();
if (fileType != Gio.FileType.DIRECTORY)
return;
let uuid = info.get_name();
let existing = extensions[uuid];
if (existing) {
log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path, extensionDir.get_path()));
return;
}
let extension;
let type = extensionDir.has_prefix(perUserDir) ? ExtensionType.PER_USER
: ExtensionType.SYSTEM;
try {
extension = createExtensionObject(uuid, extensionDir, type);
} catch (e) {
logError(e, 'Could not load extension %s'.format(uuid));
return;
}
this.emit('extension-found', extension);
}
scanExtensions() {
let perUserDir = Gio.File.new_for_path(global.userdatadir);
FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
this._loadExtension(dir, info, perUserDir);
});
}
};
Signals.addSignalMethods(ExtensionFinder.prototype);

View File

@ -1,6 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported collectFromDatadirs, recursivelyDeleteDir,
recursivelyMoveDir, loadInterfaceXML */
const { Gio, GLib } = imports.gi;
const Config = imports.misc.config;
@ -29,6 +27,11 @@ function collectFromDatadirs(subdir, includeUserDir, processFile) {
}
}
function deleteGFile(file) {
// Work around 'delete' being a keyword in JS.
return file['delete'](null);
}
function recursivelyDeleteDir(dir, deleteParent) {
let children = dir.enumerate_children('standard::name,standard::type',
Gio.FileQueryInfoFlags.NONE, null);
@ -38,13 +41,13 @@ function recursivelyDeleteDir(dir, deleteParent) {
let type = info.get_file_type();
let child = dir.get_child(info.get_name());
if (type == Gio.FileType.REGULAR)
child.delete(null);
deleteGFile(child);
else if (type == Gio.FileType.DIRECTORY)
recursivelyDeleteDir(child, true);
}
if (deleteParent)
dir.delete(null);
deleteGFile(dir);
}
function recursivelyMoveDir(srcDir, destDir) {
@ -70,18 +73,18 @@ let _ifaceResource = null;
function loadInterfaceXML(iface) {
if (!_ifaceResource) {
// don't use global.datadir so the method is usable from tests/tools
let dir = GLib.getenv('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
let path = `${dir}/gnome-shell-dbus-interfaces.gresource`;
let dir = GLib.getenv ('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
let path = dir + '/gnome-shell-dbus-interfaces.gresource';
_ifaceResource = Gio.Resource.load(path);
_ifaceResource._register();
}
let xml = null;
let uri = `resource:///org/gnome/shell/dbus-interfaces/${iface}.xml`;
let uri = 'resource:///org/gnome/shell/dbus-interfaces/' + iface + '.xml';
let f = Gio.File.new_for_uri(uri);
try {
let [ok_, bytes] = f.load_contents(null);
let [ok, bytes] = f.load_contents(null);
if (bytes instanceof Uint8Array)
xml = imports.byteArray.toString(bytes);
else

View File

@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported PresenceStatus, Presence, Inhibitor, SessionManager */
const Gio = imports.gi.Gio;
@ -11,7 +10,7 @@ var PresenceStatus = {
AVAILABLE: 0,
INVISIBLE: 1,
BUSY: 2,
IDLE: 3,
IDLE: 3
};
var PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface);

View File

@ -28,7 +28,7 @@ var HistoryManager = class {
this._entry = params.entry;
if (this._entry) {
this._entry.connect('key-press-event',
this._entry.connect('key-press-event',
this._onEntryKeyPress.bind(this));
}
}
@ -82,11 +82,11 @@ var HistoryManager = class {
_onEntryKeyPress(entry, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Up)
if (symbol == Clutter.KEY_Up) {
return this._setPrevItem(entry.get_text());
else if (symbol == Clutter.KEY_Down)
} else if (symbol == Clutter.KEY_Down) {
return this._setNextItem(entry.get_text());
}
return Clutter.EVENT_PROPAGATE;
}

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported getIBusManager */
const { Gio, GLib, IBus } = imports.gi;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
@ -18,9 +18,9 @@ function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) {
IBus.MICRO_VERSION >= requiredMicro))
return;
throw "Found IBus version %d.%d.%d but required is %d.%d.%d"
.format(IBus.MAJOR_VERSION, IBus.MINOR_VERSION, IBus.MINOR_VERSION,
requiredMajor, requiredMinor, requiredMicro);
throw "Found IBus version %d.%d.%d but required is %d.%d.%d".
format(IBus.MAJOR_VERSION, IBus.MINOR_VERSION, IBus.MINOR_VERSION,
requiredMajor, requiredMinor, requiredMicro);
}
function getIBusManager() {
@ -58,30 +58,16 @@ var IBusManager = class {
this._spawn();
}
_spawn(extraArgs = []) {
_spawn() {
try {
let cmdLine = ['ibus-daemon', '--panel', 'disable', ...extraArgs];
Gio.Subprocess.new(cmdLine, Gio.SubprocessFlags.NONE);
Gio.Subprocess.new(['ibus-daemon', '--xim', '--panel', 'disable'],
Gio.SubprocessFlags.NONE);
} catch (e) {
log(`Failed to launch ibus-daemon: ${e.message}`);
}
}
restartDaemon(extraArgs = []) {
this._spawn(['-r', ...extraArgs]);
}
_clear() {
if (this._cancellable) {
this._cancellable.cancel();
this._cancellable = null;
}
if (this._preloadEnginesId) {
GLib.source_remove(this._preloadEnginesId);
this._preloadEnginesId = 0;
}
if (this._panelService)
this._panelService.destroy();
@ -93,44 +79,33 @@ var IBusManager = class {
this._currentEngineName = null;
this.emit('ready', false);
this._spawn();
}
_onConnected() {
this._cancellable = new Gio.Cancellable();
this._ibus.list_engines_async(-1, this._cancellable,
this._initEngines.bind(this));
this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
this._ibus.request_name_async(IBus.SERVICE_PANEL,
IBus.BusNameFlag.REPLACE_EXISTING, -1, this._cancellable,
this._initPanelService.bind(this));
IBus.BusNameFlag.REPLACE_EXISTING,
-1, null,
this._initPanelService.bind(this));
}
_initEngines(ibus, result) {
try {
let enginesList = this._ibus.list_engines_async_finish(result);
let enginesList = this._ibus.list_engines_async_finish(result);
if (enginesList) {
for (let i = 0; i < enginesList.length; ++i) {
let name = enginesList[i].get_name();
this._engines.set(name, enginesList[i]);
}
this._updateReadiness();
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
logError(e);
} else {
this._clear();
}
}
_initPanelService(ibus, result) {
let success = false;
try {
success = !!this._ibus.request_name_async_finish(result);
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
logError(e);
}
let success = this._ibus.request_name_async_finish(result);
if (success) {
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
object_path: IBus.PATH_PANEL });
@ -142,7 +117,7 @@ var IBusManager = class {
});
this._panelService.connect('focus-in', (panel, path) => {
if (!GLib.str_has_suffix(path, '/InputContext_1'))
this.emit('focus-in');
this.emit ('focus-in');
});
this._panelService.connect('focus-out', () => this.emit('focus-out'));
@ -157,10 +132,10 @@ var IBusManager = class {
} catch (e) {
}
// If an engine is already active we need to get its properties
this._ibus.get_global_engine_async(-1, this._cancellable, (_bus, res) => {
this._ibus.get_global_engine_async(-1, null, (i, result) => {
let engine;
try {
engine = this._ibus.get_global_engine_async_finish(res);
engine = this._ibus.get_global_engine_async_finish(result);
if (!engine)
return;
} catch (e) {
@ -229,18 +204,8 @@ var IBusManager = class {
return;
}
this._ibus.set_global_engine_async(id,
this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
this._cancellable, (_bus, res) => {
try {
this._ibus.set_global_engine_async_finish(res);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
logError(e);
}
if (callback)
callback();
});
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, callback || null);
}
preloadEngines(ids) {
@ -248,23 +213,21 @@ var IBusManager = class {
return;
if (this._preloadEnginesId != 0) {
GLib.source_remove(this._preloadEnginesId);
Mainloop.source_remove(this._preloadEnginesId);
this._preloadEnginesId = 0;
}
this._preloadEnginesId =
GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT,
this._PRELOAD_ENGINES_DELAY_TIME,
() => {
this._ibus.preload_engines_async(
ids,
-1,
this._cancellable,
null);
this._preloadEnginesId = 0;
return GLib.SOURCE_REMOVE;
});
Mainloop.timeout_add_seconds(this._PRELOAD_ENGINES_DELAY_TIME,
() => {
this._ibus.preload_engines_async(
ids,
-1,
null,
null);
this._preloadEnginesId = 0;
return GLib.SOURCE_REMOVE;
});
}
};
Signals.addSignalMethods(IBusManager.prototype);

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported InputMethod */
const { Clutter, GLib, Gio, GObject, IBus } = imports.gi;
const { Clutter, GLib, GObject, IBus } = imports.gi;
const Keyboard = imports.ui.status.keyboard;
@ -36,7 +35,15 @@ class InputMethod extends Clutter.InputMethod {
}
_updateCapabilities() {
let caps = IBus.Capabilite.PREEDIT_TEXT | IBus.Capabilite.FOCUS | IBus.Capabilite.SURROUNDING_TEXT;
let caps = 0;
if (this.can_show_preedit)
caps |= IBus.Capabilite.PREEDIT_TEXT;
if (this._currentFocus)
caps |= IBus.Capabilite.FOCUS | IBus.Capabilite.SURROUNDING_TEXT;
else
caps |= IBus.Capabilite.PREEDIT_TEXT | IBus.Capabilite.AUXILIARY_TEXT | IBus.Capabilite.LOOKUP_TABLE | IBus.Capabilite.PROPERTY;
if (this._context)
this._context.set_capabilities(caps);
@ -47,39 +54,23 @@ class InputMethod extends Clutter.InputMethod {
}
_onConnected() {
this._cancellable = new Gio.Cancellable();
this._ibus.create_input_context_async('gnome-shell', -1,
this._cancellable, this._setContext.bind(this));
this._ibus.create_input_context_async ('gnome-shell', -1, null,
this._setContext.bind(this));
}
_setContext(bus, res) {
try {
this._context = this._ibus.create_input_context_async_finish(res);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
logError(e);
this._clear();
}
return;
}
this._context = this._ibus.create_input_context_async_finish(res);
this._context.connect('commit-text', this._onCommitText.bind(this));
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
this._context.connect('show-preedit-text', this._onShowPreeditText.bind(this));
this._context.connect('hide-preedit-text', this._onHidePreeditText.bind(this));
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
this._context.connect('destroy', this._clear.bind(this));
this._updateCapabilities();
}
_clear() {
if (this._cancellable) {
this._cancellable.cancel();
this._cancellable = null;
}
this._context = null;
this._hints = 0;
this._purpose = 0;
@ -93,15 +84,15 @@ class InputMethod extends Clutter.InputMethod {
this.emit('request-surrounding');
}
_onCommitText(_context, text) {
_onCommitText(context, text) {
this.commit(text.get_text());
}
_onDeleteSurroundingText() {
_onDeleteSurroundingText(context) {
this.delete_surrounding();
}
_onUpdatePreeditText(_context, text, pos, visible) {
_onUpdatePreeditText(context, text, pos, visible) {
if (text == null)
return;
@ -117,19 +108,19 @@ class InputMethod extends Clutter.InputMethod {
this._preeditVisible = visible;
}
_onShowPreeditText() {
_onShowPreeditText(context) {
this._preeditVisible = true;
this.set_preedit_text(this._preeditStr, this._preeditPos);
}
_onHidePreeditText() {
_onHidePreeditText(context) {
this.set_preedit_text(null, this._preeditPos);
this._preeditVisible = false;
}
_onForwardKeyEvent(_context, keyval, keycode, state) {
_onForwardKeyEvent(context, keyval, keycode, state) {
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
state &= ~IBus.ModifierType.RELEASE_MASK;
state &= ~(IBus.ModifierType.RELEASE_MASK);
let curEvent = Clutter.get_current_event();
let time;
@ -145,6 +136,7 @@ class InputMethod extends Clutter.InputMethod {
this._currentFocus = focus;
if (this._context) {
this._context.focus_in();
this._updateCapabilities();
this._emitRequestSurrounding();
}
@ -156,8 +148,10 @@ class InputMethod extends Clutter.InputMethod {
vfunc_focus_out() {
this._currentFocus = null;
if (this._context)
if (this._context) {
this._context.focus_out();
this._updateCapabilities();
}
if (this._preeditStr) {
// Unset any preedit text
@ -260,22 +254,17 @@ class InputMethod extends Clutter.InputMethod {
if (event.type() == Clutter.EventType.KEY_RELEASE)
state |= IBus.ModifierType.RELEASE_MASK;
this._context.process_key_event_async(
event.get_key_symbol(),
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
state, -1, this._cancellable,
(context, res) => {
if (context != this._context)
return;
try {
let retval = context.process_key_event_async_finish(res);
this.notify_key_event(event, retval);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
log(`Error processing key on IM: ${e.message}`);
}
});
this._context.process_key_event_async(event.get_key_symbol(),
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
state, -1, null,
(context, res) => {
try {
let retval = context.process_key_event_async_finish(res);
this.notify_key_event(event, retval);
} catch (e) {
log(`Error processing key on IM: ${e.message}`);
}
});
return true;
}
});

View File

@ -1,4 +1,3 @@
/* exported IntrospectService */
const { Gio, GLib, Meta, Shell } = imports.gi;
const INTROSPECT_SCHEMA = 'org.gnome.shell';
@ -40,15 +39,6 @@ var IntrospectService = class {
});
this._syncRunningApplications();
this._whitelistMap = new Map();
APP_WHITELIST.forEach(appName => {
Gio.DBus.watch_name(Gio.BusType.SESSION,
appName,
Gio.BusNameWatcherFlags.NONE,
(conn, name, owner) => this._whitelistMap.set(name, owner),
(conn, name) => this._whitelistMap.delete(name));
});
}
_isStandaloneApp(app) {
@ -60,7 +50,7 @@ var IntrospectService = class {
}
_isSenderWhitelisted(sender) {
return [...this._whitelistMap.values()].includes(sender);
return APP_WHITELIST.includes(sender);
}
_getSandboxedAppId(app) {
@ -79,7 +69,7 @@ var IntrospectService = class {
for (let app of apps) {
let appInfo = {};
let isAppActive = focusedApp == app;
let isAppActive = (focusedApp == app);
if (!this._isStandaloneApp(app))
continue;
@ -113,10 +103,10 @@ var IntrospectService = class {
return false;
let type = window.get_window_type();
return type == Meta.WindowType.NORMAL ||
return (type == Meta.WindowType.NORMAL ||
type == Meta.WindowType.DIALOG ||
type == Meta.WindowType.MODAL_DIALOG ||
type == Meta.WindowType.UTILITY;
type == Meta.WindowType.UTILITY);
}
GetRunningApplicationsAsync(params, invocation) {
@ -136,8 +126,7 @@ var IntrospectService = class {
let apps = this._appSystem.get_running();
let windowsList = {};
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
if (!this._isIntrospectEnabled()) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
@ -161,9 +150,9 @@ var IntrospectService = class {
'app-id': GLib.Variant.new('s', app.get_id()),
'client-type': GLib.Variant.new('u', window.get_client_type()),
'is-hidden': GLib.Variant.new('b', window.is_hidden()),
'has-focus': GLib.Variant.new('b', window == focusWindow),
'has-focus': GLib.Variant.new('b', (window == focusWindow)),
'width': GLib.Variant.new('u', frameRect.width),
'height': GLib.Variant.new('u', frameRect.height),
'height': GLib.Variant.new('u', frameRect.height)
};
// These properties may not be available for all windows:
@ -173,10 +162,9 @@ var IntrospectService = class {
if (wmClass != null)
windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
if (sandboxedAppId != null) {
if (sandboxedAppId != null)
windowsList[windowId]['sandboxed-app-id'] =
GLib.Variant.new('s', sandboxedAppId);
}
}
}
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));

View File

@ -1,5 +1,4 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* exported getCompletions, getCommonPrefix, getDeclaredConstants */
// Returns a list of potential completions for text. Completions either
// follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo)
@ -9,10 +8,11 @@
// This function is likely the one you want to call from external modules
function getCompletions(text, commandHeader, globalCompletionList) {
let methods = [];
let expr_, base;
let expr, base;
let attrHead = '';
if (globalCompletionList == null)
if (globalCompletionList == null) {
globalCompletionList = [];
}
let offset = getExpressionOffset(text, text.length - 1);
if (offset >= 0) {
@ -21,7 +21,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
// Look for expressions like "Main.panel.foo" and match Main.panel and foo
let matches = text.match(/(.*)\.(.*)/);
if (matches) {
[expr_, base, attrHead] = matches;
[expr, base, attrHead] = matches;
methods = getPropertyNamesFromExpression(base, commandHeader).filter(
attr => attr.slice(0, attrHead.length) == attrHead
@ -32,7 +32,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
// not proceeded by a dot and match them against global constants
matches = text.match(/^(\w*)$/);
if (text == '' || matches) {
[expr_, attrHead] = matches;
[expr, attrHead] = matches;
methods = globalCompletionList.filter(
attr => attr.slice(0, attrHead.length) == attrHead
);
@ -58,8 +58,9 @@ function isStopChar(c) {
function findMatchingQuote(expr, offset) {
let quoteChar = expr.charAt(offset);
for (let i = offset - 1; i >= 0; --i) {
if (expr.charAt(i) == quoteChar && expr.charAt(i - 1) != '\\')
if (expr.charAt(i) == quoteChar && expr.charAt(i - 1) != '\\') {
return i;
}
}
return -1;
}
@ -67,8 +68,9 @@ function findMatchingQuote(expr, offset) {
// Given the ending position of a regex, find where it starts
function findMatchingSlash(expr, offset) {
for (let i = offset - 1; i >= 0; --i) {
if (expr.charAt(i) == '/' && expr.charAt(i - 1) != '\\')
if (expr.charAt(i) == '/' && expr.charAt(i - 1) != '\\') {
return i;
}
}
return -1;
}
@ -79,30 +81,31 @@ function findMatchingSlash(expr, offset) {
// findMatchingBrace("[(])", 3) returns 1.
function findMatchingBrace(expr, offset) {
let closeBrace = expr.charAt(offset);
let openBrace = { ')': '(', ']': '[' }[closeBrace];
let openBrace = ({ ')': '(', ']': '[' })[closeBrace];
return findTheBrace(expr, offset - 1, openBrace, closeBrace);
}
function findTheBrace(expr, offset) {
if (offset < 0) {
return -1;
}
function findTheBrace(expr, offset, ...braces) {
let [openBrace, closeBrace] = braces;
if (expr.charAt(offset) == openBrace) {
return offset;
}
if (expr.charAt(offset).match(/['"]/)) {
return findTheBrace(expr, findMatchingQuote(expr, offset) - 1);
}
if (expr.charAt(offset) == '/') {
return findTheBrace(expr, findMatchingSlash(expr, offset) - 1);
}
if (expr.charAt(offset) == closeBrace) {
return findTheBrace(expr, findTheBrace(expr, offset - 1) - 1);
}
if (offset < 0)
return -1;
return findTheBrace(expr, offset - 1);
if (expr.charAt(offset) == openBrace)
return offset;
}
if (expr.charAt(offset).match(/['"]/))
return findTheBrace(expr, findMatchingQuote(expr, offset) - 1, ...braces);
if (expr.charAt(offset) == '/')
return findTheBrace(expr, findMatchingSlash(expr, offset) - 1, ...braces);
if (expr.charAt(offset) == closeBrace)
return findTheBrace(expr, findTheBrace(expr, offset - 1, ...braces) - 1, ...braces);
return findTheBrace(expr, offset - 1, ...braces);
return findTheBrace(expr, offset - 1);
}
// Walk expr backwards from offset looking for the beginning of an
@ -114,11 +117,13 @@ function getExpressionOffset(expr, offset) {
while (offset >= 0) {
let currChar = expr.charAt(offset);
if (isStopChar(currChar))
if (isStopChar(currChar)) {
return offset + 1;
}
if (currChar.match(/[)\]]/))
if (currChar.match(/[)\]]/)) {
offset = findMatchingBrace(expr, offset);
}
--offset;
}
@ -135,10 +140,10 @@ function isValidPropertyName(w) {
// To get all properties (enumerable and not), we need to walk
// the prototype chain ourselves
function getAllProps(obj) {
if (obj === null || obj === undefined)
if (obj === null || obj === undefined) {
return [];
return Object.getOwnPropertyNames(obj).concat(getAllProps(Object.getPrototypeOf(obj)));
}
return Object.getOwnPropertyNames(obj).concat( getAllProps(Object.getPrototypeOf(obj)) );
}
// Given a string _expr_, returns all methods
@ -162,11 +167,11 @@ function getPropertyNamesFromExpression(expr, commandHeader = '') {
if (typeof obj === 'object') {
let allProps = getAllProps(obj);
// Get only things we are allowed to complete following a '.'
allProps = allProps.filter(isValidPropertyName);
allProps = allProps.filter( isValidPropertyName );
// Make sure propsUnique contains one key for every
// property so we end up with a unique list of properties
allProps.map(p => (propsUnique[p] = null));
allProps.map(p => propsUnique[p] = null);
}
return Object.keys(propsUnique).sort();
}
@ -183,26 +188,24 @@ function getCommonPrefix(words) {
return word;
}
// Remove any blocks that are quoted or are in a regex
function removeLiterals(str) {
if (str.length == 0)
return '';
let currChar = str.charAt(str.length - 1);
if (currChar == '"' || currChar == '\'') {
return removeLiterals(
str.slice(0, findMatchingQuote(str, str.length - 1)));
} else if (currChar == '/') {
return removeLiterals(
str.slice(0, findMatchingSlash(str, str.length - 1)));
}
return removeLiterals(str.slice(0, str.length - 1)) + currChar;
}
// Returns true if there is reason to think that eval(str)
// will modify the global scope
function isUnsafeExpression(str) {
// Remove any blocks that are quoted or are in a regex
function removeLiterals(str) {
if (str.length == 0) {
return '';
}
let currChar = str.charAt(str.length - 1);
if (currChar == '"' || currChar == '\'') {
return removeLiterals(str.slice(0, findMatchingQuote(str, str.length - 1)));
} else if (currChar == '/') {
return removeLiterals(str.slice(0, findMatchingSlash(str, str.length - 1)));
}
return removeLiterals(str.slice(0, str.length - 1)) + currChar;
}
// Check for any sort of assignment
// The strategy used is dumb: remove any quotes
@ -210,10 +213,10 @@ function isUnsafeExpression(str) {
// If there is, it might be an unsafe assignment.
let prunedStr = removeLiterals(str);
prunedStr = prunedStr.replace(/[=!]==/g, ''); // replace === and !== with nothing
prunedStr = prunedStr.replace(/[=<>!]=/g, ''); // replace ==, <=, >=, != with nothing
prunedStr = prunedStr.replace(/[=!]==/g, ''); //replace === and !== with nothing
prunedStr = prunedStr.replace(/[=<>!]=/g, ''); //replace ==, <=, >=, != with nothing
if (prunedStr.match(/[=]/)) {
if (prunedStr.match(/=/)) {
return true;
} else if (prunedStr.match(/;/)) {
// If we contain a semicolon not inside of a quote/regex, assume we're unsafe as well
@ -227,10 +230,10 @@ function isUnsafeExpression(str) {
function getDeclaredConstants(str) {
let ret = [];
str.split(';').forEach(s => {
let base_, keyword;
let base, keyword;
let match = s.match(/const\s+(\w+)\s*=/);
if (match) {
[base_, keyword] = match;
[base, keyword] = match;
ret.push(keyword);
}
});

View File

@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported getKeyboardManager, holdKeyboard, releaseKeyboard */
const { GLib, GnomeDesktop, Meta } = imports.gi;

View File

@ -1,5 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported canLock, getLoginManager, registerSessionWithGDM */
const { GLib, Gio } = imports.gi;
const Signals = imports.signals;
@ -74,9 +73,8 @@ function registerSessionWithGDM() {
let _loginManager = null;
/**
* getLoginManager:
* LoginManager:
* An abstraction over systemd/logind and ConsoleKit.
* @returns {object} - the LoginManager singleton
*
*/
function getLoginManager() {
@ -104,7 +102,7 @@ var LoginManagerSystemd = class {
getCurrentSessionProxy(callback) {
if (this._currentSession) {
callback(this._currentSession);
callback (this._currentSession);
return;
}
@ -118,7 +116,7 @@ var LoginManagerSystemd = class {
} else {
log('Failed to find "Display" session; are we the greeter?');
for ([session, objectPath] of this._userProxy.Sessions) {
for (let [session, objectPath] of this._userProxy.Sessions) {
let sessionProxy = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
objectPath);
@ -184,9 +182,9 @@ var LoginManagerSystemd = class {
(proxy, result) => {
let fd = -1;
try {
let [outVariant_, fdList] = proxy.call_with_unix_fd_list_finish(result);
let [outVariant, fdList] = proxy.call_with_unix_fd_list_finish(result);
fd = fdList.steal_fds()[0];
callback(new Gio.UnixInputStream({ fd }));
callback(new Gio.UnixInputStream({ fd: fd }));
} catch (e) {
logError(e, "Error getting systemd inhibitor");
callback(null);
@ -201,7 +199,7 @@ var LoginManagerSystemd = class {
Signals.addSignalMethods(LoginManagerSystemd.prototype);
var LoginManagerDummy = class {
getCurrentSessionProxy(_callback) {
getCurrentSessionProxy(callback) {
// we could return a DummySession object that fakes whatever callers
// expect (at the time of writing: connect() and connectSignal()
// methods), but just never calling the callback should be safer

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ModemBase, ModemGsm, ModemCdma, BroadbandModem */
const { Gio, GObject, NM, NMA } = imports.gi;
const { Gio, NMA } = imports.gi;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;
@ -84,9 +84,9 @@ function _findProviderForSid(sid) {
}
// ----------------------------------------------------- //
// Support for the old ModemManager interface (MM < 0.7) //
// ----------------------------------------------------- //
//------------------------------------------------------------------------------
// Support for the old ModemManager interface (MM < 0.7)
//------------------------------------------------------------------------------
// The following are not the complete interfaces, just the methods we need
@ -98,46 +98,21 @@ const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInter
const ModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager.Modem.Cdma');
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
var ModemBase = GObject.registerClass({
GTypeFlags: GObject.TypeFlags.ABSTRACT,
Properties: {
'operator-name': GObject.ParamSpec.string(
'operator-name', 'operator-name', 'operator-name',
GObject.ParamFlags.READABLE,
null),
'signal-quality': GObject.ParamSpec.int(
'signal-quality', 'signal-quality', 'signal-quality',
GObject.ParamFlags.READABLE,
0, 100, 0),
},
}, class ModemBase extends GObject.Object {
_setOperatorName(operatorName) {
if (this.operator_name == operatorName)
return;
this.operator_name = operatorName;
this.notify('operator-name');
}
_setSignalQuality(signalQuality) {
if (this.signal_quality == signalQuality)
return;
this.signal_quality = signalQuality;
this.notify('signal-quality');
}
});
var ModemGsm = GObject.registerClass(
class ModemGsm extends ModemBase {
_init(path) {
super._init();
var ModemGsm = class {
constructor(path) {
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
this.operator_name = null;
// Code is duplicated because the function have different signatures
this._proxy.connectSignal('SignalQuality', (proxy, sender, [quality]) => {
this._setSignalQuality(quality);
this.signal_quality = quality;
this.emit('notify::signal-quality');
});
this._proxy.connectSignal('RegistrationInfo', (proxy, sender, [_status, code, name]) => {
this._setOperatorName(_findProviderForMccMnc(name, code));
this._proxy.connectSignal('RegistrationInfo', (proxy, sender, [status, code, name]) => {
this.operator_name = _findProviderForMccMnc(name, code);
this.emit('notify::operator-name');
});
this._proxy.GetRegistrationInfoRemote(([result], err) => {
if (err) {
@ -145,29 +120,33 @@ class ModemGsm extends ModemBase {
return;
}
let [status_, code, name] = result;
this._setOperatorName(_findProviderForMccMnc(name, code));
let [status, code, name] = result;
this.operator_name = _findProviderForMccMnc(name, code);
this.emit('notify::operator-name');
});
this._proxy.GetSignalQualityRemote((result, err) => {
if (err) {
// it will return an error if the device is not connected
this._setSignalQuality(0);
this.signal_quality = 0;
} else {
let [quality] = result;
this._setSignalQuality(quality);
this.signal_quality = quality;
}
this.emit('notify::signal-quality');
});
}
});
};
Signals.addSignalMethods(ModemGsm.prototype);
var ModemCdma = GObject.registerClass(
class ModemCdma extends ModemBase {
_init(path) {
super._init();
var ModemCdma = class {
constructor(path) {
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
this.operator_name = null;
this._proxy.connectSignal('SignalQuality', (proxy, sender, params) => {
this._setSignalQuality(params[0]);
this.signal_quality = params[0];
this.emit('notify::signal-quality');
// receiving this signal means the device got activated
// and we can finally call GetServingSystem
@ -177,11 +156,12 @@ class ModemCdma extends ModemBase {
this._proxy.GetSignalQualityRemote((result, err) => {
if (err) {
// it will return an error if the device is not connected
this._setSignalQuality(0);
this.signal_quality = 0;
} else {
let [quality] = result;
this._setSignalQuality(quality);
this.signal_quality = quality;
}
this.emit('notify::signal-quality');
});
}
@ -189,19 +169,22 @@ class ModemCdma extends ModemBase {
this._proxy.GetServingSystemRemote(([result], err) => {
if (err) {
// it will return an error if the device is not connected
this._setOperatorName(null);
this.operator_name = null;
} else {
let [bandClass_, band_, sid] = result;
this._setOperatorName(_findProviderForSid(sid));
let [bandClass, band, sid] = result;
this.operator_name = _findProviderForSid(sid);
}
this.emit('notify::operator-name');
});
}
});
};
Signals.addSignalMethods(ModemCdma.prototype);
// ------------------------------------------------------- //
// Support for the new ModemManager1 interface (MM >= 0.7) //
// ------------------------------------------------------- //
//------------------------------------------------------------------------------
// Support for the new ModemManager1 interface (MM >= 0.7)
//------------------------------------------------------------------------------
const BroadbandModemInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem');
const BroadbandModemProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemInterface);
@ -212,20 +195,12 @@ const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gp
const BroadbandModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem.ModemCdma');
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
var BroadbandModem = GObject.registerClass({
Properties: {
'capabilities': GObject.ParamSpec.flags(
'capabilities', 'capabilities', 'capabilities',
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
NM.DeviceModemCapabilities.$gtype,
NM.DeviceModemCapabilities.NONE),
},
}, class BroadbandModem extends ModemBase {
_init(path, capabilities) {
super._init({ capabilities });
this._proxy = new BroadbandModemProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
var BroadbandModem = class {
constructor(path, capabilities) {
this._proxy = new BroadbandModemProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_3gpp = new BroadbandModem3gppProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_cdma = new BroadbandModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._capabilities = capabilities;
this._proxy.connect('g-properties-changed', (proxy, properties) => {
if ('SignalQuality' in properties.deep_unpack())
@ -249,8 +224,9 @@ var BroadbandModem = GObject.registerClass({
}
_reloadSignalQuality() {
let [quality, recent_] = this.SignalQuality;
this._setSignalQuality(quality);
let [quality, recent] = this._proxy.SignalQuality;
this.signal_quality = quality;
this.emit('notify::signal-quality');
}
_reloadOperatorName() {
@ -264,7 +240,8 @@ var BroadbandModem = GObject.registerClass({
newName += this.operator_name_cdma;
}
this._setOperatorName(newName);
this.operator_name = newName;
this.emit('notify::operator-name');
}
_reload3gppOperatorName() {
@ -279,4 +256,5 @@ var BroadbandModem = GObject.registerClass({
this.operator_name_cdma = _findProviderForSid(sid);
this._reloadOperatorName();
}
});
};
Signals.addSignalMethods(BroadbandModem.prototype);

View File

@ -192,8 +192,9 @@ var ObjectManager = class {
_onNameAppeared() {
this._managerProxy.GetManagedObjectsRemote((result, error) => {
if (!result) {
if (error)
if (error) {
logError(error, `could not get remote objects for service ${this._serviceName} path ${this._managerPath}`);
}
this._tryToCompleteLoad();
return;

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