Compare commits

..

9 Commits

Author SHA1 Message Date
Alexander Mikhaylenko
c3aa25e4e3 workspaceAnimation: Support multiple screens
Currently, there's one animation for the whole canvas. While it looks fine
with just one screen, it causes windows to move between screens when
switching workspaces. Instead, have a separate animation on each screen,
and sync their progress so that at any given time the progress "fraction"
is the same between all screens. Clip all animations to their screens so
that the windows don't leak to other screens.

If a window is placed between every screen, can end up in multiple
animations, in that case each part is still animated separately.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1213

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
cfd792fe86 workspaceAnimation: Group sticky windows and moving window
Since the transitions consists of window clones now, all the clones appear
above sticky windows. Clone sticky windows as well, and treat them same as
moving window instead.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
7bdcc503cb workspaceAnimation: Use a workspace strip
Currently, the workspace swipe transition only has one workspace in each
direction. This works until you try to do multiple swipes in quick
succession. The second swipe would continue the existing transition, which
only has 2 or 3 workspaces in it, and will hit a wall.

To prevent this, take all workspaces and arrange them into a column or row,
depending on the layout, and use that as a transition.

For the transition that happens when focusing a window on another workspace
(for example, via Alt+Tab), still use only two workspaces instead of all of
them.

Since we don't support layouts other than single rows/columns anymore,
diagonal transitions aren't supported anymore, and will be shown as
horizontal or vertical instead.

Since nw alt-tab and gesture transitions are different, don't allow to do
both at once, that is, disable swipe tracker when a programmatic transition
is going. This will also conveniently cancel a gesture transition if a
programmatic one is initiated while a gesture is in progress.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2612

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
856a4d27e0 workspaceAnimation: Use window clones
Instead of reparenting windows, clone them. This will allow to properly
support multi-monitor setups in subsequent commits.

Block window mapping animation while the animation is running to prevent
new windows appearing during the animation from being visible at the same
time as their clones.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/929

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
9d1fe27221 workspaceAnimation: Add a background
In future we will need to use window clones to better support multiple
monitors. To avoid having to hide every window, show wallpapers behind
the workspace transition: one per monitor.

Put the wallpaper into a separate class right away, later it will be
useful to make the animation per-monitor.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
407abeb178 workspaceAnimation: Add to uiGroup insead of window_group
This will allow to hide window group completely in the following commits.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
95fc8021d2 workspaceAnimation: Extract WorkspaceGroup
Simplify the code a bit. The workspace group is relatively self-contained,
so split it from the general animation. Reimplement _syncStacking().

This will help a lot later, with workspace strip and multi-monitor support.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
060cbb65f6 workspaceAnimation: Stop depending on shellwm
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:46 +00:00
Alexander Mikhaylenko
1759e27ef7 workspaceAnimation: Split from WindowManager
It's already too complex, and will get more complex in future, split it
out. Update the code style.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326
2020-07-21 12:51:45 +00:00
419 changed files with 41357 additions and 70906 deletions

View File

@ -1,8 +1,3 @@
extends:
- ./lint/eslintrc-gjs.yml
- ./lint/eslintrc-shell.yml
overrides:
- files:
- js/ui/init.js
parserOptions:
sourceType: module

View File

@ -1,288 +1,133 @@
include:
- remote: 'https://gitlab.gnome.org/GNOME/citemplates/raw/HEAD/flatpak/flatpak_ci_initiative.yml'
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/fedora.yml'
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/ci-fairy.yml'
include: 'https://gitlab.gnome.org/GNOME/citemplates/raw/master/flatpak/flatpak_ci_initiative.yml'
stages:
- pre_review
- prep
- review
- build
- test
- analyze
- deploy
default:
# Cancel jobs if newer commits are pushed to the branch
interruptible: true
# Auto-retry jobs in case of infra failures
retry:
max: 1
when:
- 'runner_system_failure'
- 'stuck_or_timeout_failure'
- 'scheduler_failure'
- 'api_failure'
- review
- build
- test
- deploy
variables:
FDO_UPSTREAM_REPO: GNOME/gnome-shell
BUNDLE: "extensions-git.flatpak"
JS_LOG: "js-report.txt"
LINT_LOG: "eslint-report.xml"
LINT_MR_LOG: "eslint-mr-report.xml"
BUNDLE: "extensions-git.flatpak"
JS_LOG: "js-report.txt"
POT_LOG: "pot-update.txt"
image: registry.gitlab.gnome.org/gnome/mutter/fedora/34:x86_64-2021-09-04.1
workflow:
rules:
- if: '$CI_MERGE_REQUEST_IID'
- if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH'
.pipeline_guard: &pipeline_guard
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
- when: 'manual'
.gnome-shell.fedora:34:
variables:
FDO_DISTRIBUTION_VERSION: 34
FDO_DISTRIBUTION_TAG: '2021-08-12.0'
FDO_DISTRIBUTION_PACKAGES: >
findutils mozjs78-devel nodejs npm meson
pkgconfig(gio-2.0) pkgconfig(gio-unix-2.0)
pkgconfig(gnome-autoar-0) pkgconfig(json-glib-1.0)
FDO_DISTRIBUTION_EXEC: |
# For static analysis with eslint
npm install -g eslint eslint-plugin-jsdoc &&
dnf group install -y 'Development Tools' \
'C Development Tools and Libraries' &&
./.gitlab-ci/install-meson-project.sh \
-Dman=false \
https://gitlab.gnome.org/GNOME/gnome-shell.git \
3.38.0 \
subprojects/extensions-tool/ \
./generate-translations.sh &&
dnf clean all
.only_default: &only_default
only:
- branches
- tags
- merge_requests
check_commit_log:
extends:
- .fdo.ci-fairy
stage: pre_review
variables:
GIT_DEPTH: "100"
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ;
else
echo "Not a merge request" ;
fi
<<: *pipeline_guard
artifacts:
expire_in: 1 week
paths:
- commit-message-junit-report.xml
reports:
junit: commit-message-junit-report.xml
check-merge-request:
extends:
- .fdo.ci-fairy
stage: pre_review
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ;
else
echo "Not a merge request" ;
fi
<<: *pipeline_guard
artifacts:
expire_in: 1 week
paths:
- check-merge-request-report.xml
reports:
junit: check-merge-request-report.xml
build-fedora-container:
extends:
- .fdo.container-build@fedora@x86_64
- .gnome-shell.fedora:34
stage: prep
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
stage: review
variables:
GIT_DEPTH: "100"
script:
- ./.gitlab-ci/check-commit-log.sh
only:
- merge_requests
js_check:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell.fedora:34
stage: review
script:
- find js -name '*.js' $(printf "! -wholename %s " $(cat .jscheckignore)) -exec js78 -c '{}' ';' 2>&1 | tee $JS_LOG
- (! grep -q . $JS_LOG)
artifacts:
paths:
- ${JS_LOG}
when: on_failure
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
stage: review
script:
- find js -name '*.js' -exec js68 -c -s '{}' ';' 2>&1 | tee $JS_LOG
- (! grep -q . $JS_LOG)
<<: *only_default
artifacts:
paths:
- ${JS_LOG}
when: on_failure
eslint:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell.fedora:34
stage: review
script:
- export NODE_PATH=$(npm root -g)
- ./.gitlab-ci/run-eslint --output-file ${LINT_LOG} --format junit
artifacts:
reports:
junit: ${LINT_LOG}
when: always
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
stage: review
script:
- ./.gitlab-ci/run-eslint.sh
<<: *only_default
artifacts:
paths:
- reports
when: always
eslint_mr:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell.fedora:34
stage: review
script:
- export NODE_PATH=$(npm root -g)
- ./.gitlab-ci/run-eslint --output-file ${LINT_MR_LOG} --format junit
--remote ${CI_MERGE_REQUEST_PROJECT_URL}.git
--branch ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
only:
- merge_requests
artifacts:
reports:
junit: ${LINT_MR_LOG}
when: always
potfile_c_check:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell.fedora:34
stage: review
script:
- ./.gitlab-ci/check-potfiles.sh
potfile_js_check:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell.fedora:34
stage: review
script:
- js78 -m .gitlab-ci/check-potfiles.js
potfile_check:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
stage: review
script:
- ./.gitlab-ci/check-potfiles.sh
<<: *only_default
no_template_check:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell.fedora:34
stage: review
script:
- ./.gitlab-ci/check-template-strings.sh
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
stage: review
script:
- ./.gitlab-ci/check-template-strings.sh
<<: *only_default
build:
stage: build
needs: ["check_commit_log"]
before_script:
- .gitlab-ci/checkout-mutter.sh
- meson mutter mutter/build --prefix=/usr
- meson install -C mutter/build
script:
- meson . build -Dbuildtype=debugoptimized -Dman=false --werror
- meson compile -C build
- meson install -C build
artifacts:
expire_in: 1 day
paths:
- mutter
- build
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
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
- ninja -C build
- ninja -C build install
<<: *only_default
artifacts:
expire_in: 1 day
paths:
- mutter
- build
test:
stage: test
needs: ["build"]
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
NO_AT_BRIDGE: "1"
before_script:
- meson install -C mutter/build
script:
- dbus-run-session -- xvfb-run meson test -C build --no-rebuild
artifacts:
expire_in: 1 day
paths:
- build/meson-logs/testlog.txt
reports:
junit: build/meson-logs/testlog.junit.xml
when: on_failure
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
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
<<: *only_default
artifacts:
expire_in: 1 day
paths:
- build/meson-logs/testlog.txt
when: on_failure
test-coverity:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule" && $GNOME_SHELL_SCHEDULED_JOB == "coverity"'
when: always
- when: manual
needs: ["build"]
stage: analyze
allow_failure: true
before_script:
- meson install -C mutter/build
script:
- .gitlab-ci/download-coverity-tarball.sh
- CC=clang meson coverity-build -Dman=false
- ./coverity/cov-analysis-linux64-*/bin/cov-build --fs-capture-search js --dir cov-int meson compile -C coverity-build
- tar czf cov-int.tar.gz cov-int
- curl https://scan.coverity.com/builds?project=GNOME+Shell
--form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
--form description="GitLab CI build"
cache:
key: coverity-tarball
paths:
- coverity
test-pot:
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
stage: test
before_script:
- ninja -C mutter/build install
script:
# Check that pot files are generated correctly:
# https://savannah.gnu.org/bugs/?50920#comment5
- ninja -C build gnome-shell-pot 2>&1 | awk '
BEGIN { start=0; }
start==1 { print $0; }
/gnome-shell-pot/ { start=1; }
' | tee $POT_LOG
- (! grep -q . $POT_LOG)
<<: *only_default
flatpak:
stage: build
needs: ["check_commit_log"]
variables:
SUBPROJECT: "subprojects/extensions-app"
# Your manifest path
MANIFEST_PATH: "$SUBPROJECT/build-aux/flatpak/org.gnome.Extensions.json"
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
FLATPAK_MODULE: "gnome-extensions-app"
APP_ID: "org.gnome.Extensions.Devel"
extends: .flatpak
stage: build
variables:
SUBPROJECT: "subprojects/extensions-app"
# Your manifest path
MANIFEST_PATH: "$SUBPROJECT/build-aux/flatpak/org.gnome.Extensions.json"
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
FLATPAK_MODULE: "gnome-extensions-app"
APP_ID: "org.gnome.Extensions"
extends: .flatpak
<<: *only_default
nightly:
extends: '.publish_nightly'
variables:
BUNDLES: '$BUNDLE'
dist:
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
NO_AT_BRIDGE: "1"
stage: deploy
needs: ["build"]
before_script:
- meson install -C mutter/build
- mkdir -m 700 $XDG_RUNTIME_DIR
script:
- dbus-run-session xvfb-run meson dist -C build
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- "**/meson.build"
- meson/*
dist-tarball:
extends: dist
artifacts:
expose_as: 'Get tarball here'
paths:
- build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
rules:
- if: '$CI_COMMIT_TAG'

24
.gitlab-ci/Dockerfile Normal file
View File

@ -0,0 +1,24 @@
# Rebuild and push with
#
# cd .gitlab-ci/
# podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2 .
# podman push registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
#
FROM registry.fedoraproject.org/fedora:32
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(copr)' git && \
# For syntax checks with `find . -name '*.js' -exec js68 -c -s '{}' ';'`
dnf install -y findutils mozjs68-devel && \
# For static analysis with eslint
dnf install -y nodejs && \
npm install -g eslint && \
# Shameless plug for my own tooling; useful for generating zip
dnf copr enable -y fmuellner/gnome-shell-ci && \
dnf install -y gnome-extensions-tool meson && \
dnf clean all

31
.gitlab-ci/check-commit-log.sh Executable file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
echo Cannot review non-merge request
exit 1
fi
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
branch_point=$(git merge-base HEAD FETCH_HEAD)
commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA)
if [ -z "$commits" ]; then
echo Commit range empty
exit 1
fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}
for commit in $commits; do
if ! commit_message_has_url $commit; then
echo "Missing merge request or issue URL on commit $(echo $commit | cut -c -8)"
exit 1
fi
done

View File

@ -1,202 +0,0 @@
const gettextFuncs = new Set([
'_',
'N_',
'C_',
'NC_',
'dcgettext',
'dgettext',
'dngettext',
'dpgettext',
'gettext',
'ngettext',
'pgettext',
]);
function dirname(file) {
const split = file.split('/');
split.pop();
return split.join('/');
}
const scriptDir = dirname(import.meta.url);
const root = dirname(scriptDir);
const excludedFiles = new Set();
const foundFiles = new Set()
function addExcludes(filename) {
const contents = os.file.readFile(filename);
const lines = contents.split('\n')
.filter(l => l && !l.startsWith('#'));
lines.forEach(line => excludedFiles.add(line));
}
addExcludes(`${root}/po/POTFILES.in`);
addExcludes(`${root}/po/POTFILES.skip`);
function walkAst(node, func) {
func(node);
nodesToWalk(node).forEach(n => walkAst(n, func));
}
function findGettextCalls(node) {
switch(node.type) {
case 'CallExpression':
if (node.callee.type === 'Identifier' &&
gettextFuncs.has(node.callee.name))
throw new Error();
if (node.callee.type === 'MemberExpression' &&
node.callee.object.type === 'Identifier' &&
node.callee.object.name === 'Gettext' &&
node.callee.property.type === 'Identifier' &&
gettextFuncs.has(node.callee.property.name))
throw new Error();
break;
}
return true;
}
function nodesToWalk(node) {
switch(node.type) {
case 'ArrayPattern':
case 'BreakStatement':
case 'CallSiteObject': // i.e. strings passed to template
case 'ContinueStatement':
case 'DebuggerStatement':
case 'EmptyStatement':
case 'Identifier':
case 'Literal':
case 'MetaProperty': // i.e. new.target
case 'Super':
case 'ThisExpression':
return [];
case 'ArrowFunctionExpression':
case 'FunctionDeclaration':
case 'FunctionExpression':
return [...node.defaults, node.body].filter(n => !!n);
case 'AssignmentExpression':
case 'BinaryExpression':
case 'ComprehensionBlock':
case 'LogicalExpression':
return [node.left, node.right];
case 'ArrayExpression':
case 'TemplateLiteral':
return node.elements.filter(n => !!n);
case 'BlockStatement':
case 'Program':
return node.body;
case 'CallExpression':
case 'NewExpression':
case 'TaggedTemplate':
return [node.callee, ...node.arguments];
case 'CatchClause':
return [node.body, node.guard].filter(n => !!n);
case 'ClassExpression':
case 'ClassStatement':
return [...node.body, node.superClass].filter(n => !!n);
case 'ClassMethod':
return [node.name, node.body];
case 'ComprehensionExpression':
case 'GeneratorExpression':
return [node.body, ...node.blocks, node.filter].filter(n => !!n);
case 'ComprehensionIf':
return [node.test];
case 'ComputedName':
return [node.name];
case 'ConditionalExpression':
case 'IfStatement':
return [node.test, node.consequent, node.alternate].filter(n => !!n);
case 'DoWhileStatement':
case 'WhileStatement':
return [node.body, node.test];
case 'ExportDeclaration':
return [node.declaration, node.source].filter(n => !!n);
case 'ImportDeclaration':
return [...node.specifiers, node.source];
case 'LetStatement':
return [...node.head, node.body];
case 'ExpressionStatement':
return [node.expression];
case 'ForInStatement':
case 'ForOfStatement':
return [node.body, node.left, node.right];
case 'ForStatement':
return [node.init, node.test, node.update, node.body].filter(n => !!n);
case 'LabeledStatement':
return [node.body];
case 'MemberExpression':
return [node.object, node.property];
case 'ObjectExpression':
case 'ObjectPattern':
return node.properties;
case 'OptionalExpression':
return [node.expression];
case 'OptionalMemberExpression':
return [node.object, node.property];
case 'Property':
case 'PrototypeMutation':
return [node.value];
case 'ReturnStatement':
case 'ThrowStatement':
case 'UnaryExpression':
case 'UpdateExpression':
case 'YieldExpression':
return node.argument ? [node.argument] : [];
case 'SequenceExpression':
return node.expressions;
case 'SpreadExpression':
return [node.expression];
case 'SwitchCase':
return [node.test, ...node.consequent].filter(n => !!n);
case 'SwitchStatement':
return [node.discriminant, ...node.cases];
case 'TryStatement':
return [node.block, node.handler, node.finalizer].filter(n => !!n);
case 'VariableDeclaration':
return node.declarations;
case 'VariableDeclarator':
return node.init ? [node.init] : [];
case 'WithStatement':
return [node.object, node.body];
default:
print(`Ignoring ${node.type}, you should probably fix this in the script`);
}
}
function walkDir(dir) {
os.file.listDir(dir).forEach(child => {
if (child.startsWith('.'))
return;
const path = os.path.join(dir, child);
const relativePath = path.replace(`${root}/`, '');
if (excludedFiles.has(relativePath))
return;
if (!child.endsWith('.js')) {
try {
walkDir(path);
} catch (e) {
// not a directory
}
return;
}
try {
const script = os.file.readFile(path);
const ast = Reflect.parse(script);
walkAst(ast, findGettextCalls);
} catch (e) {
foundFiles.add(path);
}
});
}
walkDir(root);
if (foundFiles.size === 0)
quit(0);
print('The following files are missing from po/POTFILES.in:')
foundFiles.forEach(f => print(` ${f}`));
quit(1);

View File

@ -1,9 +1,10 @@
#!/usr/bin/env bash
srcdirs="src subprojects/extensions-tool"
srcdirs="js src subprojects/extensions-tool"
globs=('*.js' '*.c')
# find source files that contain gettext keywords
files=$(grep -lR --include='*.c' '\(gettext\|[^I_)]_\)(' $srcdirs)
files=$(grep -lR ${globs[@]/#/--include=} '\(gettext\|[^I_)]_\)(' $srcdirs)
# filter out excluded files
if [ -f po/POTFILES.skip ]; then

View File

@ -1,19 +1,11 @@
#!/usr/bin/bash
fetch() {
local remote=$1
local ref=$2
git fetch --quiet --depth=1 $remote $ref 2>/dev/null
}
mutter_target=
echo -n Cloning into mutter ...
if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/mutter.git; then
echo \ done
else
echo \ failed
git clone https://gitlab.gnome.org/GNOME/mutter.git
if [ $? -ne 0 ]; then
echo Checkout failed
exit 1
fi
@ -23,33 +15,19 @@ if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//gnome-shell/mutter}
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
echo -n Looking for $merge_request_branch on remote ...
if fetch $merge_request_remote $merge_request_branch; then
echo \ found
echo Looking for $merge_request_branch on remote ...
if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
mutter_target=FETCH_HEAD
else
echo \ not found
echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ...
if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then
echo \ found
mutter_target=FETCH_HEAD
else
echo \ not found
fi
fi
fi
if [ -z "$mutter_target" ]; then
echo -n Looking for $CI_COMMIT_REF_NAME on remote ...
if fetch origin $CI_COMMIT_REF_NAME; then
echo \ found
mutter_target=FETCH_HEAD
else
echo \ not found
mutter_target=HEAD
mutter_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
echo Using $mutter_target instead
fi
fi
if [ -z "$mutter_target" ]; then
mutter_target=$(git branch -r -l origin/$CI_COMMIT_REF_NAME)
mutter_target=${mutter_target:-origin/master}
echo Using $mutter_target instead
fi
git checkout -q $mutter_target

View File

@ -1,16 +0,0 @@
patterns:
deny:
- regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$'
message: Commit message must not contain a link to its own merge request
- regex: '^(st-|St)'
message: Commit message subject should not be prefixed with 'st-' or 'St', use 'st/' instead
where: subject
- regex: '^[^:]+: [a-z]'
message: "Commit message subject should be properly Capitalized. E.g. 'window: Marginalize extradicity'"
where: subject
- regex: '^\S*\.(js|c|h):'
message: Commit message subject prefix should not include .c, .h etc.
where: subject
- regex: '([^.]\.|[:,;])\s*$'
message: Commit message subject should not end with punctuation
where: subject

View File

@ -1,38 +0,0 @@
#!/usr/bin/bash
# We need a coverity token to fetch the tarball
if [ -x $COVERITY_TOKEN ]
then
echo "No coverity token. Run this job from a protected branch."
exit -1
fi
mkdir -p coverity
# Download and check MD5 first
curl https://scan.coverity.com/download/linux64 \
--data "token=$COVERITY_TOKEN&project=GNOME+Shell&md5=1" \
--output /tmp/coverity_tool.md5
diff /tmp/coverity_tool.md5 coverity/coverity_tool.md5 >/dev/null 2>&1
if [ $? -eq 0 -a -d coverity/cov-analysis* ]
then
echo "Coverity tarball is up-to-date"
exit 0
fi
# Download and extract coverity tarball
curl https://scan.coverity.com/download/linux64 \
--data "token=$COVERITY_TOKEN&project=GNOME+Shell" \
--output /tmp/coverity_tool.tgz
rm -rf ./coverity/cov-analysis*
tar zxf /tmp/coverity_tool.tgz -C coverity/
if [ $? -eq 0 ]
then
mv /tmp/coverity_tool.md5 coverity/
fi
rm /tmp/coverity_tool.tgz

View File

@ -1,34 +0,0 @@
#!/bin/bash
set -e
if [[ $# -lt 4 ]]; then
echo Usage: $0 [options] [repo-url] [commit] [subdir]
echo Options:
echo -Dkey=val
exit 1
fi
MESON_OPTIONS=()
while [[ $1 =~ ^-D ]]; do
MESON_OPTIONS+=( "$1" )
shift
done
REPO_URL="$1"
COMMIT="$2"
SUBDIR="$3"
PREPARE="$4"
REPO_DIR="$(basename ${REPO_URL%.git})"
git clone --depth 1 "$REPO_URL" -b "$COMMIT"
pushd "$REPO_DIR"
pushd "$SUBDIR"
sh -c "$PREPARE"
meson --prefix=/usr _build "${MESON_OPTIONS[@]}"
meson install -C _build
popd
popd
rm -rf "$REPO_DIR"

View File

@ -1,128 +0,0 @@
#!/usr/bin/env node
const { ESLint } = require('eslint');
const fs = require('fs');
const path = require('path');
const { spawn } = require('child_process');
function createConfig(config) {
const options = {
cache: true,
cacheLocation: `.eslintcache-${config}`,
};
if (config === 'legacy')
options.overrideConfigFile='lint/eslintrc-legacy.yml';
return new ESLint(options);
}
function git(...args) {
const git = spawn('git', args, { stdio: ['ignore', null, 'ignore'] });
git.stdout.setEncoding('utf8');
return new Promise(resolve => {
let out = '';
git.stdout.on('data', chunk => out += chunk);
git.stdout.on('end', () => resolve(out.trim()));
});
}
function createCommon(report1, report2, ignoreColumn=false) {
return report1.map(result => {
const { filePath, messages } = result;
const match =
report2.find(r => r.filePath === filePath) || { messages: [] };
const filteredMessages = messages.filter(
msg => match.messages.some(
m => m.line === msg.line && (ignoreColumn || m.column === msg.column)));
const [errorCount, warningCount] = filteredMessages.reduce(
([e, w], msg) => {
return [
e + Number(msg.severity === 2),
w + Number(msg.severity === 1)];
}, [0, 0]);
return {
filePath,
messages: filteredMessages,
errorCount,
warningCount,
};
});
}
async function getMergeRequestChanges(remote, branch) {
await git('fetch', remote, branch);
const branchPoint = await git('merge-base', 'HEAD', 'FETCH_HEAD');
const diff = await git('diff', '-U0', `${branchPoint}...HEAD`);
const report = [];
let messages = null;
for (const line of diff.split('\n')) {
if (line.startsWith('+++ b/')) {
const filePath = path.resolve(line.substring(6));
messages = filePath.endsWith('.js') ? [] : null;
if (messages)
report.push({ filePath, messages });
} else if (messages && line.startsWith('@@ ')) {
[, , changes] = line.split(' ');
[start, count] = `${changes},1`.split(',').map(i => parseInt(i));
for (let i = start; i < start + count; i++)
messages.push({ line: i });
}
}
return report;
}
function getOption(...names) {
const optIndex =
process.argv.findIndex(arg => names.includes(arg)) + 1;
if (optIndex === 0)
return undefined;
return process.argv[optIndex];
}
(async function main() {
const outputOption = getOption('--output-file', '-o');
const outputPath = outputOption ? path.resolve(outputOption) : null;
const sourceDir = path.dirname(process.argv[1]);
process.chdir(path.resolve(sourceDir, '..'));
const remote = getOption('--remote') || 'origin';
const branch = getOption('--branch', '-b');
const sources = ['js', 'subprojects/extensions-app/js'];
const regular = createConfig('regular');
const ops = [];
ops.push(regular.lintFiles(sources));
if (branch)
ops.push(getMergeRequestChanges(remote, branch));
else
ops.push(createConfig('legacy').lintFiles(sources));
const results = await Promise.all(ops);
const commonResults = createCommon(...results, branch !== undefined);
const formatter = await regular.loadFormatter(getOption('--format', '-f'));
const resultText = formatter.format(commonResults);
if (outputPath) {
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
fs.writeFileSync(outputPath, resultText);
} else {
console.log(resultText);
}
process.exitCode = commonResults.some(r => r.errorCount > 0) ? 1 : 0;
})().catch((error) => {
process.exitCode = 1;
console.error(error);
});

116
.gitlab-ci/run-eslint.sh Executable file
View File

@ -0,0 +1,116 @@
#!/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}
local cache=.eslintcache-${1,,}
# ensure output exists even if eslint doesn't report any errors
mkdir -p $(dirname $output)
touch $output
eslint -f unix --cache --cache-location $cache ${!extra_args} -o $output \
js subprojects/extensions-app/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

@ -8,7 +8,7 @@ first to ensure that you create a clear and specific issue.
<!--
Provide at least the following information:
* Your OS and version
* Affected GNOME Shell version (see https://wiki.gnome.org/Schedule for currently supported versions)
* Affected GNOME Shell version
* Does this issue appear in XOrg and/or Wayland
-->

View File

@ -1 +0,0 @@
js/ui/init.js

View File

@ -131,7 +131,7 @@ whenever possible, that is when not inheriting from GObjects.
};
```
For GObject inheritance, we use the GObject.registerClass() function provided
For GObject inheritence, we use the GObject.registerClass() function provided
by gjs.
```javascript
var MyActor = GObject.registerClass(

505
NEWS
View File

@ -1,490 +1,3 @@
41.1
====
* Fix icon updates while hidden [Marco; !1983]
* Fix erratic scrolling in GTK apps [Christian, Carlos; !1993, #4647]
* Fix GTK color picker support [Florian; !1990]
* Fix sound-file support in notifications [Florian; !1991]
* Fix high-contrast switches [Florian; !2000]
* Only allow one extension prefs dialog at a time [Florian; #4564]
* Fixed crashes [Ray, Sebastian; !2004, !2014]
* Misc. bug fixes and cleanups [Jonas, Florian, Jakub, Carlos; !1985, !1998,
!1996, !1979, !2007, !2010]
Contributors:
Marco Trevisan (Treviño), Carlos Garnacho, Christian Hergert,
Sebastian Keller, Florian Müllner, Jakub Steiner, Ray Strode, Jonas Ådahl
Translators:
Марко Костић [sr], Ngọc Quân Trần [vi], Emin Tufan Çetin [tr],
Yaron Shahrabani [he], Sveinn í Felli [is], Goran Vidović [hr],
Marek Černocký [cs], Selyan Slimane AMIRI [kab], Rūdolfs Mazurs [lv],
eshagh shahidani [fa], Yuri Chornoivan [uk], Matej Urbančič [sl],
Anders Jonsson [sv], Rafael Fontenelle [pt_BR], Kukuh Syafaat [id],
Hugo Carvalho [pt], Aleksandr Melman [ru], Christian Kirbach [de]
41.0
====
Translators:
Goran Vidović [hr], Jordi Mas [ca], Aman Alam [pa], Balázs Úr [hu],
Piotr Drąg [pl], Nathan Follens [nl], Quentin PAGÈS [oc], Jiri Grönroos [fi],
Alexander Shopov [bg], Alan Mortensen [da], Efstathios Iosifidis [el]
41.rc.1
=======
* Make tests optional [Florian; !1975]
* Misc. bug fixes [Florian; !1974]
Contributors:
Florian Müllner
Translators:
Daniel Șerbănescu [ro]
41.rc
=====
* Optimize rendering of fullscreen zoom [Daniel; !1899]
* Fix glitchy launch animations when leaving overview [Daniel; !1440]
* Show low priority notifications only in message list [Florian; #4265]
* Support Soup 3 instead of 2.4 [Florian; !1940, !1966]
* Set log domain for extensions that use console.log() [Evan; !1958]
* Fix wrong separator position in dash [Raghuveer; !1804]
* Fix OSK not registering button presses on X11 [Sebastian; !1955]
* Fix work area getting messed up by hidden panels [Florian; #4569]
* Fix IM candidate popover position [Florian; #4593]
* Restrict callers of private D-Bus APIs [Florian; !1970]
* Support committing preedit string on focus loss [Carlos; !1929]
* Misc. bug fixes and cleanups [Florian, Ivan, Sebastian, José, Robert; !1956,
!1949, !1937, !1961, !1962, !1871, !1964, !1946, !1957, !1959, !1879, !1968]
Contributors:
José Expósito, Carlos Garnacho, Raghuveer Kasaraneni, Sebastian Keller,
Robert Mader, Ivan Molodetskikh, Florian Müllner, Daniel van Vugt, Evan Welsh
Translators:
Yuri Chornoivan [uk], Quentin PAGÈS [oc], Asier Sarasua Garmendia [eu],
Hugo Carvalho [pt], Rafael Fontenelle [pt_BR], Jordi Mas [ca],
Alexey Rubtsov [ru], Danial Behzadi [fa], Kukuh Syafaat [id],
Marek Černocký [cs], Fran Dieguez [gl], Daniel Mustieles [es],
Źmicier Turok [be], Jiri Grönroos [fi], Emin Tufan Çetin [tr],
Baurzhan Muftakhidinov [kk], Bruce Cowan [en_GB], Philipp Kiemle [de],
Matej Urbančič [sl], Dušan Kazik [sk], Charles Monzat [fr],
Luna Jernberg [sv], Aurimas Černius [lt], Boyuan Yang [zh_CN],
Changwoo Ryu [ko]
41.beta
=======
* Unbreak Xwayland apps when not using systemd in user session [Olivier; !1850]
* extension-tool: Always print location on successful creation [Leleat; !1856]
* Fix distributed man pages [Florian; !1859]
* Immediately start app grid drags for non-touch devices [Georges; !1866]
* Avoid unnecessary icon shadow changes [Daniel; !1869]
* Handle screencast failures more gracefully [Florian; !1878]
* Fix glitch in app grid → session transition [Harshad; !1886]
* Use symbolic icons in looking glass toolbar [Chris; !1671]
* Fix IM popup visibility when in fullscreen [Florian; !1900]
* magnifier: Fix view jumps when using caret tracking [Lee; !1823]
* Fix shadow rendering glitches [Daniel; !1897]
* Allow overriding super+number shortcuts in Settings [Florian; #1250]
* Fix vertical scrollbars in RTL locales [Florian; !1910]
* Don't include hidden search results in keynav [Florian; #4470]
* Use anaccelerated deltas in swipe tracker [Alexander; !1763]
* status/network: Do not disable on login screen [Florian; !1874]
* Always take workarea into account when allocating workspaces [Marco; !1892]
* location: Split out geoclue agent from indicator [Ian; !1919]
* Add focus indication for switches [vanadiae; !1920]
* Honor switch-user lockdown settings in unlock screen [Ray; !1833]
* Fix glitch when dragging window preview in overview [Sebastian; #4292]
* Lock down "Show Text" in password entries [Ray; !687]
* Add power mode selection to status menu [Florian; !1907]
* workspace: Handle skip-taskbar changes [Daniel; !1925]
* status/network: Use WWan settings panel for GSM/LTE modems [Mohammed; !1942]
* extensionUtils: Add gettext convenience helpers [Florian; !1941]
* screenShield: Fix suspend inhibitor accounting [Sebastian; !1927, !1952]
* Unify app context menus [Florian; !1948]
* Use consistent terminology in window menu [nitinosiris; !1834]
* Fixed crashes [Gustavo, Florian; !1848, !1885, !1935]
* Misc. bug fixes and cleanups [Jonas Å., Florian, Georges, Daniel, Olivier,
Carlos, Robert, Sebastian, Jakub, Jonas D., Fionn; !1838, !1854, !1860,
!1872, !1876, !1880, !1888, !1890, !1891, !1894, !1902, !1901, !1903,
!1841, !1904, !1786, !1906, !1909, !1908, !1840, !1913, !1917, !1914,
!1857, !1922, !1924, !1931, !1926, !953, !1932, !1939, !1938, !1944,
!1936, !1947, !1945, !1950]
Contributors:
Marco Trevisan (Treviño), Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
Harshad Gavali, Tjipke van der Heide, Fionn Kelleher, Sebastian Keller, Lee,
Leleat, Robert Mader, Chris Mayo, Alexander Mikhaylenko, Florian Müllner,
Georges Basile Stavracas Neto, nitinosiris, Mohammed Sadiq, Ian Douglas Scott,
Gustavo Noronha Silva, Jakub Steiner, Ray Strode, Daniel van Vugt, vanadiae,
Jonas Ådahl
Translators:
Quentin PAGÈS [oc], Cheng-Chia Tseng [zh_TW], Jordi Mas [ca],
Hugo Carvalho [pt], Julia Dronova [ru], Efstathios Iosifidis [el],
Alexander Shopov [bg], Florentina Mușat [ro], Yuri Chornoivan [uk],
Alexey Rubtsov [ru], Rafael Fontenelle [pt_BR], Yaron Shahrabani [he],
Daniel Mustieles [es], Matej Urbančič [sl], Danial Behzadi [fa],
Kukuh Syafaat [id], Fran Dieguez [gl], Boyuan Yang [zh_CN], Fabio Tomat [fur],
Tjipke van der Heide [fy], Emin Tufan Çetin [tr], Luna Jernberg [sv],
Daniel Șerbănescu [ro]
40.1
====
* Fix keyboard preview for IM that use 'default' layout [Peng; !1756]
* extensions: Fix copying technical details on prefs crash [Jan; !1795, !1796]
* Make window previews as large as possible [Jonas D.; !1670, !1813]
* Fix PgUp/PgDown handling in overview [Florian; !1798]
* Fix scroll view following keyboard focus [Andrew; !1802]
* Fix word suggestions in on-screen keyboard [Jia; !1806]
* Support animated backgrounds set via the wallpaper portal [Alexander; !1816]
* Fix freeze after cancelling (some) system-modal dialogs [Florian; !1819]
* Support double-super when animations are disabled [Florian; !1811]
* gdm: Allow timed login with disabled user list [Ray; !1809]
* status: Report real battery percentage when full [Prajna; !1787]
* Allow tap-drag-release to select variants in OSK [Carlos; !1789]
* Fix password authentication after fingerprint failure [Ray, Benjamin; !1821]
* Fix screen blanking on idle [Florian; !1824]
* Fix oversized system action icons in search [Sebastian; !1777]
* Only show 'Open Windows' in app menus if there are multiple [Leleat; !1827]
* Fix duplicated workspaces in minimap [Sebastian; !1828]
* Fix repeated letters in type-to-find overview search [Sebastian; !1828]
* Improve workspace placeholder in overview minimap [Joonas; !1801]
* screencasts: Improve default gstreamer pipeline [Jonas D.; !1633]
* Leave overview when activating app via shortcut [Nishal; !1839]
* Fix invisible scroll bars in faded views [Florian; !1831]
* Correct arrow navigation in alt-tab switcher in RTL locales [Leleat; !1835]
* Improve touch interaction of app grid actions [Carlos; !1774]
* Fixed crashes [Jonas Å., Sebastian; !1810, !1817]
* Misc. bug fixes and cleanups [Carlos, Yuri, Sebastian, Suryashankar, Zander,
arushsharma24, Florian, Georges, Jonas D., Frederic, Leleat, Jakub,
theRealPadster, Simon, Olivier; !1770, !1781, !1782, !1775, !1769, !1791,
!1764, !1793, !1799, !1805, !1484, !1815, !1820, !1807, !1825, !1822, !1800,
!1818, !1830, !1790, !1812, !1771, !1844, !1845, !1837, !1842]
Contributors:
Jonas Ådahl, arushsharma24, Benjamin Berg, Zander Brown, Jia Chao,
Frederic Crozat, Suryashankar Das, Jonas Dreßler, Olivier Fourdan,
Carlos Garnacho, Joonas Henriksson, Sebastian Keller, Yuri Konotopov,
Nishal Kulkarni, Leleat, Alexander Mikhaylenko, Florian Müllner,
Georges Basile Stavracas Neto, Prajna Sariputra, Simon Schneegans,
Jakub Steiner, Ray Strode, theRealPadster, Jan Tojnar, Peng Wu, Andrew Zaech
Translators:
Timo Jyrinki [fi], Boyuan Yang [zh_CN], Hannie Dumoleyn [nl], Dz Chen [zh_CN],
Ngọc Quân Trần [vi], Hugo Carvalho [pt], Yosef Or Boczko [he],
Yaron Shahrabani [he], Nathan Follens [nl], Cédric Valmary [oc],
Carmen Bianca BAKKER [eo], Emin Tufan Çetin [tr], Dušan Kazik [sk],
Stas Solovey [ru], Pawan Chitrakar [ne], Jordi Mas [ca], Quentin PAGÈS [oc]
40.0
====
Translators:
Zander Brown [en_GB], Dušan Kazik [sk]
40.rc
=====
* Define default app grid arrangement [Allan; !1700]
* Fix shading behind system modal dialogs [Florian; !1712]
* Only show logout-inhibiting apps in end-session dialog [Michael; !1424]
* Fix minimap previews on multi-monitor systems [Florian; !1721]
* Drop strict extension version match for unstable releases [Florian; !1719]
* Fix missing app menu after overview gesture [Florian; !1726]
* Improve app folder appearance [Jakub; !1714]
* Fix window previews becoming undraggable after workspace switch
[Sebastian; !1717]
* Fix dragging icons to a different page in RTL locales [Carlos; !1734]
* Support double super for opening app grid [Florian; !1736]
* Improve workspace handling on secondary monitors [Florian; !1735]
* Improve interaction when dragging between app grid pages [Carlos; !1630]
* Fix launching on requested workspace on wayland [Florian; !1316]
* Make wifi strength indicator consistent with icons in Settings [Remi; !1432]
* Start session in overview [Georges; !1678]
* Tweak window preview layout in overview [Jonas D.; !1702, !1737]
* Improve overview performance [Jonas D.; !1713, !1733, !1743, !1755]
* Fix new workspaces being invisible in minimap [Florian; !1716]
* Fix glitch after dragging window preview from second monitor [Ivan; !1727]
* Do not switch workspaces when scrolling during super-tab [Florian; !1746]
* Make OSK shifting up windows more reliable [Jonas D.; !1728, !1760]
* Fix swipe gesture glitches [Alexander; !1731]
* Fix mis-scaled preview icons in window picker [Sebastian; !1751]
* Fix unintended app grid changes during icon DND in dash [Sebastian; !1767]
* Fix missing X11 fallback icons [Florian; !1761]
* Fixed crashes [Sebastian; !1718]
* Misc. bug fixes and cleanups [Jonas Å., Sebastian, Abderrahim, Florian,
Alexander, Felix, Ivan, Jonas D., Jakub, Daniel; !1710, !1707, !1720, !1722,
!1724, !1732, !1246, !1738, !1740] !1742, !1741, !1745, !1748, !1749, !1765,
!1766, !1757, !1758]
Contributors:
Jonas Ådahl, arushsharma24, Allan Day, Felix Divo, Jonas Dreßler,
Carlos Garnacho, Sebastian Keller, Abderrahim Kitouni, Alexander Mikhaylenko,
Ivan Molodetskikh, Florian Müllner, Georges Basile Stavracas Neto,
Remi Salmon, Jakub Steiner, Michael Terry, Daniel van Vugt
Translators:
Fran Dieguez [gl], Balázs Meskó [hu], Baurzhan Muftakhidinov [kk],
Goran Vidović [hr], Christian Kirbach [de], Марко Костић [sr],
Asier Sarasua Garmendia [eu], Guillaume Bernard [fr], Tim Sabsch [de],
Philipp Kiemle [de], Danial Behzadi [fa], Piotr Drąg [pl],
Rūdolfs Mazurs [lv], Daniel Mustieles [es], Marek Černocký [cs],
Fabio Tomat [fur], Changwoo Ryu [ko], Kjartan Maraas [nb], A S Alam [pa],
Milo Casagrande [it]
40.beta
=======
* Overview redesign
- Move dash to the bottom [Georges, Abderrahim, Jakub; !1559]
- Do not duplicate dash icons in app grid [Florian; !1580]
- Separate favorites from running apps in dash [Florian; !1606, !1610, !1659]
- Change to a horizontal workspace layout [Georges; !1593, !1603]
- Move background to workspaces [Georges, Florian, Jakub; !1599]
- Overhaul window preview style [Florian, Jakub; !1605, !1654, !1657]
- Rework workspace switching animation [Alexander; !1326]
- Show workspace side-by-side [Georges; !1613]
- Allow switching workspaces with super+scroll on wayland [Florian; !1612]
- Allow swiping through more than one workspace at a time [Alexander; !1647]
- Extend active dash area to the screen edge [Florian; !1660]
- Change overall overview layout [Georges, Florian; !1624]
- Refine workspace activation in overview [Georges; !1645]
- Add vertical swipe gesture to shift through overview [Carlos; !1643]
- Add shortcuts for shifting through overview [Florian; !1695]
- Round background corners in overview [Jonas D.; !1651, !1697]
- Hide workspace minimap when using less than two workspaces [Florian; !1696]
- Scale down backgrounds in window picker [Georges; !1691]
- Minor improvements and bug fixes [Florian, Abderrahim, Georges, Sebastian,
Jakub, Pascal, Jonas D.; !1594, !1609, !1608, !1620, !1629, !1625, !1634,
!1640, #3669, !1636, !1655, !1656, !1665, !1667, !1638, !1680, !1682, !1684,
!1681, !1687, !1693, !1694, !1692]
* Fix glitch in app folder icons on smaller displays [Sebastian; !1581]
* Remove arrows from top bar menus [Doan, Florian, Razze; !1583, !1618, !1615]
* Fix stuck grab after failed area screenshots [Sebastian; !1600]
* Prefer image-data hint over app-icon in notifications [Guilherme; !1616]
* Fix drag actor position when animations are turned off [Sebastian; !1627]
* Improve spacing in MPRIS notifications with small text [Sebastian; !1632]
* Add Welcome dialog after major updates [Bastien; !1619]
* Do not save empty commands in run dialog history [Lucas; !1442, !1653]
* Consider device type for fingerprint hint on login screen [Razze; !1572]
* Add tooltip to Extensions app to view unellipsized description [Leleat; !1663]
* Fix stuck polkit dialog when using non-password auth [Florian; !1662]
* Provide screenshot feedback (flash, shutter) before writing file to disk
[Brion, Jonas; !1658]
* Improve Thai layout in on-screen keyboard [Panawat; !1427]
* Improve error handling for fingerprint auth [Marco; !1652]
* Handle a large number of window previews more gracefully [Sebastian; !1685]
* Follow swipe gesture when bringing up on-screen keyboard [Carlos; !1668]
* Disable out-of-date extensions by default (again) [Evan; !1706]
* Fixed crashes [Jonas D., Carlos; !1673, !1672]
* Misc. bug fixes and cleanups [Florian, Sebastian, Razze, Georges, Daniel,
Robert, Jonas D., Jonas Å., Marco, Bastien, TerraAr, Carlos; !1575, !1579,
!1577, !1578, !1585, !1587, !1588, !1590, !1591, !1592, !1595, !1596, !1597,
!1598, !1582, !1589, !1617, !1611, !1637, !1635, !1641, !1646, !1546, !1648,
!1650, !1649, !1644, !1661, !1622, !1075, !1674, !1556, !1686, !1683, !1688,
!1699, !1698, !1701, !1709]
Contributors:
Jonas Ådahl, Jonas Dreßler, Carlos Garnacho, Sebastian Keller,
Abderrahim Kitouni, Leleat, Robert Mader, Alexander Mikhaylenko,
Florian Müllner, Georges Basile Stavracas Neto, Bastien Nocera, Pascal Nowack,
Razze, Guilherme Silva, Jakub Steiner, TerraAr, Marco Trevisan (Treviño),
Brion Vibber, Doan Nam Long Vu, Daniel van Vugt, Evan Welsh,
Lucas Werkmeister, Panawat Wong-kleaw
Translators:
Balázs Úr [hu], Danial Behzadi [fa], Rafael Fontenelle [pt_BR], A S Alam [pa],
Anders Jonsson [sv], Yuri Chornoivan [uk], Marek Černocký [cs],
Hugo Carvalho [pt], Fran Dieguez [gl], Daniel Șerbănescu [ro],
Florentina Mușat [ro], Daniel Mustieles [es], Jordi Mas [ca],
Matej Urbančič [sl], Kukuh Syafaat [id], Bruno Lopes da Silva [pt_BR],
Аляксей [be], Balázs Meskó [hu], Марко Костић [sr], Enrico Nicoletto [pt_BR],
Emin Tufan Çetin [tr], Jiri Grönroos [fi], Aurimas Černius [lt]
40.alpha.1.1
============
* Adapt to settings moving to gsettings-desktop-schemas [Florian; !1573]
* Misc. bug fixes [Georges, Florian; !1571, !1574]
Contributors:
Florian Müllner, Georges Basile Stavracas Neto
Translators:
Марко Костић [sr], Marek Černocký [cs], Fabio Tomat [fur]
40.alpha.1
==========
* Restore app picker fade during swipes [Georges, Florian; !1519, !1569]
* Sort extensions in Looking Glass alphabetically [Florijan; !1516]
* Fix screenshots of unredirected fullscreen windows on X11
[Jonas Å., LuK1337; !1534, !1549]
* Use GPU to render (most) shadows [Georges; !1539]
* Refine avatar styling [Joonas; !1490]
* Fix storing VPN secrets [Sebastian; !1535]
* Don't depend on asciidoc and sassc when building from tarball
[Florian; !1553, !1555]
* Use horizontal pages in app picker [Georges; !1554]
* Avoid costly icon theme lookups unless when needed [Ivan; !1558]
* Properly expose locked state to logind [Florian; !1561]
* Use 3 fingers for system swipe gestures [Georges; !1562]
* Fix glitches in overview transitions [Jonas Å., Ivan; !1545, !1550]
* Improve login screen accessibility [Mike; !1567]
* Overhaul top bar styling [Jonas D.; !1397]
* Allow changing input volume by scrolling over microphone icon [Razze; !1566]
* Port Extensions app and portal to GTK4 [Florian; !1495]
* Fixed crashes [Jonas Å.; !1527]
* Misc. bug fixes and cleanups [Georges, Florian, Tom, Hans, Jonas D., Ivan,
Sebastian, Daniel; !1518, !1521, !1523, !1525, !1520, !1526, !1472, !1339,
!1529, !1531, !1532, !1533, !1528, !1350] !1542, !1537, !1548, !1551, !1557,
!1543, !1560, !1544, !1565]
Contributors:
Jonas Ådahl, Jonas Dreßler, Mike Gerow, Florijan Hamzic, Joonas Henriksson,
Sebastian Keller, Tom Levy, LuK1337, Ivan Molodetskikh, Florian Müllner,
Georges Basile Stavracas Neto, Hans Ulrich Niedermann, Razze, Daniel van Vugt
Translators:
Florentina Mușat [ro], Fabio Tomat [fur], Hugo Carvalho [pt],
Jordi Mas i Hernandez [ca], Philipp Kiemle [de], Fran Dieguez [gl],
Jordi Mas [ca], Kukuh Syafaat [id], Kjartan Maraas [nb],
Daniel Șerbănescu [ro], Matej Urbančič [sl]
40.alpha
========
* Handle @content properties in ease() functions [Andre; !1461]
* Fix screencast indicator on Xorg [Jonas Å.; !1466]
* Expand ellipsized app picker labels on hover [Georges; !1477, !1496]
* Fix inline-replies in chat notifications [Florian; #3226]
* Refine MPRIS notification layout [Harry; !1480]
* Improve do-not-disturb support [Florian; #2873, !1511]
* Fix mobile broadband support [Popax21; #3203]
* Add extension filtering in Extensions app [Florian; #3382]
* Improve app picker spacing on larger resolutions [Georges; !1510]
* Plugged leaks [Ray; !1460, !1459]
* Fixed crashes [Daniel, Florian; !1453, #3258, !1507]
* Misc. bug fixes and cleanups [Florian, Georges, Carlos, Joonas, Jan,
Jonas Å., Robert, Jonas D., Ian, Daniel, Sebastian, Jordan; !1456, !1436,
!1405, !1421, #3252, !1464, !1469, !1465, !1473, !1475, #3307, !1479,
!1482, !1470, !1486, #3335, #3342, #3388, !1497, !1498, !1491, !1501,
!1492, !1489, !1502, !1505, !1504, !1506, !1503, !1483, !1508, !1481,
!1509, !1512, !1417, !1517]
Contributors:
Jonas Dreßler, Carlos Garnacho, Joonas Henriksson, Sebastian Keller,
Robert Mader, Andre Moreira Magalhaes, Daniel García Moreno, Harry Míchal,
Florian Müllner, Georges Basile Stavracas Neto, Jordan Petridis, Popax21,
Ian Douglas Scott, Ray Strode, Jan Tojnar, Olav Vitters, Daniel van Vugt,
Jonas Ådahl
Translators:
Juliano de Souza Camargo [pt], Fabio Tomat [fur], Akarshan Biswas [bn_IN],
Carmen Bianca BAKKER [eo], Daniel Mustieles [es],
Asier Sarasua Garmendia [eu], Ask Hjorth Larsen [da], Yuri Chornoivan [uk],
Anders Jonsson [sv], Kjartan Maraas [nb]
3.38.1
======
* Add screen recordings to recent items [Florian; #3171]
* Tweak peek-password feature [Florian; #3138]
* Fix workspace glitches in overview [Florian; #3208, #3211]
* Improve DND behavior in app picker [Georges; !1447]
* Misc. bug fixes and cleanups [Florian, Daniel, Georges, Bastien, Christopher,
yun341, Carlos; #3169, !1434, !1441, !1444, !379, !1443, #2230, !1448,
!1451, #3209]
Contributors:
Yacine Bouklif, Christopher Davis, Carlos Garnacho, Daniel García Moreno,
Florian Müllner, Georges Basile Stavracas Neto, Bastien Nocera, yun341
Translators:
Juliano de Souza Camargo [pt], Yacine Bouklif [kab], Charles Monzat [fr],
Cheng-Chia Tseng [zh_TW], Yosef Or Boczko [he]
3.38.0
======
* Misc. bug fixes and cleanups [Andy, Florian; #3147, !1438]
Contributors:
Andy Holmes, Florian Müllner
Translators:
Anders Jonsson [sv], Balázs Úr [hu], Dušan Kazik [sk], Alan Mortensen [da],
Tim Sabsch [de], Claude Paroz [fr], Jiri Grönroos [fi], Juliano Camargo [pt],
Milo Casagrande [it], Aron Xu [zh_CN], Rūdolfs Mazurs [lv]
3.37.92
=======
* Fix screen recorder shortcut [Florian; #3097]
* Support cycle-group cycling only over windows in the workspac3 [Mitar; #3116]
* Misc. bug fixes and cleanups [Georges, Daniel, Carlos; !1428, !1423,
!1311, #2968]
Contributors:
Carlos Garnacho, Mitar, Florian Müllner, Georges Basile Stavracas Neto,
Daniel van Vugt
Translators:
Yuri Chornoivan [uk], Zander Brown [en_GB], Rafael Fontenelle [pt_BR],
Nathan Follens [nl], Danial Behzadi [fa], Kukuh Syafaat [id],
Aurimas Černius [lt], Marek Černocký [cs], Fabio Tomat [fur],
Changwoo Ryu [ko], Марко Костић [sr], Daniel Mustieles [es], Dušan Kazik [sk],
Thibault Martin [fr], Jordi Mas [ca]
3.37.91
=======
* Fix potential stack overflow in libcroco [Michael; !1404]
* Fix page removal in app picker [Georges; !1406]
* Fix "old style" VPN authentication [Florian; !1407]
* Fix X11 session login [Benjamin; !1418]
* Fix week number alignment when using font-scaling [Joonas; !1415]
* Fix lock screen on systems without GLSL shader support [Zephaniah; #3071]
* Misc. bug fixes and cleanups [Florian, Jonas, Georges, Andre, Will, Björn;
!1396, !1359, !1408, !1409, !1414, !1413, !1416, #3073]
Contributors:
Jonas Ådahl, Benjamin Berg, Michael Catanzaro, Björn Daase, Joonas Henriksson,
Zephaniah E. Loss-Cutler-Hull, Andre Moreira Magalhaes, Florian Müllner,
Georges Basile Stavracas Neto, Will Thompson
Translators:
Fran Dieguez [gl], Jordi Mas [ca], Daniel Mustieles [es],
Florentina Mușat [ro], Akarshan Biswas [bn_IN], Baurzhan Muftakhidinov [kk],
Piotr Drąg [pl], Rafael Fontenelle [pt_BR], Emin Tufan Çetin [tr],
sicklylife [ja], Danial Behzadi [fa], Jiri Grönroos [fi], Goran Vidović [hr],
Matej Urbančič [sl], Boyuan Yang [zh_CN]
3.37.90
=======
* Fix extension updates when many extensions are installed [Jeremias; !1363]
* Fix missing icons in on-screen keyboard [Emre; #2631, #3007]
* Fix delay when showing calendar events [Sebastian; #2992]
* Allow rearranging items in app picker [Georges; !1284]
* Fix top bar navigation when NumLock is active [Olivier; #550]
* Delay login animation until wallpaper has loaded [Michael; #734996]
* Reset auth prompt on login screen on VT switch before fade in [Ray; #2997]
* Move screencasting into a separate service [Jonas Å.; !1372]
* Replace loaded terms with more descriptive one [Olivier; !1393]
* Add "Boot Options" support to restart dialog [Hans; !199]
* Move "Restart" into a separate menu item/dialog [Florian; #2202]
* Default to not installing updates on low battery [Michael; #2717]
* Misc. bug fixes and cleanups [Florian, Daniel V., Georges, Jonas Å.,
Daniel G., Carlos, Benjamin, Piotr, Andre, Jonas D., Andy; !1357, !1356,
#2969, #2969, !1358, !1371, #3005, !1380, #3022, !1381, !895, !1387, !1386,
!1385, #3037, !1389, !1390, !1391, !1383, !1399, #2983, !1403]
Contributors:
Jonas Ådahl, Benjamin Berg, Michael Catanzaro, Piotr Drąg, Jonas Dreßler,
Olivier Fourdan, Carlos Garnacho, Hans de Goede, Andy Holmes,
Sebastian Keller, Andre Moreira Magalhaes, Daniel García Moreno,
Florian Müllner, Georges Basile Stavracas Neto, Jeremias Ortega, Ray Strode,
Emre Uyguroglu, Daniel van Vugt
Translators:
Tim Sabsch [de], Boyuan Yang [zh_CN], Fabio Tomat [fur],
Efstathios Iosifidis [el], Rafael Fontenelle [pt_BR], Yuri Chornoivan [uk],
Daniel Șerbănescu [ro], Jordi Mas [ca], Daniel Mustieles [es],
Emin Tufan Çetin [tr], Asier Sarasua Garmendia [eu]
3.37.3
======
* Refactor and clean up window picker
@ -717,7 +230,7 @@ Translators:
* Handle extension updates [Florian; !945]
* Animate showing and hiding caps-lock warning [Jonas; !952]
* Support "auto" lengths in CSS [Florian; !971]
* Turn extension-prefs into the official Extensions app [Florian; #1968]
* Turn extension-prefs into the offical Extensions app [Florian; #1968]
* Sandbox the portal helper [Michael; !983]
* Misc. bug fixes and cleanups [Florian, Björn, Jakub, Alexander, Daniel V.,
Jonas, nana-4, Carlos, Sebastian, Daniel G., Georges, Piotr; !918, !917,
@ -1006,7 +519,7 @@ Translators:
======
* Fix keeping actors visible in scrollviews [Marco; #1061]
* Move some chrome above popup windows [Jonas D.; !358]
* Include 'sandboxed-app-id' in window introspection info [Florian; #1289]
* Include 'sandboxed-app-id' in winodw introspection info [Florian; #1289]
* Port to libecal-2.0 [Milan; !501]
* Support TCRYPT in mount password dialog [segfault; !126]
* Misc. bug fixes and cleanups [Florian, Marco, Veerasamy; !517, #745, !499,
@ -1555,7 +1068,7 @@ Translations:
* gdm: Fix "Not listed" focus indication [Florian; #784040]
* Fix missing icons in freedesktop notifications [Florian; #784245]
* gdm: Disable user list when empty [Xiaoguang; #731320]
* gdm: Allow empty response to PAM messages [Ray; #784360]
* gdm: Allow empty reponse to PAM messages [Ray; #784360]
* Fix blocked clicks in shutdown dialog [Florian; #781738]
* Show OSD popup when changing volume via scroll wheel [Florian; #781028]
* Refine list search results [Rares; #749957]
@ -3015,7 +2528,7 @@ Translations:
* Merge the wayland branch [Giovanni, Neil; #707467]
* Make search entry behave better in RTL locales [Matthias, Florian; #705779]
* Allow to change app pages with pageUp/pageDown keys [Carlos; #707979]
* Set appropriate a11y states on expandable menu items [Alejandro; #708038]
* Set approriate a11y states on expandable menu items [Alejandro; #708038]
* Improve page indicator animation [Carlos; #707565]
* Misc bug fixes and cleanups [Florian, Olivier, Jasper, Giovanni, Magdalen,
Adel, Carlos, Rico, Joanmarie; #707308, #707430, #707508, #707557, #707600,
@ -4299,7 +3812,7 @@ Translations:
* Update the calendar code to use ECalClient [Giovanni; #671177]
* Update jhbuild script to use the main moduleset [Owen, Will; #668440]
* StTextureCache: code cleanup, evict unused icons, merge together
simultaneous requests for the same icon [Jasper; #670771, #671656, #672273]
simulataneous requests for the same icon [Jasper; #670771, #671656, #672273]
* Clean up St for recent Clutter changes and fix bugs. StContainer and
StGroup are removed [Jasper, Florian; #670034, #670640, #670904]
* Code cleanup [Adel, Jasper, Rui; #613194, #671086, #671103]
@ -4434,7 +3947,7 @@ Translations:
[Stefano; #664201]
- Delay rearranging windows in the overview as long as the pointer
is over a window [Vit; #645325]
* Add a GConf => DConf migration file for overridden Mutter settings
* Add a GConf => DConf migration file for overriden Mutter settings
[Florian; #667636]
* When a VPN connection is active, show that as the network icon
[Giovanni; #665115]
@ -4681,7 +4194,7 @@ Translations:
- Add fingerprint reader support [Ray; #657823]
- Add a power button offering the choice of Suspend/Restart/Power off
[Ray; #657822]
- Remove the option to view the current keyboard layout [Matthias; #659164]
- Remove the option to view the current keyboad layout [Matthias; #659164]
- Make Control-Alt-Tab work for full keyboard access [Ray; #659177]
* Frequently initiate a full garbage collection; Spidermonkey isn't very good
at tracking the amount of resources we have allocated so this hopefully will
@ -4898,7 +4411,7 @@ Translations:
* Fix selection highlighting for light-on-dark entries [Jasper; #643768]
* Make control-Return in the overview open a new window [Maxim]
* Delay showing the alt-Tab switcher to reduce visual noise when
flipping between windows [Dan; #652346]
flipping betweeen windows [Dan; #652346]
* When we have vertically stacked monitors, put the message tray
on the bottom one [Dan; #636963]
* Fix various problems with keynav and the Activities button
@ -5049,7 +4562,7 @@ Translations:
- Fix missing device descriptions with multiple devices of the
same type [Giovanni]
https://bugzilla.gnome.org/show_bug.cgi?id=646074
- Label ad-hoc networks with an appropriate icon [Dan]
- Label ad-hoc neworks with an appropriate icon [Dan]
https://bugzilla.gnome.org/show_bug.cgi?id=646141
- Fix displaying some devices states as "invalid" [Dan]
https://bugzilla.gnome.org/show_bug.cgi?id=646946

View File

@ -1,5 +1,5 @@
# GNOME Shell
GNOME Shell provides core user interface functions for the GNOME desktop,
GNOME Shell provides core user interface functions for the GNOME 3 desktop,
like switching to windows and launching applications. GNOME Shell takes
advantage of the capabilities of modern graphics hardware and introduces
innovative user interface concepts to provide a visually attractive and
@ -10,7 +10,6 @@ to build GNOME Shell from source and how to get involved with the project,
see the [project wiki][project-wiki].
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
Please refer to the [*Schedule* wiki page][schedule] to see the supported versions.
## Contributing
@ -20,24 +19,10 @@ Commit messages should follow the [GNOME commit message
guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL
to either an issue or a merge request in each commit.
## Default branch
The default development branch is `main`. If you still have a local
checkout under the old name, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
## License
GNOME Shell is distributed under the terms of the GNU General Public License,
version 2 or later. See the [COPYING][license] file for details.
[project-wiki]: https://wiki.gnome.org/Projects/GnomeShell
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues
[schedule]: https://wiki.gnome.org/Schedule
[license]: COPYING

View File

@ -13,9 +13,6 @@
/* Define to 1 if you have the `mallinfo' function. */
#mesondefine HAVE_MALLINFO
/* Define to 1 if you have the `mallinfo2' function. */
#mesondefine HAVE_MALLINFO2
/* Define to 1 fi you have the <sys/resource.h> header file. */
#mesondefine HAVE_SYS_RESOURCE_H

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.shell.keybindings"
group="system"
name="Launchers"
wm_name="GNOME Shell"
package="gnome-shell">
<KeyListEntry name="switch-to-application-1"
description="Activate favorite application 1"
hidden="true"/>
<KeyListEntry name="switch-to-application-2"
description="Activate favorite application 2"
hidden="true"/>
<KeyListEntry name="switch-to-application-3"
description="Activate favorite application 3"
hidden="true"/>
<KeyListEntry name="switch-to-application-4"
description="Activate favorite application 4"
hidden="true"/>
<KeyListEntry name="switch-to-application-5"
description="Activate favorite application 5"
hidden="true"/>
<KeyListEntry name="switch-to-application-6"
description="Activate favorite application 6"
hidden="true"/>
<KeyListEntry name="switch-to-application-7"
description="Activate favorite application 7"
hidden="true"/>
<KeyListEntry name="switch-to-application-8"
description="Activate favorite application 8"
hidden="true"/>
<KeyListEntry name="switch-to-application-9"
description="Activate favorite application 9"
hidden="true"/>
</KeyListEntries>

View File

@ -123,7 +123,7 @@ def locale_to_xkb(locale, name):
if xkb:
return xkb
else:
raise KeyError("layout %s explicitly disabled in overrides"
raise KeyError("layout %s explicitely disabled in overrides"
% locale)
xkb_names = sorted(name_to_xkb.keys())
if name in xkb_names:

View File

@ -1,76 +0,0 @@
<!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.PowerProfiles:
@short_description: Power Profiles daemon
The power-profiles-daemon API is meant to be used by parts of the OS or
desktop environment to switch system power profiles based on user choice,
or user intent.
OS components would typically use the "Profiles" property to construct
their UI (2 or 3 profiles available), and monitor the "ActiveProfile"
and the "PerformanceInhibited" properties to update that UI. The UI
would try to set the "ActiveProfile" property if the user selected
a different one.
Note that the reason why the project exists and how it is different from
existing projects is explained <ulink href=" https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/blob/master/README.md">
in the project's README file</ulink>.
The object path will be "/net/hadess/PowerProfiles".
-->
<interface name="net.hadess.PowerProfiles">
<!--
ActiveProfile:
The type of the currently active profile. It might change automatically
if the "performance" profile was selected but it got inhibited, in which
case the "PerformanceInhibited" property will reflect the reason.
-->
<property name="ActiveProfile" type="s" access="readwrite"/>
<!--
PerformanceInhibited:
This will be set if the performance power profile is unavailable, with
the value being used to identify the reason for unavailability. As new
reasons can be added, it is recommended that front-ends show a generic
reason if they do not recognise the value. Possible values are:
- "lap-detected" (the computer is sitting on the user's lap)
- "high-operating-temperature" (the computer is close to overheating)
- "" (the empty string, if not inhibited)
-->
<property name="PerformanceInhibited" type="s" access="read"/>
<!--
Profiles:
An array of key-pair values representing each profile. The key named
"Driver" (s) identifies the power-profiles-daemon backend code used to
implement the profile.
The key named "Profile" (s) will be one of:
- "power-saver" (battery saving profile)
- "balanced" (the default profile)
- "performance" (a profile that does not care about noise or battery consumption)
Only one of each type of profile will be listed, with the daemon choosing the
more appropriate "driver" for each profile type.
-->
<property name="Profiles" type="aa{sv}" access="read"/>
<!--
Actions:
An array of strings listing each one of the "actions" implemented in
the running daemon. This is used by API users to figure out whether
particular functionality is available in a version of the daemon.
-->
<property name="Actions" type="as" access="read"/>
</interface>
</node>

View File

@ -1,78 +0,0 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="net.reactivated.Fprint.Device">
<method name="ListEnrolledFingers">
<arg type="s" name="username" direction="in">
</arg>
<arg type="as" name="enrolled_fingers" direction="out">
</arg>
</method>
<method name="DeleteEnrolledFingers">
<arg type="s" name="username" direction="in">
</arg>
</method>
<method name="DeleteEnrolledFingers2">
</method>
<method name="Claim">
<arg type="s" name="username" direction="in">
</arg>
</method>
<method name="Release">
</method>
<method name="VerifyStart">
<arg type="s" name="finger_name" direction="in">
</arg>
</method>
<method name="VerifyStop">
</method>
<signal name="VerifyFingerSelected">
<arg type="s" name="finger_name">
</arg>
</signal>
<signal name="VerifyStatus">
<arg type="s" name="result">
</arg>
<arg type="b" name="done">
</arg>
</signal>
<method name="EnrollStart">
<arg type="s" name="finger_name" direction="in">
</arg>
</method>
<method name="EnrollStop">
</method>
<signal name="EnrollStatus">
<arg type="s" name="result">
</arg>
<arg type="b" name="done">
</arg>
</signal>
<property name="name" type="s" access="read">
</property>
<property name="num-enroll-stages" type="i" access="read">
</property>
<property name="scan-type" type="s" access="read">
</property>
</interface>
</node>

View File

@ -1,18 +0,0 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="net.reactivated.Fprint.Manager">
<method name="GetDevices">
<arg type="ao" name="devices" direction="out">
</arg>
</method>
<method name="GetDefaultDevice">
<arg type="o" name="device" direction="out">
</arg>
</method>
</interface>
</node>

View File

@ -20,12 +20,6 @@
<method name="ListSessions">
<arg name="sessions" type="a(susso)" direction="out"/>
</method>
<method name="CanRebootToBootLoaderMenu">
<arg type="s" direction="out"/>
</method>
<method name="SetRebootToBootLoaderMenu">
<arg type="t" direction="in"/>
</method>
<signal name="PrepareForSleep">
<arg type="b" direction="out"/>
</signal>

View File

@ -0,0 +1,26 @@
<node>
<interface name="org.gnome.Magnifier.ZoomRegion">
<method name="setMagFactor">
<arg type="d" direction="in"/>
<arg type="d" direction="in"/>
</method>
<method name="getMagFactor">
<arg type="d" direction="out"/>
<arg type="d" direction="out"/>
</method>
<method name="setRoi">
<arg type="ai" direction="in"/>
</method>
<method name="getRoi">
<arg type="ai" direction="out"/>
</method>
<method name="shiftContentsTo">
<arg type="i" direction="in"/>
<arg type="i" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="moveResize">
<arg type="ai" direction="in"/>
</method>
</interface>
</node>

View File

@ -0,0 +1,54 @@
<node>
<interface name="org.gnome.Magnifier">
<method name="setActive">
<arg type="b" direction="in"/>
</method>
<method name="isActive">
<arg type="b" direction="out"/>
</method>
<method name="showCursor"/>
<method name="hideCursor"/>
<method name="createZoomRegion">
<arg type="d" direction="in"/>
<arg type="d" direction="in"/>
<arg type="ai" direction="in"/>
<arg type="ai" direction="in"/>
<arg type="o" direction="out"/>
</method>
<method name="addZoomRegion">
<arg type="o" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="getZoomRegions">
<arg type="ao" direction="out"/>
</method>
<method name="clearAllZoomRegions"/>
<method name="fullScreenCapable">
<arg type="b" direction="out"/>
</method>
<method name="setCrosswireSize">
<arg type="i" direction="in"/>
</method>
<method name="getCrosswireSize">
<arg type="i" direction="out"/>
</method>
<method name="setCrosswireLength">
<arg type="i" direction="in"/>
</method>
<method name="getCrosswireLength">
<arg type="i" direction="out"/>
</method>
<method name="setCrosswireClip">
<arg type="b" direction="in"/>
</method>
<method name="getCrosswireClip">
<arg type="b" direction="out"/>
</method>
<method name="setCrosswireColor">
<arg type="u" direction="in"/>
</method>
<method name="getCrosswireColor">
<arg type="u" direction="out"/>
</method>
</interface>
</node>

View File

@ -1,191 +0,0 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Mutter.ScreenCast:
@short_description: Screen cast interface
This API is private and not intended to be used outside of the integrated
system that uses libmutter. No compatibility between versions are
promised.
-->
<interface name="org.gnome.Mutter.ScreenCast">
<!--
CreateSession:
@properties: Properties
@session_path: Path to the new session object
* "remote-desktop-session-id" (s): The ID of a remote desktop session.
Remote desktop driven screen casts
are started and stopped by the remote
desktop session.
* "disable-animations" (b): Set to "true" if the screen cast application
would prefer animations to be globally
disabled, while the session is running. Default
is "false". Available since version 3.
-->
<method name="CreateSession">
<arg name="properties" type="a{sv}" direction="in" />
<arg name="session_path" type="o" direction="out" />
</method>
<!--
Version:
@short_description: API version
-->
<property name="Version" type="i" access="read" />
</interface>
<!--
org.gnome.Mutter.ScreenCast.Session:
@short_description: Screen cast session
-->
<interface name="org.gnome.Mutter.ScreenCast.Session">
<!--
Start:
Start the screen cast session
-->
<method name="Start" />
<!--
Stop:
Stop the screen cast session
-->
<method name="Stop" />
<!--
Closed:
The session has closed.
-->
<signal name="Closed" />
<!--
RecordMonitor:
@connector: Connector of the monitor to record
@properties: Properties
@stream_path: Path to the new stream object
Record a single monitor.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordMonitor">
<arg name="connector" type="s" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordWindow:
@properties: Properties used determining what window to select
@stream_path: Path to the new stream object
Supported since API version 2.
Record a single window. The cursor will not be included.
Available @properties include:
* "window-id" (t): Id of the window to record.
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see RecordMonitor).
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
-->
<method name="RecordWindow">
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordArea:
@x: X position of the recorded area
@y: Y position of the recorded area
@width: width of the recorded area
@height: height of the recorded area
@properties: Properties
@stream_path: Path to the new stream object
Record an area of the stage. The coordinates are in stage coordinates.
The size of the stream does not necessarily match the size of the
recorded area, and will depend on DPI scale of the affected monitors.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordArea">
<arg name="x" type="i" direction="in" />
<arg name="y" type="i" direction="in" />
<arg name="width" type="i" direction="in" />
<arg name="height" type="i" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
</interface>
<!--
org.gnome.Mutter.ScreenCast.Stream:
@short_description: Screen cast stream
-->
<interface name="org.gnome.Mutter.ScreenCast.Stream">
<!--
PipeWireStreamAdded:
@short_description: Pipewire stream added
A signal emitted when PipeWire stream for the screen cast stream has
been created. The @node_id corresponds to the PipeWire stream node.
-->
<signal name="PipeWireStreamAdded">
<annotation name="org.gtk.GDBus.C.Name" value="pipewire-stream-added"/>
<arg name="node_id" type="u" direction="out" />
</signal>
<!--
Parameters:
@short_description: Optional stream parameters
Available parameters include:
* "position" (ii): Position of the source of the stream in the
compositor coordinate space.
* "size" (ii): Size of the source of the stream in the compositor
coordinate space.
-->
<property name="Parameters" type="a{sv}" access="read" />
</interface>
</node>

View File

@ -3,9 +3,6 @@
<method name="GetAppId">
<arg type="s" direction="out"/>
</method>
<method name="GetFlags">
<arg type="u" direction="out"/>
</method>
<method name="GetReason">
<arg type="s" direction="out"/>
</method>

View File

@ -180,10 +180,10 @@
Enable an extension.
-->
<method name="EnableExtension">
<arg type="s" direction="in" name="uuid"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="EnableExtension"> \
<arg type="s" direction="in" name="uuid"/> \
<arg type="b" direction="out" name="success"/> \
</method> \
<!--
DisableExtension:
@ -192,10 +192,10 @@
Disable an extension.
-->
<method name="DisableExtension">
<arg type="s" direction="in" name="uuid"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="DisableExtension"> \
<arg type="s" direction="in" name="uuid"/> \
<arg type="b" direction="out" name="success"/> \
</method> \
<!--
LaunchExtensionPrefs:

View File

@ -70,14 +70,6 @@
-->
<property name="AnimationsEnabled" type="b" access="read"/>
<!--
ScreenSize:
@short_description: The size of the screen
Since: 3
-->
<property name="ScreenSize" type="(ii)" access="read"/>
<property name="version" type="u" access="read"/>
</interface>
</node>

View File

@ -1,10 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell/dbus-interfaces">
<file preprocess="xml-stripblanks">net.hadess.PowerProfiles.xml</file>
<file preprocess="xml-stripblanks">net.hadess.SensorProxy.xml</file>
<file preprocess="xml-stripblanks">net.reactivated.Fprint.Device.xml</file>
<file preprocess="xml-stripblanks">net.reactivated.Fprint.Manager.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.Application.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.bolt1.Device.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.bolt1.Manager.xml</file>
@ -29,7 +26,8 @@
<file preprocess="xml-stripblanks">org.freedesktop.realmd.Service.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.UPower.Device.xml</file>
<file preprocess="xml-stripblanks">org.freedesktop.UPower.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Mutter.ScreenCast.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Magnifier.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Magnifier.ZoomRegion.xml</file>
<file preprocess="xml-stripblanks">org.gnome.ScreenSaver.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SessionManager.EndSessionDialog.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SessionManager.Inhibitor.xml</file>

View File

@ -0,0 +1,4 @@
[org.gnome.shell.overrides]
attach-modal-dialogs = /desktop/gnome/shell/windows/attach_modal_dialogs
edge-tiling = /desktop/gnome/shell/windows/edge_tiling
workspaces-only-on-primary = /desktop/gnome/shell/windows/workspaces_only_on_primary

View File

@ -2,16 +2,14 @@
<gresources>
<gresource prefix="/org/gnome/shell/theme">
<file>calendar-today.svg</file>
<file alias="icons/scalable/status/carousel-arrow-next-24-symbolic.svg">carousel-arrow-next-24-symbolic.svg</file>
<file alias="icons/scalable/status/carousel-arrow-back-24-symbolic.svg">carousel-arrow-back-24-symbolic.svg</file>
<file>checkbox-focused.svg</file>
<file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file>
<file>checkbox.svg</file>
<file alias="icons/scalable/actions/color-pick.svg">color-pick.svg</file>
<file>dash-placeholder.svg</file>
<file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file>
<file>gnome-shell-start.svg</file>
<file alias="icons/scalable/status/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file>no-events.svg</file>
<file>no-notifications.svg</file>
@ -22,21 +20,17 @@
<file alias="icons/scalable/actions/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
<file alias="icons/scalable/actions/preview-close-symbolic.svg">window-close-24-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file>
<file>process-working.svg</file>
<file alias="icons/scalable/status/screen-privacy-disabled-symbolic.svg">screen-privacy-disabled-symbolic.svg</file>
<file alias="icons/scalable/status/screen-privacy-symbolic.svg">screen-privacy-symbolic.svg</file>
<file>toggle-off.svg</file>
<file>toggle-off-dark.svg</file>
<file>toggle-off-hc.svg</file>
<file>toggle-on.svg</file>
<file>toggle-on-dark.svg</file>
<file>toggle-on-hc.svg</file>
<file>workspace-placeholder.svg</file>
</gresource>
</gresources>

View File

@ -1,7 +1,7 @@
[Unit]
Description=GNOME Shell on Wayland
# On wayland, force a session shutdown
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-shutdown.target
OnFailure=gnome-shell-disable-extensions.service gnome-session-shutdown.target
OnFailureJobMode=replace-irreversibly
CollectMode=inactive-or-failed
RefuseManualStart=on
@ -13,21 +13,18 @@ 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]
Slice=session.slice
Type=notify
# NOTE: This can be replaced with ConditionEnvironment=XDG_SESSION_TYPE=%I in
# the [Unit] section with systemd >= 246. Also, the current solution is
# kind of painful as systemd had a bug where it retries the condition.
# Only start if the template instance matches the session type.
ExecCondition=/bin/sh -c 'test "$XDG_SESSION_TYPE" = "%I" || exit 2'
ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# unset some environment variables that were set by the shell and won't work now that the shell is gone
ExecStopPost=-/bin/sh -c 'test "$SERVICE_RESULT" != "exec-condition" && systemctl --user unset-environment GNOME_SETUP_DISPLAY WAYLAND_DISPLAY DISPLAY XAUTHORITY'
ExecStopPost=-systemctl --user unset-environment GNOME_SETUP_DISPLAY WAYLAND_DISPLAY DISPLAY XAUTHORITY
# 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

View File

@ -0,0 +1,10 @@
[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

View File

@ -1,7 +1,7 @@
[Unit]
Description=GNOME Shell on X11
# On X11, try to show the GNOME Session Failed screen
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-failed.target
OnFailure=gnome-shell-disable-extensions.service gnome-session-failed.target
OnFailureJobMode=replace
CollectMode=inactive-or-failed
RefuseManualStart=on
@ -13,24 +13,18 @@ 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]
Slice=session.slice
Type=notify
# NOTE: This can be replaced with ConditionEnvironment=XDG_SESSION_TYPE=%I in
# the [Unit] section with systemd >= 246. Also, the current solution is
# kind of painful as systemd had a bug where it retries the condition.
# Only start if the template instance matches the session type.
ExecCondition=/bin/sh -c 'test "$XDG_SESSION_TYPE" = "%I" || exit 2'
ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# On X11 we do not need to unset any variables
# On X11 we want to restart on-success (Alt+F2 + r) and on-failure.
Restart=always
# Do not wait before restarting the shell

View File

@ -1,10 +1,10 @@
[Unit]
Description=GNOME Shell
Description=GNOME Shell on X11
DefaultDependencies=no
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
Wants=org.gnome.Shell@wayland.service
Wants=org.gnome.Shell@x11.service
Requires=gnome-shell-x11.service
After=gnome-shell-x11.service

View File

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

View File

@ -41,7 +41,6 @@ foreach service_file : service_files
)
endforeach
theme_deps = []
subdir('dbus-interfaces')
subdir('icons')
@ -73,13 +72,9 @@ configure_file(
install_dir: pkgdatadir
)
keybinding_files = [
'50-gnome-shell-launchers.xml',
'50-gnome-shell-system.xml',
]
install_data('gnome-shell.portal', install_dir: portaldir)
install_data(keybinding_files, install_dir: keysdir)
install_data('50-gnome-shell-system.xml', install_dir: keysdir)
schemaconf = configuration_data()
@ -106,21 +101,22 @@ if have_systemd
unitconf.set('bindir', bindir)
configure_file(
input: 'org.gnome.Shell@x11.service.in',
output: 'org.gnome.Shell@x11.service',
input: 'gnome-shell-x11.service.in',
output: 'gnome-shell-x11.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
configure_file(
input: 'org.gnome.Shell@wayland.service.in',
output: 'org.gnome.Shell@wayland.service',
input: 'gnome-shell-wayland.service.in',
output: 'gnome-shell-wayland.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
units = files('org.gnome.Shell.target',
'org.gnome.Shell-disable-extensions.service')
units = files('gnome-shell-x11.target',
'gnome-shell-wayland.target',
'gnome-shell-disable-extensions.service')
install_data(units, install_dir: systemduserunitdir)
endif
@ -131,3 +127,5 @@ custom_target('compile-schemas',
output: 'gschemas.compiled',
command: [find_program('glib-compile-schemas'), meson.current_build_dir()],
build_by_default: true)
install_data('gnome-shell-overrides.convert', install_dir: convertdir)

View File

@ -41,7 +41,7 @@
</description>
</key>
<key name="disable-extension-version-validation" type="b">
<default>false</default>
<default>true</default>
<summary>Disables the validation of extension version compatibility</summary>
<description>
GNOME Shell will only load extensions that claim to support the current
@ -50,13 +50,20 @@
</description>
</key>
<key name="favorite-apps" type="as">
<default>[ 'org.gnome.Epiphany.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<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>
<summary>List of desktop file IDs for favorite applications</summary>
<description>
The applications corresponding to these identifiers
will be displayed in the favorites area.
</description>
</key>
<key name="app-picker-view" type="u">
<default>0</default>
<summary>App Picker View</summary>
<description>
Index of the currently selected view in the application picker.
</description>
</key>
<key name="command-history" type="as">
<default>[]</default>
<summary>History for command (Alt-F2) dialog</summary>
@ -94,42 +101,16 @@
adapter is ever seen not to have devices associated to it.
</description>
</key>
<key name="welcome-dialog-last-shown-version" type="s">
<default>''</default>
<summary>The last version the “Welcome to GNOME” dialog was shown for</summary>
<key name="introspect" type="b">
<default>false</default>
<summary>Enable introspection API</summary>
<description>
This key determines for which version the “Welcome to GNOME” dialog was
last shown. An empty string represents the oldest possible version, and
a huge number will represent versions that do not exist yet. This huge
number can be used to effectively disable the dialog.
Enables a D-Bus API that allows to introspect the application state of
the shell.
</description>
</key>
<key name="app-picker-layout" type="aa{sv}">
<default><![CDATA[
[{
'org.gnome.Geary.desktop': <{'position': <0>}>,
'org.gnome.Contacts.desktop': <{'position': <1>}>,
'org.gnome.Weather.desktop': <{'position': <2>}>,
'org.gnome.clocks.desktop': <{'position': <3>}>,
'org.gnome.Maps.desktop': <{'position': <4>}>,
'org.gnome.Books.desktop': <{'position': <5>}>,
'org.gnome.Photos.desktop': <{'position': <6>}>,
'org.gnome.Totem.desktop': <{'position': <7>}>,
'org.gnome.Calculator.desktop': <{'position': <8>}>,
'org.gnome.gedit.desktop': <{'position': <9>}>,
'simple-scan.desktop': <{'position': <10>}>,
'gnome-control-center.desktop': <{'position': <11>}>,
'gnome-system-monitor.desktop': <{'position': <12>}>,
'org.gnome.Boxes.desktop': <{'position': <13>}>,
'org.gnome.Terminal.desktop': <{'position': <14>}>,
'Utilities': <{'position': <15>}>,
'org.gnome.Characters.desktop': <{'position': <16>}>,
'yelp.desktop': <{'position': <17>}>,
'org.gnome.Screenshot.desktop': <{'position': <18>}>,
'org.gnome.Cheese.desktop': <{'position': <19>}>,
'org.gnome.font-viewer.desktop': <{'position': <20>}>
}]
]]></default>
<default>[]</default>
<summary>Layout of the app picker</summary>
<description>
Layout of the app picker. Each entry in the array is a page. Pages are
@ -151,20 +132,6 @@
Keybinding to open the application menu.
</description>
</key>
<key name="shift-overview-up" type="as">
<default>["&lt;Super&gt;&lt;Alt&gt;Up"]</default>
<summary>Keybinding to shift between overview states</summary>
<description>
Keybinding to shift between session, window picker and app grid
</description>
</key>
<key name="shift-overview-down" type="as">
<default>["&lt;Super&gt;&lt;Alt&gt;Down"]</default>
<summary>Keybinding to shift between overview states</summary>
<description>
Keybinding to shift between app grid, window picker and session
</description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the “Show Applications” view</summary>
@ -230,14 +197,6 @@
<default>["&lt;Super&gt;9"]</default>
<summary>Switch to application 9</summary>
</key>
<key name="switch-realm" type="as">
<default>["&lt;Primary&gt;Tab"]</default>
<summary>Open Realm Switcher</summary>
</key>
<key name="switch-realm-backward" type="as">
<default>["&lt;Shift&gt;&lt;Primary&gt;Tab"]</default>
<summary>Open Realm Switcher Backwards</summary>
</key>
</schema>
<schema id="org.gnome.shell.app-switcher"

View File

@ -176,186 +176,7 @@
"-",
":",
"'",
"@",
" ๎",
"๏",
"๛",
"๚"
]
]
]
},
{
"level": "shift",
"mode": "latched",
"rows": [
[
[
"+"
],
[
"๑"
],
[
"๒"
],
[
"๓"
],
[
"๔"
],
[
"ู"
],
[
"฿"
],
[
"๕"
],
[
"๖"
],
[
"๗"
],
[
"๘"
],
[
"๙"
]
],
[
[
""
],
[
"\""
],
[
"ฎ"
],
[
"ฑ"
],
[
"ธ"
],
[
"ํ"
],
[
"๊"
],
[
"ณ"
],
[
"ฯ"
],
[
"ญ"
],
[
"ฐ"
],
[
","
]
],
[
[
"ฤ"
],
[
"ฆ"
],
[
"ฏ"
],
[
"โ"
],
[
"ฌ"
],
[
"็"
],
[
"๋"
],
[
"ษ"
],
[
"ศ"
],
[
"ซ"
],
[
"."
],
[
"ฅ"
]
],
[
[
"("
],
[
")"
],
[
"ฉ"
],
[
"ฮ"
],
[
"ฺ"
],
[
"์"
],
[
"?"
],
[
"ฒ"
],
[
"ฬ"
],
[
"ฦ"
]
],
[
[
","
],
[
" "
],
[
".",
"#",
"!",
",",
"?",
"-",
":",
"'",
"@",
" ๎",
"๏",
"๛",
"๚"
"@"
]
]
]

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
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="24"
height="24"
viewBox="0 0 24 24.000001"
version="1.1"
id="svg19258">
<defs
id="defs19252" />
<metadata
id="metadata19255">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="g834"
transform="rotate(-90,-246.75894,471.75774)"
style="fill:#241f31">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#241f31;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 213.0007,724.40348 -10.3711,7.3945 v 0 a 1.5,1.5 0 0 0 -0.6308,1.2187 v 1.5 h 1.5 a 1.5,1.5 0 0 0 0.8711,-0.2793 l 8.6289,-6.1523 8.6289,6.1523 a 1.5,1.5 0 0 0 0.8711,0.2793 h 1.5 v -1.5 a 1.5,1.5 0 0 0 -0.6309,-1.2187 v 0 z"
id="path832" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
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="24"
height="24"
viewBox="0 0 24 24.000001"
version="1.1"
id="svg19258">
<defs
id="defs19252" />
<metadata
id="metadata19255">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="g872"
transform="matrix(0,-1,-1,0,742.51668,224.9988)"
style="fill:#241f31">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#241f31;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 213.0007,724.40348 -10.3711,7.3945 v 0 a 1.5,1.5 0 0 0 -0.6308,1.2187 v 1.5 h 1.5 a 1.5,1.5 0 0 0 0.8711,-0.2793 l 8.6289,-6.1523 8.6289,6.1523 a 1.5,1.5 0 0 0 0.8711,0.2793 h 1.5 v -1.5 a 1.5,1.5 0 0 0 -0.6309,-1.2187 v 0 z"
id="path870" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -11,32 +11,7 @@ stage {
}
.toggle-switch { width: 48px; }
.toggle-switch {
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"); }
}
//force opaque panel
#panel {
&.login-screen,
&.unlock-screen,
&:overview {
background-color: #000;
.panel-corner {
-panel-corner-opacity: 1;
}
}
.panel-button {
color: #fff !important;
}
}
//thumbnail app icons no dropshadow and forced color
.window-picker .icon-dropshadow {
icon-shadow: none;
background-color: $osd_bg_color;
padding: $base_padding * 2;
border-radius: $modal_radius;
.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"); }
}

View File

@ -11,6 +11,6 @@ will then be synchronized periodically before releases.
GNOME Shell Sass is distributed under the terms of the GNU General Public
License, version 2 or later. See the [COPYING][license] file for details.
[shell-subtree]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/HEAD/data/theme/gnome-shell-sass
[shell-subtree]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/master/data/theme/gnome-shell-sass
[sass-repo]: https://gitlab.gnome.org/GNOME/gnome-shell-sass
[license]: COPYING

View File

@ -28,7 +28,6 @@ $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));
$system_bg_color: desaturate(#241f31,100%); //neutralize the HIG color
//insensitive state derived colors
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);

View File

@ -31,7 +31,7 @@ $base_margin: 4px;
$base_spacing: 6px;
// border radii
$base_border_radius: 8px;
$base_border_radius: 5px;
$modal_radius:$base_border_radius * 2;
@ -76,7 +76,7 @@ stage {
%osd_panel {
color: $osd_fg_color;
background-color: $osd_bg_color;
//border: 1px solid $osd_outer_borders_color;
border: 1px solid $osd_outer_borders_color;
border-radius: $base_border_radius * 2 + 4px;
padding: $base_padding * 2;
}
@ -85,7 +85,8 @@ stage {
// for the dash and workspace switcher
%overview_panel {
color: $osd_fg_color;
background-color: transparentize($osd_fg_color, 0.9);
background-color: transparentize($osd_bg_color, 0.2);
border: 1px solid $osd_outer_borders_color;
}
// icon tiles
@ -129,8 +130,8 @@ stage {
border-bottom-width: 0;
&:insensitive { @include button(insensitive, $shadow: none); }
&:focus { @include button(focus, $shadow: none); }
&:hover { @include button(hover, $shadow: none); }
&:focus { @include button(focus, $shadow: none); }
&:active { @include button(active, $shadow: none); }
// radius is 2 pixel less to fit in bubble

View File

@ -46,7 +46,7 @@
border-color: if($fc==$selected_bg_color,
$selected_borders_color,
darken($fc,35%));
box-shadow: inset 0 0 0 2px $fc;
box-shadow: inset 0 0 0 1px $fc;
}
@if $t==hover { }
@if $t==insensitive {
@ -79,7 +79,7 @@
@function draw_button_hilight_color($c) {
//
// calculate the right top highlight color for buttons
// calculate the right top hilight color for buttons
//
// $c: base color;
//
@ -218,8 +218,7 @@
&:drop {
.overview-icon {
border: 2px solid $selected_bg_color; //already 2px transparent so no jumping
background-color: transparentize($selected_bg_color, .8);
background-color: transparentize($selected_bg_color, .15);
}
}

View File

@ -26,7 +26,6 @@ $osd_borders_color: rgba(0,0,0, 0.7);
$osd_outer_borders_color: rgba(255,255,255, 0.1);
$shadow_color: rgba(0,0,0, 0.1);
$system_bg_color: desaturate(#241f31,100%); //neutralize the HIG color
//insensitive state derived colors
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);

View File

@ -37,8 +37,8 @@
@import 'widgets/window-picker';
@import 'widgets/search-entry';
@import 'widgets/search-results';
@import 'widgets/dash';
@import 'widgets/app-grid';
@import 'widgets/dash';
@import 'widgets/workspace-thumbnails';
// A11y / misc
@import 'widgets/a11y';
@ -49,5 +49,3 @@
// Lock / login screens
@import 'widgets/login-dialog';
@import 'widgets/screen-shield';
@import 'widgets/realms';

View File

@ -4,14 +4,10 @@ $app_icon_size: 96px;
// app icons
.icon-grid {
row-spacing: $base_spacing * 2;
column-spacing: $base_spacing * 2;
row-spacing: $base_spacing * 6;
column-spacing: $base_spacing * 6;
max-row-spacing: $base_spacing * 12;
max-column-spacing: $base_spacing * 12;
page-padding-top: $base_padding * 4;
page-padding-bottom: $base_padding * 4;
page-padding-left: $base_padding * 2;
page-padding-right: $base_padding * 2;
}
/* App Icons */
@ -34,15 +30,16 @@ $app_grid_fg_color: #fff;
/* App Folders */
.app-well-app.app-folder {
background-color: $dash_background_color;
background-color: transparentize($osd_bg_color, 0.8);
border-radius: $base_border_radius + 4px; // same as %icon_tile
}
// expanded folder
.app-folder-dialog { //style like the dash
.app-folder-dialog {
border-radius: $modal_radius * 1.5;
background-color: $dash_background_color;
padding: 12px 0px 12px 0px;
border: 1px solid $osd_outer_borders_color;
background-color: transparentize(darken($osd_bg_color,10%), 0.05);
padding: 12px;
& .folder-name-container {
padding: 24px 36px 0;
@ -74,14 +71,14 @@ $app_grid_fg_color: #fff;
& .icon-grid {
row-spacing: $base_spacing * 2;
column-spacing: $base_spacing * 5;
page-padding-top: 0;
page-padding-bottom: 0;
page-padding-left: 0;
page-padding-right: 0;
}
& .page-indicators {
margin-bottom: 18px;
.page-indicator {
padding: 15px 12px;
}
}
}
.app-folder-dialog-container {
@ -90,6 +87,13 @@ $app_grid_fg_color: #fff;
height: 620px;
}
.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;
@ -108,13 +112,14 @@ $app_grid_fg_color: #fff;
}
// right-click app menu
.app-menu {
.app-menu,
.app-well-menu {
max-width: 27.25em;
}
// App Grid pagination indicators
.page-indicator {
padding: $base_padding $base_padding * 2 0;
padding: 15px 20px;
.page-indicator-icon {
width: 10px;
@ -124,8 +129,10 @@ $app_grid_fg_color: #fff;
}
}
.apps-scroll-view {
padding: 0;
// Some hacks I don't even know
.all-apps {
// horizontal padding to make sure scrollbars or dash don't overlap content
padding: 0px 88px 10px 88px;
}
// shutdown and other actions in the grid
@ -135,33 +142,3 @@ $app_grid_fg_color: #fff;
border-radius: 99px;
icon-size: $app_icon_size * 0.5;
}
.page-navigation-hint {
width: 300px;
&.dnd {
background: rgba(255, 255, 255, 0.1);
}
&.next:ltr,
&.previous:rtl {
background-gradient-start: rgba(255, 255, 255, 0.05);
background-gradient-end: transparent;
background-gradient-direction: horizontal;
border-radius: 15px 0px 0px 15px;
}
&.previous:ltr,
&.next:rtl {
background-gradient-start: transparent;
background-gradient-end: rgba(255, 255, 255, 0.05);
background-gradient-direction: horizontal;
border-radius: 0px 15px 15px 0px;
}
}
.page-navigation-arrow {
margin: 6px;
width: 24px;
height: 24px;
}

View File

@ -14,5 +14,5 @@
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 5px rgba(black, 0.8);
icon-shadow: 0 1px 2px rgba(black, 0.4);
}

View File

@ -1,11 +1,11 @@
/* Date/Time Menu */
.clock-display-box {
spacing: 2px;
spacing: $base_spacing / 2;
.clock {
padding-left: $base_padding * 2;
padding-right: $base_padding * 2;
padding-left: $base_padding;
padding-right: $base_padding;
}
}
@ -170,6 +170,7 @@
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%);
@ -231,9 +232,7 @@
color: $fg_color;
font-feature-settings: "tnum";
@include fontsize($base_font_size);
&:ltr { text-align: right; }
&:rtl { text-align: left; }
text-align: right;
}
// timezone offset label

View File

@ -1,18 +1,20 @@
/* Dash */
$dash_background_color: #3b3b3b;
$dash_placeholder_size: 32px;
$dash_padding: $base_padding + 4px; // 10px
$dash_spacing: $base_padding / 4;
$dash_bottom_margin: $base_margin * 4;
$dash_spacing: $base_padding + 4px;
$dash_border_radius: $modal_radius * 1.5;
#dash {
@extend %overview_panel;
@include fontsize($base_font_size - 2);
margin-top: $base_spacing * 3;
padding: 0 $dash_padding;
padding: ($dash_spacing / 2) 0;
border-radius: 0 $dash_border_radius $dash_border_radius 0;
border-left-width: 0;
&:rtl {
border-radius: $dash_border_radius 0 0 $dash_border_radius;
border-right-width: 0;
}
.placeholder {
// background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
@ -25,38 +27,23 @@ $dash_border_radius: $modal_radius * 1.5;
width: $dash_placeholder_size;
height: $dash_placeholder_size;
}
.overview-icon {
padding: $dash_padding / 2;
}
}
.dash-background {
background-color: $dash_background_color;
margin-bottom: $dash_bottom_margin;
padding: $dash_padding;
border-radius: $dash_border_radius;
}
// Dash Items
.dash-item-container .app-well-app, .show-apps {
padding: $dash_padding $dash_spacing $dash_padding + $dash_bottom_margin;
}
.dash-separator {
width: 1px;
margin: 0 ($dash_spacing + ($dash_padding / 2)) $dash_bottom_margin;
background-color: transparentize($osd_fg_color,0.7);
.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;
background-color: $osd_bg_color;
border-radius: 99px;
padding: $base_padding $base_padding * 2;
padding: $base_padding $base_padding + 2px;
text-align: center;
-y-offset: $base_margin * 3; // distance from the dash edge
-x-offset: $base_margin * 2; // distance from the dash edge
}
// Show apps button
@ -66,8 +53,9 @@ $dash_border_radius: $modal_radius * 1.5;
&:focus,
&:checked {
.overview-icon {
background-color: transparentize($osd_bg_color,0.5);
background-color: darken($osd_bg_color,10%);
color: $fg_color;
}
}
}

View File

@ -38,7 +38,7 @@
font-size: 18pt;
font-weight: 800;
&.lightweight {
&.leightweight {
font-size: 13pt;
font-weight: 800;
}
@ -135,6 +135,10 @@
spacing: 8px;
margin-bottom: 6px;
.polkit-dialog-user-icon {
border-radius: 99px;
background-size: contain;
}
.polkit-dialog-user-root-label { color: $warning_color; }
}
@ -162,12 +166,3 @@
.audio-selection-device-icon {
icon-size: $base_icon_size * 4;
}
/* Welcome dialog */
.welcome-dialog-image {
background-image: url("resource:///org/gnome/shell/theme/gnome-shell-start.svg");
background-size: contain;
/* Reasonable maximum dimensions */
height: 300px;
width: 300px;
}

View File

@ -3,7 +3,7 @@
StEntry {
border-radius: $base_border_radius;
padding: 8px;
border-width: 0;
border-width: 1px;
color: $fg_color;
@include entry(normal);
//&:hover { @include entry(hover);}

View File

@ -5,19 +5,18 @@
max-width: 23em;
}
.login-dialog,
.unlock-dialog {
.login-dialog {
//reset
border: none;
background-color: transparent;
$_gdm_bg: $system_bg_color;
$_gdm_bg: lighten(#2e3436, 19%);
StEntry {
@if $variant=='dark' {
$_gdm_entry_bg: darken($system_bg_color, 3%);
$_gdm_entry_bg: transparentize(lighten(desaturate(#241f31, 20%), 2%), 0.5);
background-color: $_gdm_entry_bg;
color: $fg_color;
color: $osd_fg_color;
}
}
@ -25,9 +24,9 @@
.modal-dialog-button {
padding: 4px 18px;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
background-color: darken($system_bg_color, 3%);
border-color: darken($system_bg_color, 3%);
color: $osd_fg_color;
background-color: $_gdm_bg;
border-color: $_gdm_bg;
color: $fg_color;
$_hover_c: lighten($_gdm_bg, 5%);
&:hover, &:focus {
@ -44,7 +43,7 @@
@include button(insensitive);
border-color: darken($_gdm_bg, 5%);
background-color: darken($_gdm_bg, 5%);
color: transparentize($osd_fg_color, 0.3);
color: transparentize($fg_color, 0.3);
}
&:default {
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
@ -77,8 +76,8 @@
border-radius: 99px;
width: $base_icon_size * 2;
height: $base_icon_size * 2;
border-color: darken($system_bg_color, 3%);
background-color: darken($system_bg_color, 3%);
border-color: transparentize($bg_color,0.7);
background-color: transparentize($bg_color,0.7);
StIcon { icon-size: $base_icon_size; }
}
@ -93,6 +92,7 @@
.login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { width: 23em; spacing: 5px; }
.login-dialog-message { text-align: center; }
.login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
.login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label {
padding-left: 2px;
@ -138,10 +138,11 @@
.user-widget.horizontal .user-widget-label {
@include fontsize($base_font_size + 2);
font-weight: bold;
text-align: left;
padding-left: 15px;
&:ltr { padding-left: 14px; text-align: left; }
&:rtl { padding-right: 14px; text-align: right; }
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.user-widget.vertical .user-widget-label {
@ -151,11 +152,6 @@
padding-top: 16px;
}
.login-dialog-timed-login-indicator {
height: 2px;
background-color: darken($fg_color,40%);
}
.login-dialog-prompt-layout {
padding-top: 24px;
padding-bottom: 12px;

View File

@ -25,20 +25,6 @@
// NOTE: remove the padding if notification_bubble could remove margin for drop shadow
padding: $base_margin;
spacing: $base_spacing * 2;
.dnd-button {
// We need this because the focus outline isn't inset like for the buttons
// so the dnd button would grow when it gets focus if we didn't change only
// its color when focusing.
border-width: 2px;
border-color: transparent;
border-radius: 99px;
border-style: solid;
&:focus {
border-color: transparentize($selected_bg_color, 0.4);
}
}
}
// message bubbles
@ -85,11 +71,9 @@
> .event-time {
color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2);
text-align: right;
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: 0.13em;
&:ltr { text-align: right };
&:rtl { text-align: left };
}
}
@ -113,7 +97,7 @@
/* Media Controls */
.message-media-control {
padding: $base_padding * 2 1.64em; // $base_padding * 4 = 24px
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

View File

@ -9,7 +9,6 @@
background-size: contain;
color: $osd_fg_color;
border-radius: 99px;
icon-size: $base_icon_size * 4; // 64px
&:hover {
color: lighten($osd_fg_color,30%);
}
@ -17,12 +16,6 @@
& StIcon {
background-color: transparentize($osd_fg_color,0.95);
border-radius: 99px;
padding: $base_padding * 2 ; // 12px
width: $base_icon_size * 2.5; height: $base_icon_size * 2.5; // 40px;
}
&.user-avatar {
border: 2px $osd_fg_color;
}
}
@ -37,6 +30,15 @@
}
}
.user-widget.horizontal .user-icon {
icon-size: $base_icon_size * 4; // 64px
& StIcon {
padding: $base_padding * 2 ; // 12px
width: $base_icon_size * 2.5; height: $base_icon_size * 2.5; // 40px;
}
}
.lightbox { background-color: black; }
.flashspot { background-color: white; }
@ -51,9 +53,3 @@
@include fontsize($base_font_size - 1);
color: $warning_color;
}
/* Workspace animation */
.workspace-animation {
background-color: $system_bg_color;
}

View File

@ -1,4 +1,4 @@
/* Notifications & Message Tray */
/* Notifications & Mesage Tray */
$notification_banner_height: 64px;
$notification_banner_width: 34em;

View File

@ -1,11 +1,8 @@
/* OVERVIEW */
.controls-manager, .secondary-monitor-workspaces {
spacing: $base_spacing * 2;
}
#overviewGroup {
background-color: $system_bg_color;
#overview {
spacing: 24px;
background-color: transparent;
}
.overview-controls {

View File

@ -3,36 +3,43 @@
$panel_corner_radius: $base_border_radius+1;
$panel_bg_color: #000;
$panel_fg_color: #ddd;
$panel_height: 2.2em;
$panel_transition_duration: 250ms; // same as the overview transition duration
$panel_fg_color: #ccc;
$panel_height: 1.86em;
#panel {
background-color: $panel_bg_color;
font-weight: bold;
height: $panel_height;
font-feature-settings: "tnum";
transition-duration: $panel_transition_duration;
// transparent panel on lock & login screens
&.unlock-screen,
&.login-screen,
&:overview {
&.login-screen {
background-color: transparent;
.panel-corner {
-panel-corner-opacity: 0;
-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;
-panel-corner-opacity: 1;
transition-duration: $panel_transition_duration;
&:active, &:overview, &:focus {
-panel-corner-border-color: lighten($selected_bg_color,5%);
}
}
// panel menus
@ -41,69 +48,53 @@ $panel_transition_duration: 250ms; // same as the overview transition duration
color: $panel_fg_color;
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: $base_padding;
transition-duration: 150ms;
border: 3px solid transparent;
border-radius: 99px;
&.clock-display {
.clock {
transition-duration: 150ms;
border: 3px solid transparent;
border-radius: 99px;
}
&:hover {
color: lighten($panel_fg_color, 20%);
}
&:hover, &:active, &:overview, &:focus, &:checked {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.20);
// The clock display needs to have the background on .clock because
// we want to exclude the do-not-disturb indicator from the background
&.clock-display {
box-shadow: none;
.clock {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.20);
}
}
&:active, &:overview, &:focus, &:checked {
color: lighten($panel_fg_color, 20%);
}
// status area icons
.system-status-icon {
icon-size: $base_icon_size;
padding: $base_padding - 1px;
margin: 0 $base_margin;
}
.panel-status-indicators-box .system-status-icon,
.panel-status-menu-box .system-status-icon {
margin: 0;
}
// app menu icon
.app-menu-icon {
margin-left: $base_margin;
margin-right: $base_margin;
-st-icon-style: symbolic;
// dimensions of the icon are hardcoded
}
&#panelActivities {
-natural-hpadding: $base_padding * 3;
// lock & login screen styles
.unlock-screen &,
.login-screen & {
color: lighten($fg_color, 10%);
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
}
}
&.unlock-screen,
&.login-screen,
&:overview {
.panel-button {
&:hover, &:active, &:overview, &:focus, &:checked {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15);
.panel-button {
&:active, &:overview, &:focus, &:checked {
// Trick due to St limitations. It needs a background to draw a box-shadow
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
}
}
&.clock-display {
box-shadow: none;
.panel-button.clock-display {
// Move highlight from .panel-button to .clock
&:active, &:overview, &:focus, &:checked {
box-shadow: none;
.clock {
box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.15);
}
}
.clock {
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
}
}
}
@ -128,8 +119,3 @@ $panel_transition_duration: 250ms; // same as the overview transition duration
spacing: $base_spacing;
.label-shadow { color: transparent; }
}
#appMenu .panel-status-menu-box {
padding: 0 $base_padding;
spacing: $base_spacing;
}

View File

@ -76,10 +76,8 @@ $popover_arrow_height: 12px;
// container for radio and check boxes
.popup-menu-ornament {
text-align: right;
width: 1.2em;
&:ltr { text-align: right };
&:rtl { text-align: left };
}
// separator

View File

@ -1,17 +0,0 @@
.realm-switch-label {
font-size: 36px;
font-weight: bold;
color: #ffffff;
background-color: rgba(10, 10, 10, 0.7);
border-radius: 5px;
padding: .5em;
}
.realm-frame-label {
font-size: 12pt;
font-weight: bold;
}
.realm-config-icon {
color: #8e8e80;
}

View File

@ -66,7 +66,7 @@
}
#lockDialogGroup {
background-color: $system_bg_color;
background-color: lighten(#2e3436, 8%);
}
#unlockDialogNotifications {

View File

@ -10,16 +10,17 @@ $search_entry_height: 36px;
border-radius: $search_entry_height * 0.5; // half the height
color: transparentize($fg_color,0.3);
background-color: $bg_color;
margin-top: $base_spacing * 2;
margin-bottom: $base_spacing;
border-width: 2px;
border-color: transparent;
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;

View File

@ -16,7 +16,7 @@ $slider_size: 15px;
-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 handler
// 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);

View File

@ -3,50 +3,63 @@
$window_picker_spacing: $base_spacing; // 6px
$window_picker_padding: $base_padding * 2; // 12px
$window_thumbnail_label_color: transparentize($osd_bg_color, 0.4);
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
$window_close_button_size: 30px;
$window_close_button_size: 24px;
$window_close_button_padding: 3px;
$window_clone_border_size: 6px;
// Window picker
.window-picker {
// Space between window thumbnails
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: $window_clone_border_size;
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-radius: 99px;
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: $osd_bg_color;
color: $osd_fg_color;
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);
transition-duration: 300ms;
& StIcon { icon-size: 24px; }
&:hover {
background-color: lighten($osd_bg_color, 15%);
background-color: lighten($selected_bg_color, 5%);
}
&:active {
color: transparentize($osd_fg_color, 0.2);
background-color: darken($osd_bg_color, 5%);
background-color: darken($selected_bg_color, 5%);
}
}
.workspace-background {
// keep in sync with BACKGROUND_CORNER_RADIUS_PIXELS in workspace.js
border-radius: 30px;
box-shadow: 0 4px 16px 4px transparentize(darken($osd_bg_color, 30%), 0.7);
}

View File

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

View File

@ -1,343 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
id="svg8"
version="1.1"
viewBox="0 0 600 400"
height="400"
width="600"
sodipodi:docname="gnome-shell-start.svg">
<defs
id="defs2">
<linearGradient
id="a">
<stop
offset="0"
stop-color="#eef4fc"
id="stop3"
style="stop-color:#b2cdf1;stop-opacity:1" />
<stop
offset="1"
stop-color="#fff"
id="stop5" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient10562"
id="linearGradient10564"
x1="-1179.9999"
y1="1314.5198"
x2="-940.00006"
y2="1314.5198"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3993149,0,0,1.3993149,1306.25,-919.42736)" />
<linearGradient
inkscape:collect="always"
id="linearGradient10562">
<stop
style="stop-color:#3580e4;stop-opacity:1"
offset="0"
id="stop10558" />
<stop
style="stop-color:#8abfdd;stop-opacity:1"
offset="1"
id="stop10560" />
</linearGradient>
<clipPath
id="e-3"
clipPathUnits="userSpaceOnUse">
<path
d="m 65,177 c -18.502,0 -33.5,14.998 -33.5,33.5 0.008,7.371 4.131,15.807 11.388,23.526 l 12.617,13.171 H 75.02 l 12.137,-13.245 c 6.636,-7.059 11.33,-16.117 11.344,-23.452 0,-18.502 -14.998,-33.5 -33.5,-33.5 z"
style="marker:none"
fill="#ffffff"
stroke-width="2"
id="path34-6" />
</clipPath>
<radialGradient
r="33.5"
fy="48.405998"
fx="79.091003"
cy="48.405998"
cx="79.091003"
gradientTransform="matrix(0.00476,1.62228,-1.43419,0.00422,141.702,-82.047)"
gradientUnits="userSpaceOnUse"
id="f-7"
xlink:href="#b" />
<linearGradient
id="b">
<stop
offset="0"
stop-color="#fff"
id="stop11" />
<stop
offset=".519"
stop-color="#fff"
id="stop13" />
<stop
offset=".734"
stop-color="#cfcfcf"
id="stop15" />
<stop
offset="1"
stop-color="#dcdcdc"
id="stop17" />
</linearGradient>
<radialGradient
r="12"
fy="54.102001"
fx="71.473999"
cy="54.102001"
cx="71.473999"
gradientTransform="matrix(4.50607,0,0,4.76661,-259.306,-59.706)"
gradientUnits="userSpaceOnUse"
id="g-2"
xlink:href="#c" />
<linearGradient
id="c">
<stop
offset="0"
stop-color="#ed686f"
id="stop20" />
<stop
offset=".865"
stop-color="#a51d2d"
id="stop22" />
<stop
offset="1"
stop-color="#e01b24"
id="stop24" />
</linearGradient>
<radialGradient
r="14.583"
fy="49.777"
fx="40.152"
cy="49.777"
cx="40.152"
gradientTransform="matrix(0.87016,4.27869,-2.56693,0.52204,148.394,-163.306)"
gradientUnits="userSpaceOnUse"
id="h-7"
xlink:href="#d" />
<linearGradient
id="d">
<stop
offset="0"
stop-color="#ed686f"
id="stop27" />
<stop
offset=".911"
stop-color="#a51d2d"
id="stop29" />
<stop
offset="1"
stop-color="#e01b24"
id="stop31" />
</linearGradient>
<radialGradient
r="14.583"
fy="49.777"
fx="40.152"
cy="49.777"
cx="40.152"
gradientTransform="matrix(0.87016,4.27869,-2.56693,0.52204,148.394,-163.306)"
gradientUnits="userSpaceOnUse"
id="i-6"
xlink:href="#d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient860"
id="linearGradient22"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.575111,0,0,1.575111,1217.8748,47.173672)"
x1="85"
y1="107.162"
x2="85"
y2="86" />
<linearGradient
id="linearGradient860">
<stop
offset="0"
stop-color="#eef4fc"
id="stop856"
style="stop-color:#c5dcf7;stop-opacity:1" />
<stop
offset="1"
stop-color="#fff"
id="stop858" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient860"
id="linearGradient24"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.1158457,0,0,2.1158457,1459.4994,-118.92278)"
x1="85"
y1="110.30392"
x2="85"
y2="86.986084" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient860"
id="linearGradient23"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5463767,0,0,1.5463767,655.03375,-16.075361)"
x1="85"
y1="107.162"
x2="85"
y2="82.13472" />
</defs>
<sodipodi:namedview
units="px"
borderlayer="true"
inkscape:showpageshadow="false"
showgrid="false"
inkscape:document-rotation="0"
inkscape:current-layer="layer1"
inkscape:document-units="px"
inkscape:cy="75.603256"
inkscape:cx="199.00314"
inkscape:zoom="0.98994949"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
borderopacity="1"
bordercolor="#383838"
pagecolor="#1f1f1f"
id="base"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-bbox="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true">
<inkscape:grid
type="xygrid"
id="grid900" />
</sodipodi:namedview>
<metadata
id="metadata5">
<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></dc:title>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1"
transform="translate(-620,9.4371882)">
<g
id="g4043"
transform="translate(-15.793175)">
<circle
style="fill:url(#linearGradient10564);fill-opacity:1;stroke:none;stroke-width:3.66905;stroke-linecap:round;stroke-linejoin:round"
id="path10517"
cx="-177.02397"
cy="920"
r="167.91774"
transform="rotate(-90)" />
<path
d="m 1066.6646,147.98131 c 12.3048,0.0174 23.474,7.19166 28.6008,18.37784 a 23.631877,23.631877 0 0 1 10.7762,-2.62748 c 12.4288,0.0178 22.7209,9.65384 23.5474,22.05492 h 0.08 c 8.6991,0 15.7508,7.05171 15.7508,15.75083 0,8.69911 -7.0522,15.75083 -15.7513,15.75083 h -88.2056 a 18.901933,18.901933 0 0 1 -18.9019,-18.901 18.901933,18.901933 0 0 1 12.6566,-17.81853 33.12417,33.12417 0 0 1 -0.056,-1.08246 c 0,-17.39824 14.1038,-31.50213 31.5025,-31.50213 z"
id="path10"
style="fill:url(#linearGradient22);stroke-width:0.577558" />
<g
id="g245"
transform="matrix(1.5161629,0,0,1.5161629,396.40481,-143.42807)">
<g
id="g126"
transform="matrix(0.75000161,0,0,0.75000161,154.45946,111.99828)">
<g
id="g265">
<g
transform="matrix(3.12129,0,0,2.9344,91.063695,-499.94397)"
clip-path="url(#e-3)"
id="g47-0">
<path
transform="translate(-8,156)"
d="M 73,21 C 54.498,21 39.5,35.998 39.5,54.5 39.508,61.871 43,68.922 46.44,74.879 L 58,98 H 88 L 99.605,74.79 C 103,68.91 106.485,61.835 106.5,54.5 106.5,35.998 91.502,21 73,21 Z"
style="fill:url(#f-7);marker:none"
fill="url(#f)"
id="path39-6" />
<path
d="m 64,177 c 0,0 -18.332,12.132 -18.332,30.989 0,14.571 16.174,46.011 16.174,46.011 H 67 c 0,0 1.333,-31.44 1.333,-46.011 C 68.333,189.132 64,177 64,177 Z"
fill="url(#g)"
id="path41-2"
style="fill:url(#g-2)" />
<path
transform="translate(-8,156)"
d="m 71.983,21.106 c -8.207,0.147 -16.328,3.285 -22.5,8.695 -6.174,5.409 -10.35,13.047 -11.574,21.163 -1.24,8.225 0.567,16.874 4.995,23.915 L 61.902,98 h 6.432 L 55.002,81.27 C 50.702,75.875 46.53,70.2 44.406,63.636 42.283,57.072 42.24,49.836 44.409,43.288 A 32.824,32.824 0 0 1 54.925,28.13 32.824,32.824 0 0 1 71.983,21.105 Z"
fill="url(#h)"
id="path43-6"
style="fill:url(#h-7)" />
<path
transform="matrix(-1,0,0,1,137.16,155.823)"
d="M 73.003,21.303 C 65.294,19.756 57.033,21.149 50.257,25.138 43.481,29.127 38.255,35.675 35.867,43.167 A 32.484,32.484 0 0 0 35.11,59.972 32.484,32.484 0 0 0 42.904,74.879 L 54.11,98 H 67.493 L 54.16,74.356 C 51.292,69.269 48.603,63.95 47.733,58.175 46.863,52.4 47.769,46.404 50.107,41.052 54.28,31.502 62.943,24.03 73.002,21.304 Z"
fill="url(#i)"
id="path45-1"
style="fill:url(#i-6)" />
</g>
<path
style="marker:none"
d="m 271.0607,256.22128 v 19.397 a 9.702,9.702 0 0 0 9.724,9.726 h 26.326 c 5.388,0 8.594,-4.457 9.725,-9.726 v -19.397 z"
fill="#e5a50a"
id="path49-8" />
<path
style="marker:none"
d="m 271.0607,252.06028 v 19.397 a 9.702,9.702 0 0 0 9.724,9.724 h 26.326 c 5.388,0 8.594,-4.455 9.725,-9.724 v -19.397 z"
fill="#e5a50a"
id="path51-7" />
<path
style="marker:none"
d="m 300.1907,252.06028 v 29.121 h 6.92 c 5.388,0 8.594,-4.455 9.725,-9.724 v -19.397 z"
fill="#f3af0b"
id="path53-9" />
</g>
</g>
</g>
<path
style="font-variation-settings:normal;fill:url(#linearGradient24);fill-opacity:1;stroke-width:0.822282"
d="m 1051.0577,24.011554 a 37.111799,37.111799 0 0 0 -36.9465,35.120895 c -13.3251,2.089947 -23.45686,13.564137 -23.45686,27.494149 0,15.421302 12.41476,27.836692 27.83666,27.836692 h 72.3273 c 11.9284,0 21.5316,-9.60251 21.5316,-21.530902 0,-11.928386 -9.6032,-21.532163 -21.5316,-21.532163 h -3.9868 a 37.111799,37.111799 0 0 0 1.4509,-10.27624 37.111799,37.111799 0 0 0 -37.1118,-37.111798 37.111799,37.111799 0 0 0 -0.1123,0 z"
id="path12" />
<path
d="m 803.48555,82.893284 c -12.0805,0.0171 -23.046,7.06046 -28.0791,18.042576 a 23.200767,23.200767 0 0 0 -10.5796,-2.579546 c -12.2021,0.0175 -22.3064,9.477716 -23.1179,21.652566 h -0.079 c -8.5404,0 -15.4634,6.92307 -15.4634,15.46349 0,8.54042 6.9235,15.46349 15.4639,15.46349 h 86.5965 a 18.55711,18.55711 0 0 0 18.5571,-18.55619 18.55711,18.55711 0 0 0 -12.4257,-17.49347 32.519894,32.519894 0 0 0 0.055,-1.06272 c 0,-17.080836 -13.8466,-30.927426 -30.9279,-30.927426 z"
id="path21"
style="fill:url(#linearGradient23);fill-opacity:1;stroke-width:0.999999" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -29,7 +29,6 @@ theme_sources = files([
'gnome-shell-sass/widgets/_overview.scss',
'gnome-shell-sass/widgets/_panel.scss',
'gnome-shell-sass/widgets/_popovers.scss',
'gnome-shell-sass/widgets/_realms.scss',
'gnome-shell-sass/widgets/_screen-shield.scss',
'gnome-shell-sass/widgets/_scrollbars.scss',
'gnome-shell-sass/widgets/_search-entry.scss',
@ -43,21 +42,20 @@ theme_sources = files([
'gnome-shell-sass/widgets/_workspace-thumbnails.scss'
])
stylesheets = [
'gnome-shell-high-contrast.css',
'gnome-shell.css'
styles = [
'gnome-shell-high-contrast',
'gnome-shell'
]
foreach stylesheet: stylesheets
if not fs.exists(stylesheet)
sassc = find_program('sassc')
theme_deps += custom_target(stylesheet,
input: fs.replace_suffix(stylesheet, '.scss'),
output: stylesheet,
command: [
sassc, '-a', '@INPUT@', '@OUTPUT@'
],
depend_files: theme_sources)
endif
theme_deps = []
foreach style: styles
theme_deps += custom_target('style-' + style,
input: '@0@.scss'.format(style),
output: '@0@.css'.format(style),
command: [
sassc, '-a', '@INPUT@', '@OUTPUT@'
],
depend_files: theme_sources)
endforeach

View File

@ -1,106 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="a" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="b">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.3"/>
</g>
</mask>
<clipPath id="c">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="d">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="e">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="f">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="g">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="h">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="i">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="j">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="k">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="l">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="m">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="n">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="o">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="p">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.3"/>
</g>
</mask>
<clipPath id="q">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="r">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="s">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<g clip-path="url(#c)" mask="url(#b)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 562.460938 212.058594 h 10.449218 c -1.183594 0.492187 -1.296875 2.460937 0 3 h -10.449218 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#e)" mask="url(#d)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 16 632 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#g)" mask="url(#f)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 17 631 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 18 634 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#k)" mask="url(#j)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 16 634 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#m)" mask="url(#l)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 17 635 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#o)" mask="url(#n)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 19 635 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#q)" mask="url(#p)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 136 660 v 7 h 7 v -7 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#s)" mask="url(#r)" transform="matrix(1 0 0 1 -380 -376)">
<path d="m 219 642 h 3 v 12 h -3 z m 0 0" fill="#2e3436"/>
</g>
<path d="m 1.53125 0.46875 l -1.0625 1.0625 l 14 14 l 1.0625 -1.0625 l -1.945312 -1.945312 c 0.847656 -0.527344 1.414062 -1.449219 1.414062 -2.523438 v -6 c 0 -1.660156 -1.339844 -3 -3 -3 h -8 c -0.554688 0 -1.070312 0.160156 -1.515625 0.421875 z m 2.53125 2.53125 h 0.199219 l -0.097657 0.097656 z m 2.675781 0 h 0.699219 l -1.6875 1.6875 l -0.351562 -0.351562 z m 2.824219 0 h 1.230469 l -3.367188 3.363281 l -0.613281 -0.613281 z m 2.609375 0.035156 c 0.316406 0.054688 0.578125 0.246094 0.714844 0.523438 l -4.132813 4.132812 l -0.617187 -0.617187 z m -11.171875 1.023438 v 5.941406 c 0 1.660156 1.339844 3 3 3 h 5.941406 l -2 -2 h -1.785156 l 0.894531 -0.894531 l -0.355469 -0.355469 l -1.25 1.25 h -1.238281 l 1.867188 -1.867188 l -0.707031 -0.707031 l -2.160157 2.15625 c -0.121093 -0.164062 -0.207031 -0.359375 -0.207031 -0.582031 v -0.4375 l 1.75 -1.75 l -1.0625 -1.0625 l -0.6875 0.6875 v -0.699219 l 0.339844 -0.339843 z m 12 0.09375 v 5.847656 c 0 0.535156 -0.417969 0.960938 -0.949219 0.988281 l -2.941406 -2.941406 z m -5 9.847656 c -5 0 -5 1 -5 1 c 0 1 1 1 1 1 h 8 c 0.328125 0 0.539062 -0.109375 0.6875 -0.253906 l -1.542969 -1.546875 c -0.730469 -0.113281 -1.71875 -0.199219 -3.144531 -0.199219 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -1,109 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="a" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="b">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.3"/>
</g>
</mask>
<clipPath id="c">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="d">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="e">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="f">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="g">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="h">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="i">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="j">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="k">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="l">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="m">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="n">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.05"/>
</g>
</mask>
<clipPath id="o">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="p">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.3"/>
</g>
</mask>
<clipPath id="q">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<mask id="r">
<g filter="url(#a)">
<path d="m 0 0 h 16 v 16 h -16 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="s">
<path d="m 0 0 h 1024 v 800 h -1024 z"/>
</clipPath>
<g clip-path="url(#c)" mask="url(#b)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 562.460938 212.058594 h 10.449218 c -1.183594 0.492187 -1.296875 2.460937 0 3 h -10.449218 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#e)" mask="url(#d)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 16 632 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#g)" mask="url(#f)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 17 631 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 18 634 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#k)" mask="url(#j)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 16 634 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#m)" mask="url(#l)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 17 635 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#o)" mask="url(#n)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 19 635 h 1 v 1 h -1 z m 0 0" fill="#2e3436" fill-rule="evenodd"/>
</g>
<g clip-path="url(#q)" mask="url(#p)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 136 660 v 7 h 7 v -7 z m 0 0" fill="#2e3436"/>
</g>
<g clip-path="url(#s)" mask="url(#r)" transform="matrix(1 0 0 1 -360 -376)">
<path d="m 219 642 h 3 v 12 h -3 z m 0 0" fill="#2e3436"/>
</g>
<g fill="#2e3436">
<path d="m 4 1 c -1.660156 0 -3 1.339844 -3 3 v 6 c 0 1.660156 1.339844 3 3 3 h 8 c 1.660156 0 3 -1.339844 3 -3 v -6 c 0 -1.660156 -1.339844 -3 -3 -3 z m 0 2 h 0.261719 l -1.261719 1.261719 v -0.261719 c 0 -0.554688 0.445312 -1 1 -1 z m 2.738281 0 h 0.699219 l -4.4375 4.4375 v -0.699219 z m 2.824219 0 h 1.230469 l -7.585938 7.582031 c -0.121093 -0.164062 -0.207031 -0.359375 -0.207031 -0.582031 v -0.4375 z m 2.609375 0.035156 c 0.316406 0.054688 0.578125 0.246094 0.714844 0.523438 l -7.441407 7.441406 h -1.238281 z m 0.828125 1.121094 v 5.84375 c 0 0.554688 -0.445312 1 -1 1 h -5.84375 z m 0 0" fill-rule="evenodd"/>
<path d="m 8 14 c -5 0 -5 1 -5 1 c 0 1 1 1 1 1 h 8 c 1 0 1 -1 1 -1 s 0 -1 -5 -1 z m 0 0"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
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="24"
height="24"
viewBox="0 0 6.3499999 6.3500002"
version="1.1"
id="svg59656">
<defs
id="defs59650" />
<metadata
id="metadata59653">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="color:#bebebe;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Andale Mono';-inkscape-font-specification:'Andale Mono';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:#241f31;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.471289;marker:none;enable-background:new"
id="path10839-9"
d="m 1.5875,1.5875 h 0.2645834 c 0.00274,-3.18e-5 0.0055,-1.217e-4 0.00827,0 0.067456,0.00296 0.1349031,0.03402 0.181901,0.082682 L 3.1758323,2.8029916 4.3160156,1.670182 C 4.3862956,1.609196 4.4341976,1.589352 4.4979166,1.5875 H 4.7625 v 0.264583 c 0,0.075795 -0.00909,0.1456928 -0.066146,0.1984375 L 3.5644391,3.175 4.688086,4.3077474 C 4.737877,4.3575344 4.762498,4.4277227 4.7625,4.4979167 V 4.7625 H 4.4979167 C 4.4277225,4.7624974 4.3575325,4.7378673 4.3077475,4.6880859 L 3.1758323,3.5554004 2.0422526,4.688086 C 1.9924676,4.737878 1.9222747,4.7625 1.8520834,4.7625 H 1.5875 V 4.4979168 c -8e-7,-0.070191 0.024622,-0.1403827 0.074414,-0.1901693 L 2.7954938,3.175 1.6619141,2.0505208 C 1.6061553,1.9990249 1.581703,1.9263651 1.5875,1.8520833 Z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="27"
height="76"
id="svg11252"
version="1.1"
sodipodi:docname="dash-placeholder-horizontal.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)">
<metadata
id="metadata19">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview17"
showgrid="false"
inkscape:pagecheckerboard="true"
inkscape:zoom="12.473684"
inkscape:cx="38"
inkscape:cy="26.327004"
inkscape:current-layer="g99967"
inkscape:document-rotation="0" />
<defs
id="defs11254">
<radialGradient
xlink:href="#linearGradient39563-4-2"
id="radialGradient68155-2-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.3486842,24.5,341.84211)"
cx="49"
cy="488"
fx="49"
fy="488"
r="38" />
<linearGradient
id="linearGradient39563-4-2">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop39565-1-4" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop39567-7-9" />
</linearGradient>
<radialGradient
xlink:href="#linearGradient39573-6-1"
id="radialGradient68157-0-8"
gradientUnits="userSpaceOnUse"
cx="50.5"
cy="487.5"
fx="50.5"
fy="487.5"
r="10.5"
gradientTransform="matrix(1.2857143,0,0,1.2857143,8.571428,-114.78571)" />
<linearGradient
id="linearGradient39573-6-1">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop39575-5-6" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop39577-1-2" />
</linearGradient>
</defs>
<g
id="layer1"
transform="rotate(90,465.93109,104.43109)">
<g
id="g99967"
style="display:inline"
transform="translate(326,44.862171)">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.49375;fill:url(#radialGradient68155-2-3);fill-opacity:1;stroke:none;stroke-width:1;marker:none;enable-background:accumulate"
id="rect99969"
width="76"
height="2"
x="35.5"
y="511"
rx="0"
ry="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.43125;fill:url(#radialGradient68157-0-8);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.28571;marker:none;enable-background:accumulate"
id="path99971"
d="m 87,512.00001 c 0,7.45584 -6.044155,13.5 -13.5,13.5 -7.455844,0 -13.5,-6.04416 -13.5,-13.5 0,-7.45585 6.044156,-13.5 13.5,-13.5 7.455845,0 13.5,6.04415 13.5,13.5 z" />
<path
d="m 78.076923,512.00001 c 0,2.52776 -2.049159,4.57692 -4.576923,4.57692 -2.527766,0 -4.576923,-2.04916 -4.576923,-4.57692 0,-2.52777 2.049157,-4.57692 4.576923,-4.57692 2.527765,0 4.576923,2.04915 4.576923,4.57692 z"
id="path99973"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.435897;marker:none;enable-background:accumulate" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -3,8 +3,13 @@ private_headers = [
'gactionobservable.h',
'gactionobserver.h',
'shell-network-agent.h',
'shell-recorder-src.h'
]
if not enable_recorder
private_headers += 'shell-recorder.h'
endif
exclude_directories = [
'calendar-server',
'hotplug-sniffer',

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY version SYSTEM "version.xml">
@ -36,6 +36,10 @@
<xi:include href="xml/shell-tray-icon.xml"/>
<xi:include href="xml/shell-tray-manager.xml"/>
</chapter>
<chapter>
<title>Recorder</title>
<xi:include href="xml/shell-recorder.xml"/>
</chapter>
<chapter>
<title>Integration helpers and utilities</title>
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY version SYSTEM "version.xml">

View File

@ -23,7 +23,7 @@ Not only will that give you the very latest version of this rapidly
changing project, it will be much easier than get GNOME Shell and
its dependencies to build from tarballs.</description>
<homepage rdf:resource="https://wiki.gnome.org/Projects/GnomeShell" />
<support-forum rdf:resource="https://discourse.gnome.org/tags/shell" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
<download-page rdf:resource="http://download.gnome.org/sources/gnome-shell/" />
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/gnome-shell/issues/" />
@ -73,10 +73,4 @@ its dependencies to build from tarballs.</description>
<gnome:userid>gbsneto</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Marge Bot</foaf:name>
<gnome:userid>marge-bot</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@ -25,8 +25,6 @@ var ServiceImplementation = class {
// subclasses may override this to disable automatic shutdown
this._autoShutdown = true;
this._queueShutdownCheck();
}
// subclasses may override this to own additional names

View File

@ -1,7 +1,2 @@
.expander { padding: 12px; }
.expander.expanded { border: 0 solid @borders; border-bottom-width: 1px; }
.expander-toolbar {
border: 0 solid @borders;
border-top-width: 1px;
padding: 3px;
}
.expander-frame > * { border-top-width: 0; }
.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }

View File

@ -116,37 +116,27 @@ var ExtensionsService = class extends ServiceImplementation {
if (this._handleError(invocation, error))
return;
if (this._prefsDialog) {
this._handleError(invocation,
new Error('Already showing a prefs dialog'));
return;
}
const [serialized] = res;
const extension = ExtensionUtils.deserializeExtension(serialized);
this._prefsDialog = new ExtensionPrefsDialog(extension);
this._prefsDialog.connect('realize', () => {
let externalWindow = null;
const window = new ExtensionPrefsDialog(extension);
window.realize();
if (parentWindow)
externalWindow = Shew.ExternalWindow.new_from_handle(parentWindow);
let externalWindow = null;
if (externalWindow)
externalWindow.set_parent_of(this._prefsDialog.get_surface());
});
if (parentWindow)
externalWindow = Shew.ExternalWindow.new_from_handle(parentWindow);
if (externalWindow)
externalWindow.set_parent_of(window.window);
if (options.modal)
this._prefsDialog.modal = options.modal.get_boolean();
window.modal = options.modal.get_boolean();
this._prefsDialog.connect('close-request', () => {
delete this._prefsDialog;
this.release();
return false;
});
window.connect('destroy', () => this.release());
this.hold();
this._prefsDialog.show();
window.show();
invocation.return_value(null);
});
@ -166,6 +156,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
GTypeName: 'ExtensionPrefsDialog',
Template: 'resource:///org/gnome/Shell/Extensions/ui/extension-prefs-dialog.ui',
InternalChildren: [
'headerBar',
'stack',
'expander',
'expanderArrow',
@ -174,24 +165,24 @@ var ExtensionPrefsDialog = GObject.registerClass({
],
}, class ExtensionPrefsDialog extends Gtk.Window {
_init(extension) {
super._init({
title: extension.metadata.name,
});
super._init();
this._uuid = extension.uuid;
this._url = extension.metadata.url || '';
this._headerBar.title = extension.metadata.name;
this._actionGroup = new Gio.SimpleActionGroup();
this.insert_action_group('win', this._actionGroup);
this._initActions();
this._addCustomStylesheet();
this._gesture = new Gtk.GestureClick({
this._gesture = new Gtk.GestureMultiPress({
widget: this._expander,
button: 0,
exclusive: true,
});
this._expander.add_controller(this._gesture);
this._gesture.connect('released', (gesture, nPress) => {
if (nPress === 1)
@ -202,10 +193,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
this._expanderArrow.icon_name = this._revealer.reveal_child
? 'pan-down-symbolic'
: 'pan-end-symbolic';
this._syncExpandedStyle();
});
this._revealer.connect('notify::child-revealed',
() => this._syncExpandedStyle());
try {
ExtensionUtils.installImporter(extension);
@ -217,21 +205,13 @@ var ExtensionPrefsDialog = GObject.registerClass({
prefsModule.init(extension.metadata);
const widget = prefsModule.buildPrefsWidget();
this._stack.add_named(widget, 'prefs');
this._stack.add(widget);
this._stack.visible_child = widget;
} catch (e) {
this._setError(e);
logError(e, 'Failed to open preferences');
}
}
_syncExpandedStyle() {
if (this._revealer.reveal_child)
this._expander.add_css_class('expanded');
else if (!this._revealer.child_revealed)
this._expander.remove_css_class('expanded');
}
_setError(exc) {
this._errorView.buffer.text = `${exc}\n\nStack trace:\n`;
// Indent stack trace.
@ -263,8 +243,8 @@ var ExtensionPrefsDialog = GObject.registerClass({
enabled: false,
});
action.connect('activate', () => {
const clipboard = this.get_display().get_clipboard();
clipboard.set(this._errorMarkdown);
const clipboard = Gtk.Clipboard.get_default(this.get_display());
clipboard.set_text(this._errorMarkdown, -1);
});
this._actionGroup.add_action(action);
@ -287,7 +267,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
} catch (e) {
logError(e, 'Failed to add application style');
}
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(),
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
}

View File

@ -1,7 +1,7 @@
/* exported main */
imports.gi.versions.Gdk = '4.0';
imports.gi.versions.Gtk = '4.0';
imports.gi.versions.Gdk = '3.0';
imports.gi.versions.Gtk = '3.0';
const { Gtk } = imports.gi;
const pkg = imports.package;
@ -10,7 +10,7 @@ const { DBusService } = imports.dbusService;
const { ExtensionsService } = imports.extensionsService;
function main() {
Gtk.init();
Gtk.init(null);
pkg.initFormat();
const service = new DBusService(

View File

@ -1,30 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ExtensionPrefsDialog" parent="GtkWindow">
<property name="default-width">600</property>
<property name="default-height">400</property>
<property name="default_width">600</property>
<property name="default_height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar"/>
<object class="GtkHeaderBar" id="headerBar">
<property name="visible">True</property>
<property name="show_close_button">True</property>
</object>
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-height">True</property>
<property name="visible">True</property>
<property name="hscrollbar_policy">never</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin-start">100</property>
<property name="margin-end">100</property>
<property name="margin-top">100</property>
<property name="margin-bottom">60</property>
<property name="margin">100</property>
<property name="margin_bottom">60</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Somethings gone wrong</property>
<attributes>
<attribute name="scale" value="1.44"/> <!-- x-large -->
@ -36,78 +44,135 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">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.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
</object>
</child>
<child>
<object class="GtkFrame">
<property name="margin-top">12</property>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin_top">12</property>
<child>
<object class="GtkBox">
<object class="GtkFrame" id="expander">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkBox" id="expander">
<property name="spacing">6</property>
<style>
<class name="expander"/>
</style>
<object class="GtkEventBox">
<property name="visible">True</property>
<child>
<object class="GtkImage" id="expanderArrow">
<property name="icon-name">pan-end-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Technical Details</property>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="expanderArrow">
<property name="visible">True</property>
<property name="icon_name">pan-end-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Technical Details</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<child>
<object class="GtkRevealer" id="revealer">
<object class="GtkFrame">
<property name="visible">True</property>
<property name="shadow_type">in</property>
<style>
<class name="expander-frame"/>
</style>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkTextView" id="errorView">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="monospace">True</property>
<property name="editable">False</property>
<property name="wrap-mode">word</property>
<property name="left-margin">12</property>
<property name="right-margin">12</property>
<property name="top-margin">12</property>
<property name="bottom-margin">12</property>
<property name="wrap_mode">word</property>
<property name="left_margin">12</property>
<property name="right_margin">12</property>
<property name="top_margin">12</property>
<property name="bottom_margin">12</property>
</object>
</child>
<child>
<object class="GtkBox">
<object class="GtkToolbar">
<property name="visible">True</property>
<style>
<class name="expander-toolbar"/>
</style>
<child>
<object class="GtkButton">
<property name="receives-default">True</property>
<property name="action-name">win.copy-error</property>
<property name="has-frame">False</property>
<property name="icon-name">edit-copy-symbolic</property>
<object class="GtkToolItem">
<property name="visible">True</property>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">win.copy-error</property>
<style>
<class name="flat"/>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">edit-copy-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="homeButton">
<property name="visible"
bind-source="homeButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="hexpand">True</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Homepage</property>
<property name="tooltip-text" translatable="yes">Visit extension homepage</property>
<property name="receives-default">True</property>
<property name="has-frame">False</property>
<property name="action-name">win.show-url</property>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="draw">False</property>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
<property name="visible">True</property>
<child>
<object class="GtkButton" id="homeButton">
<property name="visible"
bind-source="homeButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="label" translatable="yes">Homepage</property>
<property name="tooltip_text" translatable="yes">Visit extension homepage</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="action_name">win.show-url</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
</child>
</object>

View File

@ -6,15 +6,8 @@ launcherconf.set('libdir', libdir)
dbus_services = {
'org.gnome.Shell.Extensions': 'extensions',
'org.gnome.Shell.Notifications': 'notifications',
'org.gnome.ScreenSaver': 'screensaver',
}
if enable_recorder
dbus_services += {
'org.gnome.Shell.Screencast': 'screencast',
}
endif
config_dir = '@0@/..'.format(meson.current_build_dir())
foreach service, dir : dbus_services
@ -27,7 +20,7 @@ foreach service, dir : dbus_services
serviceconf = configuration_data()
serviceconf.set('service', service)
serviceconf.set('gjs', gjs)
serviceconf.set('gjs', gjs.path())
serviceconf.set('pkgdatadir', pkgdatadir)
configure_file(

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/ScreenSaver/js">
<file>main.js</file>
<file>screenSaverService.js</file>
<file>dbusService.js</file>
<file>misc/config.js</file>
<file>misc/fileUtils.js</file>
</gresource>
</gresources>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/Shell/Screencast/js">
<file>main.js</file>
<file>screencastService.js</file>
<file>dbusService.js</file>
<file>misc/config.js</file>
<file>misc/fileUtils.js</file>
</gresource>
</gresources>

View File

@ -1,11 +0,0 @@
/* exported main */
const { DBusService } = imports.dbusService;
const { ScreencastService } = imports.screencastService;
function main() {
const service = new DBusService(
'org.gnome.Shell.Screencast',
new ScreencastService());
service.run();
}

View File

@ -1,471 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreencastService */
imports.gi.versions.Gtk = '4.0';
const { Gio, GLib, Gst, Gtk } = imports.gi;
const { loadInterfaceXML, loadSubInterfaceXML } = imports.misc.fileUtils;
const { ServiceImplementation } = imports.dbusService;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
const IntrospectIface = loadInterfaceXML('org.gnome.Shell.Introspect');
const IntrospectProxy = Gio.DBusProxy.makeProxyWrapper(IntrospectIface);
const ScreenCastIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast', 'org.gnome.Mutter.ScreenCast');
const ScreenCastSessionIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast.Session', 'org.gnome.Mutter.ScreenCast');
const ScreenCastStreamIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast.Stream', 'org.gnome.Mutter.ScreenCast');
const ScreenCastProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastIface);
const ScreenCastSessionProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastSessionIface);
const ScreenCastStreamProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastStreamIface);
const DEFAULT_PIPELINE = 'videoconvert chroma-mode=GST_VIDEO_CHROMA_MODE_NONE dither=GST_VIDEO_DITHER_NONE matrix-mode=GST_VIDEO_MATRIX_MODE_OUTPUT_ONLY n-threads=%T ! queue ! vp8enc cpu-used=16 max-quantizer=17 deadline=1 keyframe-mode=disabled threads=%T static-threshold=1000 buffer-size=20000 ! queue ! webmmux';
const DEFAULT_FRAMERATE = 30;
const DEFAULT_DRAW_CURSOR = true;
const PipelineState = {
INIT: 0,
PLAYING: 1,
FLUSHING: 2,
STOPPED: 3,
};
const SessionState = {
INIT: 0,
ACTIVE: 1,
STOPPED: 2,
};
var Recorder = class {
constructor(sessionPath, x, y, width, height, filePath, options,
invocation,
onErrorCallback) {
this._startInvocation = invocation;
this._dbusConnection = invocation.get_connection();
this._onErrorCallback = onErrorCallback;
this._stopInvocation = null;
this._pipelineIsPlaying = false;
this._sessionIsActive = false;
this._x = x;
this._y = y;
this._width = width;
this._height = height;
this._filePath = filePath;
this._pipelineString = DEFAULT_PIPELINE;
this._framerate = DEFAULT_FRAMERATE;
this._drawCursor = DEFAULT_DRAW_CURSOR;
this._applyOptions(options);
this._watchSender(invocation.get_sender());
this._initSession(sessionPath);
}
_applyOptions(options) {
for (const option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'] !== undefined)
this._pipelineString = options['pipeline'];
if (options['framerate'] !== undefined)
this._framerate = options['framerate'];
if ('draw-cursor' in options)
this._drawCursor = options['draw-cursor'];
}
_addRecentItem() {
const file = Gio.File.new_for_path(this._filePath);
Gtk.RecentManager.get_default().add_item(file.get_uri());
}
_watchSender(sender) {
this._nameWatchId = this._dbusConnection.watch_name(
sender,
Gio.BusNameWatcherFlags.NONE,
null,
this._senderVanished.bind(this));
}
_unwatchSender() {
if (this._nameWatchId !== 0) {
this._dbusConnection.unwatch_name(this._nameWatchId);
this._nameWatchId = 0;
}
}
_senderVanished() {
this._unwatchSender();
this.stopRecording(null);
}
_notifyStopped() {
this._unwatchSender();
if (this._onStartedCallback)
this._onStartedCallback(this, false);
else if (this._onStoppedCallback)
this._onStoppedCallback(this);
else
this._onErrorCallback(this);
}
_onSessionClosed() {
switch (this._pipelineState) {
case PipelineState.STOPPED:
break;
default:
this._pipeline.set_state(Gst.State.NULL);
log(`Unexpected pipeline state: ${this._pipelineState}`);
break;
}
this._notifyStopped();
}
_initSession(sessionPath) {
this._sessionProxy = new ScreenCastSessionProxy(Gio.DBus.session,
'org.gnome.Mutter.ScreenCast',
sessionPath);
this._sessionProxy.connectSignal('Closed', this._onSessionClosed.bind(this));
}
_startPipeline(nodeId) {
if (!this._ensurePipeline(nodeId))
return;
const bus = this._pipeline.get_bus();
bus.add_watch(bus, this._onBusMessage.bind(this));
this._pipeline.set_state(Gst.State.PLAYING);
this._pipelineState = PipelineState.PLAYING;
this._onStartedCallback(this, true);
this._onStartedCallback = null;
}
startRecording(onStartedCallback) {
this._onStartedCallback = onStartedCallback;
const [streamPath] = this._sessionProxy.RecordAreaSync(
this._x, this._y,
this._width, this._height,
{
'is-recording': GLib.Variant.new('b', true),
'cursor-mode': GLib.Variant.new('u', this._drawCursor ? 1 : 0),
});
this._streamProxy = new ScreenCastStreamProxy(Gio.DBus.session,
'org.gnome.ScreenCast.Stream',
streamPath);
this._streamProxy.connectSignal('PipeWireStreamAdded',
(proxy, sender, params) => {
const [nodeId] = params;
this._startPipeline(nodeId);
});
this._sessionProxy.StartSync();
this._sessionState = SessionState.ACTIVE;
}
stopRecording(onStoppedCallback) {
this._pipelineState = PipelineState.FLUSHING;
this._onStoppedCallback = onStoppedCallback;
this._pipeline.send_event(Gst.Event.new_eos());
}
_stopSession() {
this._sessionProxy.StopSync();
this._sessionState = SessionState.STOPPED;
}
_onBusMessage(bus, message, _) {
switch (message.type) {
case Gst.MessageType.EOS:
this._pipeline.set_state(Gst.State.NULL);
this._addRecentItem();
switch (this._pipelineState) {
case PipelineState.FLUSHING:
this._pipelineState = PipelineState.STOPPED;
break;
default:
break;
}
switch (this._sessionState) {
case SessionState.ACTIVE:
this._stopSession();
break;
case SessionState.STOPPED:
this._notifyStopped();
break;
default:
break;
}
break;
default:
break;
}
return true;
}
_substituteThreadCount(pipelineDescr) {
const numProcessors = GLib.get_num_processors();
const numThreads = Math.min(Math.max(1, numProcessors), 64);
return pipelineDescr.replaceAll('%T', numThreads);
}
_ensurePipeline(nodeId) {
const framerate = this._framerate;
let fullPipeline = `
pipewiresrc path=${nodeId}
do-timestamp=true
keepalive-time=1000
resend-last=true !
video/x-raw,max-framerate=${framerate}/1 !
${this._pipelineString} !
filesink location="${this._filePath}"`;
fullPipeline = this._substituteThreadCount(fullPipeline);
try {
this._pipeline = Gst.parse_launch_full(fullPipeline,
null,
Gst.ParseFlags.FATAL_ERRORS);
} catch (e) {
log(`Failed to create pipeline: ${e}`);
this._notifyStopped();
}
return !!this._pipeline;
}
};
var ScreencastService = class extends ServiceImplementation {
constructor() {
super(ScreencastIface, '/org/gnome/Shell/Screencast');
Gst.init(null);
Gtk.init();
this._recorders = new Map();
this._senders = new Map();
this._lockdownSettings = new Gio.Settings({
schema_id: 'org.gnome.desktop.lockdown',
});
this._proxy = new ScreenCastProxy(Gio.DBus.session,
'org.gnome.Mutter.ScreenCast',
'/org/gnome/Mutter/ScreenCast');
this._introspectProxy = new IntrospectProxy(Gio.DBus.session,
'org.gnome.Shell.Introspect',
'/org/gnome/Shell/Introspect');
}
_removeRecorder(sender) {
this._recorders.delete(sender);
if (this._recorders.size === 0)
this.release();
}
_addRecorder(sender, recorder) {
this._recorders.set(sender, recorder);
if (this._recorders.size === 1)
this.hold();
}
_getAbsolutePath(filename) {
if (GLib.path_is_absolute(filename))
return filename;
let videoDir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS);
if (!GLib.file_test(videoDir, GLib.FileTest.EXISTS))
videoDir = GLib.get_home_dir();
return GLib.build_filenamev([videoDir, filename]);
}
_generateFilePath(template) {
let filename = '';
let escape = false;
[...template].forEach(c => {
if (escape) {
switch (c) {
case '%':
filename += '%';
break;
case 'd': {
const datetime = GLib.DateTime.new_now_local();
const datestr = datetime.format('%0x');
const datestrEscaped = datestr.replace(/\//g, '-');
filename += datestrEscaped;
break;
}
case 't': {
const datetime = GLib.DateTime.new_now_local();
const datestr = datetime.format('%0X');
const datestrEscaped = datestr.replace(/\//g, ':');
filename += datestrEscaped;
break;
}
default:
log(`Warning: Unknown escape ${c}`);
}
escape = false;
} else if (c === '%') {
escape = true;
} else {
filename += c;
}
});
if (escape)
filename += '%';
return this._getAbsolutePath(filename);
}
ScreencastAsync(params, invocation) {
let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const sender = invocation.get_sender();
if (this._recorders.get(sender)) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const [sessionPath] = this._proxy.CreateSessionSync({});
const [fileTemplate, options] = params;
const [screenWidth, screenHeight] = this._introspectProxy.ScreenSize;
const filePath = this._generateFilePath(fileTemplate);
let recorder;
try {
recorder = new Recorder(
sessionPath,
0, 0,
screenWidth, screenHeight,
filePath,
options,
invocation,
_recorder => this._removeRecorder(sender));
} catch (error) {
log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
this._addRecorder(sender, recorder);
try {
recorder.startRecording(
(_, result) => {
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
}
ScreencastAreaAsync(params, invocation) {
let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const sender = invocation.get_sender();
if (this._recorders.get(sender)) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const [sessionPath] = this._proxy.CreateSessionSync({});
const [x, y, width, height, fileTemplate, options] = params;
const filePath = this._generateFilePath(fileTemplate);
let recorder;
try {
recorder = new Recorder(
sessionPath,
x, y,
width, height,
filePath,
options,
invocation,
_recorder => this._removeRecorder(sender));
} catch (error) {
log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
this._addRecorder(sender, recorder);
try {
recorder.startRecording(
(_, result) => {
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
}
StopScreencastAsync(params, invocation) {
const sender = invocation.get_sender();
const recorder = this._recorders.get(sender);
if (!recorder) {
invocation.return_value(GLib.Variant.new('(b)', [false]));
return;
}
recorder.stopRecording(() => {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(b)', [true]));
});
}
};

View File

@ -1,11 +0,0 @@
/* exported main */
const { DBusService } = imports.dbusService;
const { ScreenSaverService } = imports.screenSaverService;
function main() {
const service = new DBusService(
'org.gnome.ScreenSaver',
new ScreenSaverService());
service.run();
}

View File

@ -1,70 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreenSaverService */
const { Gio, GLib } = imports.gi;
const { loadInterfaceXML } = imports.misc.fileUtils;
const { ServiceImplementation } = imports.dbusService;
const ScreenSaverIface = loadInterfaceXML('org.gnome.ScreenSaver');
const ScreenSaverProxy = Gio.DBusProxy.makeProxyWrapper(ScreenSaverIface);
var ScreenSaverService = class extends ServiceImplementation {
constructor() {
super(ScreenSaverIface, '/org/gnome/ScreenSaver');
this._autoShutdown = false;
this._proxy = new ScreenSaverProxy(Gio.DBus.session,
'org.gnome.Shell.ScreenShield',
'/org/gnome/ScreenSaver',
(proxy, error) => {
if (error)
log(error.message);
});
this._proxy.connectSignal('ActiveChanged',
(proxy, sender, params) => {
this._dbusImpl.emit_signal('ActiveChanged',
new GLib.Variant('(b)', params));
});
this._proxy.connectSignal('WakeUpScreen',
() => this._dbusImpl.emit_signal('WakeUpScreen', null));
}
LockAsync(params, invocation) {
this._proxy.LockRemote(...params, (res, error) => {
if (this._handleError(invocation, error))
return;
invocation.return_value(null);
});
}
GetActiveAsync(params, invocation) {
this._proxy.GetActiveRemote(...params, (res, error) => {
if (this._handleError(invocation, error))
return;
invocation.return_value(new GLib.Variant('(b)', res));
});
}
SetActiveAsync(params, invocation) {
this._proxy.SetActiveRemote(...params, (res, error) => {
if (this._handleError(invocation, error))
return;
invocation.return_value(null);
});
}
GetActiveTimeAsync(params, invocation) {
this._proxy.GetActiveTimeRemote(...params, (res, error) => {
if (this._handleError(invocation, error))
return;
invocation.return_value(new GLib.Variant('(u)', res));
});
}
};

View File

@ -1,17 +1,15 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported AuthPrompt */
const { Clutter, GLib, GObject, Pango, Shell, St } = imports.gi;
const { Clutter, GObject, Pango, Shell, St } = imports.gi;
const Animation = imports.ui.animation;
const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util;
const OVirt = imports.gdm.oVirt;
const Vmware = imports.gdm.vmware;
const Util = imports.misc.util;
const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget;
const Util = imports.misc.util;
var DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
@ -29,14 +27,11 @@ var AuthPromptStatus = {
VERIFYING: 1,
VERIFICATION_FAILED: 2,
VERIFICATION_SUCCEEDED: 3,
VERIFICATION_CANCELLED: 4,
VERIFICATION_IN_PROGRESS: 5,
};
var BeginRequestType = {
PROVIDE_USERNAME: 0,
DONT_PROVIDE_USERNAME: 1,
REUSE_USERNAME: 2,
};
var AuthPrompt = GObject.registerClass({
@ -61,7 +56,6 @@ var AuthPrompt = GObject.registerClass({
this._gdmClient = gdmClient;
this._mode = mode;
this._defaultButtonWellActor = null;
this._cancelledRetries = 0;
let reauthenticationOnly;
if (this._mode == AuthPromptMode.UNLOCK_ONLY)
@ -170,13 +164,6 @@ var AuthPrompt = GObject.registerClass({
this._mainBox.add_child(this._entry);
this._entry.grab_key_focus();
this._timedLoginIndicator = new St.Bin({
style_class: 'login-dialog-timed-login-indicator',
scale_x: 0,
});
this.add_child(this._timedLoginIndicator);
[this._textEntry, this._passwordEntry].forEach(entry => {
entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages)
@ -205,42 +192,7 @@ var AuthPrompt = GObject.registerClass({
this._defaultButtonWell.add_child(this._spinner);
}
showTimedLoginIndicator(time) {
let hold = new Batch.Hold();
this.hideTimedLoginIndicator();
const startTime = GLib.get_monotonic_time();
this._timedLoginTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 33,
() => {
const currentTime = GLib.get_monotonic_time();
const elapsedTime = (currentTime - startTime) / GLib.USEC_PER_SEC;
this._timedLoginIndicator.scale_x = elapsedTime / time;
if (elapsedTime >= time) {
this._timedLoginTimeoutId = 0;
hold.release();
return GLib.SOURCE_REMOVE;
}
return GLib.SOURCE_CONTINUE;
});
GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
return hold;
}
hideTimedLoginIndicator() {
if (this._timedLoginTimeoutId) {
GLib.source_remove(this._timedLoginTimeoutId);
this._timedLoginTimeoutId = 0;
}
this._timedLoginIndicator.scale_x = 0.;
}
_activateNext(shouldSpin) {
this.verificationStatus = AuthPromptStatus.VERIFICATION_IN_PROGRESS;
this.updateSensitivity(false);
if (shouldSpin)
@ -314,27 +266,20 @@ var AuthPrompt = GObject.registerClass({
this.reset();
}
_onShowMessage(_userVerifier, serviceName, message, type) {
this.setMessage(serviceName, message, type);
_onShowMessage(userVerifier, message, type) {
this.setMessage(message, type);
this.emit('prompted');
}
_onVerificationFailed(userVerifier, serviceName, canRetry) {
const wasQueryingService = this._queryingService === serviceName;
if (wasQueryingService) {
this._queryingService = null;
this.clear();
}
_onVerificationFailed(userVerifier, canRetry) {
this._queryingService = null;
this.clear();
this.updateSensitivity(canRetry);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
if (!canRetry)
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
if (wasQueryingService)
Util.wiggle(this._entry);
Util.wiggle(this._entry);
}
_onVerificationComplete() {
@ -458,7 +403,7 @@ var AuthPrompt = GObject.registerClass({
});
}
setMessage(serviceName, message, type) {
setMessage(message, type) {
if (type == GdmUtil.MessageType.ERROR)
this._message.add_style_class_name('login-dialog-message-warning');
else
@ -476,18 +421,6 @@ var AuthPrompt = GObject.registerClass({
} else {
this._message.opacity = 0;
}
if (type === GdmUtil.MessageType.ERROR &&
this._userVerifier.serviceIsFingerprint(serviceName)) {
// TODO: Use Await for wiggle to be over before unfreezing the user verifier queue
const wiggleParameters = {
duration: 65,
wiggleCount: 3,
};
this._userVerifier.increaseCurrentMessageTimeout(
wiggleParameters.duration * (wiggleParameters.wiggleCount + 2));
Util.wiggle(this._message, wiggleParameters);
}
}
updateSensitivity(sensitive) {
@ -496,14 +429,8 @@ var AuthPrompt = GObject.registerClass({
this._entry.reactive = sensitive;
if (sensitive) {
if (sensitive)
this._entry.grab_key_focus();
} else {
this.grab_key_focus();
if (this._entry === this._passwordEntry)
this._entry.password_visible = false;
}
}
vfunc_hide() {
@ -548,26 +475,18 @@ var AuthPrompt = GObject.registerClass({
if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED)
this.emit('failed');
else if (oldStatus === AuthPromptStatus.VERIFICATION_CANCELLED)
this.emit('cancelled');
let beginRequestType;
if (this._mode == AuthPromptMode.UNLOCK_ONLY) {
// The user is constant at the unlock screen, so it will immediately
// respond to the request with the username
if (oldStatus === AuthPromptStatus.VERIFICATION_CANCELLED)
return;
beginRequestType = BeginRequestType.PROVIDE_USERNAME;
} else if (this._userVerifier.serviceIsForeground(OVirt.SERVICE_NAME) ||
this._userVerifier.serviceIsForeground(Vmware.SERVICE_NAME) ||
} else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) ||
this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) {
// We don't need to know the username if the user preempted the login screen
// with a smartcard or with preauthenticated oVirt credentials
beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME;
} else if (oldStatus === AuthPromptStatus.VERIFICATION_IN_PROGRESS) {
// We're going back to retry with current user
beginRequestType = BeginRequestType.REUSE_USERNAME;
} else {
// In all other cases, we should get the username up front.
beginRequestType = BeginRequestType.PROVIDE_USERNAME;
@ -616,14 +535,7 @@ var AuthPrompt = GObject.registerClass({
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED)
return;
if (this.verificationStatus === AuthPromptStatus.VERIFICATION_IN_PROGRESS) {
this._cancelledRetries++;
if (this._cancelledRetries > this._userVerifier.allowedFailures)
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
} else {
this.verificationStatus = AuthPromptStatus.VERIFICATION_CANCELLED;
}
this.reset();
this.emit('cancelled');
}
});

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported CredentialManager */
var CredentialManager = class CredentialManager {
class CredentialManager {
constructor(service) {
this._token = null;
this._service = service;
@ -21,4 +21,4 @@ var CredentialManager = class CredentialManager {
get service() {
return this._service;
}
};
}

33
js/gdm/fingerprint.js Normal file
View File

@ -0,0 +1,33 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported FprintManager */
const Gio = imports.gi.Gio;
const FprintManagerIface = `
<node>
<interface name="net.reactivated.Fprint.Manager">
<method name="GetDefaultDevice">
<arg type="o" direction="out" />
</method>
</interface>
</node>`;
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);
function FprintManager() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
g_interface_name: FprintManagerInfo.name,
g_interface_info: FprintManagerInfo,
g_name: 'net.reactivated.Fprint',
g_object_path: '/net/reactivated/Fprint/Manager',
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
try {
self.init(null);
} catch (e) {
log(`Failed to connect to Fprint service: ${e.message}`);
return null;
}
return self;
}

View File

@ -42,6 +42,7 @@ var UserListItem = GObject.registerClass({
_init(user) {
let layout = new St.BoxLayout({
vertical: true,
x_align: Clutter.ActorAlign.START,
});
super._init({
style_class: 'login-dialog-user-list-item',
@ -463,7 +464,6 @@ var LoginDialog = GObject.registerClass({
child: notListedLabel,
reactive: true,
x_align: Clutter.ActorAlign.START,
label_actor: notListedLabel,
});
this._notListedButton.connect('clicked', this._hideUserListAskForUsernameAndBeginVerification.bind(this));
@ -762,9 +762,6 @@ var LoginDialog = GObject.registerClass({
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
if (this._disableUserList && this._timedLoginUserListHold)
this._timedLoginUserListHold.release();
}
}
@ -858,7 +855,6 @@ var LoginDialog = GObject.registerClass({
this._resetGreeterProxy();
this._sessionMenuButton.updateSensitivity(true);
const previousUser = this._user;
this._user = null;
if (this._nextSignalId) {
@ -866,11 +862,7 @@ var LoginDialog = GObject.registerClass({
this._nextSignalId = 0;
}
if (previousUser && beginRequest === AuthPrompt.BeginRequestType.REUSE_USERNAME) {
this._user = previousUser;
this._authPrompt.setUser(this._user);
this._authPrompt.begin({ userName: previousUser.get_user_name() });
} else if (beginRequest === AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
if (!this._disableUserList)
this._showUserList();
else
@ -961,15 +953,16 @@ var LoginDialog = GObject.registerClass({
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
return;
if (this._authPrompt.verificationStatus !== AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._bindOpacity();
this.ease({
opacity: 255,
duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._unbindOpacity(),
onComplete: () => {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._unbindOpacity();
},
});
}
@ -1051,72 +1044,54 @@ var LoginDialog = GObject.registerClass({
let loginItem = null;
let animationTime;
let tasks = [
() => {
if (this._disableUserList)
return;
let tasks = [() => this._waitForItemForUser(userName),
this._timedLoginUserListHold = this._waitForItemForUser(userName);
},
() => {
loginItem = this._userList.getItemFromUserName(userName);
() => {
this._timedLoginUserListHold = null;
// If there is an animation running on the item, reset it.
loginItem.hideTimedLoginIndicator();
},
if (this._disableUserList)
loginItem = this._authPrompt;
else
loginItem = this._userList.getItemFromUserName(userName);
() => {
// If we're just starting out, start on the right item.
if (!this._userManager.is_loaded)
this._userList.jumpToItem(loginItem);
},
// If there is an animation running on the item, reset it.
loginItem.hideTimedLoginIndicator();
},
() => {
// This blocks the timed login animation until a few
// seconds after the user stops interacting with the
// login screen.
() => {
if (this._disableUserList)
return;
// We skip this step if the timed login delay is very short.
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD) {
animationTime = delay - _TIMED_LOGIN_IDLE_THRESHOLD;
return this._blockTimedLoginUntilIdle();
} else {
animationTime = delay;
return null;
}
},
// If we're just starting out, start on the right item.
if (!this._userManager.is_loaded)
this._userList.jumpToItem(loginItem);
},
() => {
// If idle timeout is done, make sure the timed login indicator is shown
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
this._authPrompt.visible)
this._authPrompt.cancel();
() => {
// This blocks the timed login animation until a few
// seconds after the user stops interacting with the
// login screen.
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
this._userList.scrollToItem(loginItem);
loginItem.grab_key_focus();
}
},
// We skip this step if the timed login delay is very short.
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD) {
animationTime = delay - _TIMED_LOGIN_IDLE_THRESHOLD;
return this._blockTimedLoginUntilIdle();
} else {
animationTime = delay;
return null;
}
},
() => loginItem.showTimedLoginIndicator(animationTime),
() => {
if (this._disableUserList)
return;
// If idle timeout is done, make sure the timed login indicator is shown
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
this._authPrompt.visible)
this._authPrompt.cancel();
if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
this._userList.scrollToItem(loginItem);
loginItem.grab_key_focus();
}
},
() => loginItem.showTimedLoginIndicator(animationTime),
() => {
this._timedLoginBatch = null;
this._greeter.call_begin_auto_login_sync(userName, null);
},
];
() => {
this._timedLoginBatch = null;
this._greeter.call_begin_auto_login_sync(userName, null);
}];
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);

View File

@ -6,18 +6,13 @@ const { Clutter, Gdm, Gio, GLib } = imports.gi;
const Signals = imports.signals;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const OVirt = imports.gdm.oVirt;
const Vmware = imports.gdm.vmware;
const Main = imports.ui.main;
const { loadInterfaceXML } = imports.misc.fileUtils;
const Params = imports.misc.params;
const SmartcardManager = imports.misc.smartcardManager;
const FprintManagerIface = loadInterfaceXML('net.reactivated.Fprint.Manager');
const FprintManagerProxy = Gio.DBusProxy.makeProxyWrapper(FprintManagerIface);
const FprintDeviceIface = loadInterfaceXML('net.reactivated.Fprint.Device');
const FprintDeviceProxy = Gio.DBusProxy.makeProxyWrapper(FprintDeviceIface);
Gio._promisify(Gdm.Client.prototype,
'open_reauthentication_channel', 'open_reauthentication_channel_finish');
Gio._promisify(Gdm.Client.prototype,
@ -46,20 +41,12 @@ var DISABLE_USER_LIST_KEY = 'disable-user-list';
// Give user 48ms to read each character of a PAM message
var USER_READ_TIME = 48;
const FINGERPRINT_ERROR_TIMEOUT_WAIT = 15;
var MessageType = {
// Keep messages in order by priority
NONE: 0,
HINT: 1,
ERROR: 1,
INFO: 2,
ERROR: 3,
};
const FingerprintReaderType = {
NONE: 0,
PRESS: 1,
SWIPE: 2,
HINT: 3,
};
function fadeInActor(actor) {
@ -151,12 +138,7 @@ var ShellUserVerifier = class {
this._updateDefaultService.bind(this));
this._updateDefaultService();
this._fprintManager = new FprintManagerProxy(Gio.DBus.system,
'net.reactivated.Fprint',
'/net/reactivated/Fprint/Manager',
null,
null,
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
this._fprintManager = Fprint.FprintManager();
this._smartcardManager = SmartcardManager.getSmartcardManager();
// We check for smartcards right away, since an inserted smartcard
@ -173,10 +155,10 @@ var ShellUserVerifier = class {
this._messageQueue = [];
this._messageQueueTimeoutId = 0;
this.hasPendingMessages = false;
this.reauthenticating = false;
this._failCounter = 0;
this._unavailableServices = new Set();
this._credentialManagers = {};
this._credentialManagers[OVirt.SERVICE_NAME] = OVirt.getOVirtCredentialsManager();
@ -194,18 +176,6 @@ var ShellUserVerifier = class {
}
}
get hasPendingMessages() {
return !!this._messageQueue.length;
}
get allowedFailures() {
return this._settings.get_int(ALLOWED_FAILURES_KEY);
}
get currentMessage() {
return this._messageQueue ? this._messageQueue[0] : null;
}
begin(userName, hold) {
this._cancellable = new Gio.Cancellable();
this._hold = hold;
@ -234,7 +204,6 @@ var ShellUserVerifier = class {
_clearUserVerifier() {
if (this._userVerifier) {
this._disconnectSignals();
this._userVerifier.run_dispose();
this._userVerifier = null;
}
@ -251,7 +220,7 @@ var ShellUserVerifier = class {
}
destroy() {
this.cancel();
this.clear();
this._settings.run_dispose();
this._settings = null;
@ -271,19 +240,14 @@ var ShellUserVerifier = class {
if (!this.hasPendingMessages) {
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
} else {
const cancellable = this._cancellable;
let signalId = this.connect('no-more-messages', () => {
this.disconnect(signalId);
if (!cancellable.is_cancelled())
this._userVerifier.call_answer_query(serviceName, answer, cancellable, null);
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
});
}
}
_getIntervalForMessage(message) {
if (!message)
return 0;
// We probably could be smarter here
return message.length * USER_READ_TIME;
}
@ -294,72 +258,41 @@ var ShellUserVerifier = class {
this._messageQueue = [];
this.hasPendingMessages = false;
this.emit('no-more-messages');
}
increaseCurrentMessageTimeout(interval) {
if (!this._messageQueueTimeoutId && interval > 0)
this._currentMessageExtraInterval = interval;
}
_serviceHasPendingMessages(serviceName) {
return this._messageQueue.some(m => m.serviceName === serviceName);
}
_filterServiceMessages(serviceName, messageType) {
// This function allows to remove queued messages for the @serviceName
// whose type has lower priority than @messageType, replacing them
// with a null message that will lead to clearing the prompt once done.
if (this._serviceHasPendingMessages(serviceName))
this._queuePriorityMessage(serviceName, null, messageType);
}
_queueMessageTimeout() {
if (this._messageQueue.length == 0) {
this.finishMessageQueue();
return;
}
if (this._messageQueueTimeoutId != 0)
return;
const message = this.currentMessage;
let message = this._messageQueue.shift();
delete this._currentMessageExtraInterval;
this.emit('show-message', message.serviceName, message.text, message.type);
this.emit('show-message', message.text, message.type);
this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
message.interval + (this._currentMessageExtraInterval | 0), () => {
this._messageQueueTimeoutId = 0;
if (this._messageQueue.length > 1) {
this._messageQueue.shift();
this._queueMessageTimeout();
} else {
this.finishMessageQueue();
}
return GLib.SOURCE_REMOVE;
});
message.interval,
() => {
this._messageQueueTimeoutId = 0;
this._queueMessageTimeout();
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
}
_queueMessage(serviceName, message, messageType) {
_queueMessage(message, messageType) {
let interval = this._getIntervalForMessage(message);
this._messageQueue.push({ serviceName, text: message, type: messageType, interval });
this.hasPendingMessages = true;
this._messageQueue.push({ text: message, type: messageType, interval });
this._queueMessageTimeout();
}
_queuePriorityMessage(serviceName, message, messageType) {
const newQueue = this._messageQueue.filter(m => {
if (m.serviceName !== serviceName || m.type >= messageType)
return m.text !== message;
return false;
});
if (!newQueue.includes(this.currentMessage))
this._clearMessageQueue();
this._messageQueue = newQueue;
this._queueMessage(serviceName, message, messageType);
}
_clearMessageQueue() {
this.finishMessageQueue();
@ -367,11 +300,11 @@ var ShellUserVerifier = class {
GLib.source_remove(this._messageQueueTimeoutId);
this._messageQueueTimeoutId = 0;
}
this.emit('show-message', null, null, MessageType.NONE);
this.emit('show-message', null, MessageType.NONE);
}
_checkForFingerprintReader() {
this._fingerprintReaderType = FingerprintReaderType.NONE;
this._haveFingerprintReader = false;
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY) ||
this._fprintManager == null) {
@ -380,17 +313,9 @@ var ShellUserVerifier = class {
}
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable,
(params, error) => {
if (!error && params) {
const [device] = params;
const fprintDeviceProxy = new FprintDeviceProxy(Gio.DBus.system,
'net.reactivated.Fprint',
device);
const fprintDeviceType = fprintDeviceProxy['scan-type'];
this._fingerprintReaderType = fprintDeviceType === 'swipe'
? FingerprintReaderType.SWIPE
: FingerprintReaderType.PRESS;
(device, error) => {
if (!error && device) {
this._haveFingerprintReader = true;
this._updateDefaultService();
}
});
@ -423,13 +348,12 @@ var ShellUserVerifier = class {
}
}
_reportInitError(where, error, serviceName) {
_reportInitError(where, error) {
logError(error, where);
this._hold.release();
this._queueMessage(serviceName, _('Authentication error'), MessageType.ERROR);
this._failCounter++;
this._verificationFailed(serviceName, false);
this._queueMessage(_("Authentication error"), MessageType.ERROR);
this._verificationFailed(false);
}
async _openReauthenticationChannel(userName) {
@ -477,33 +401,13 @@ var ShellUserVerifier = class {
}
_connectSignals() {
this._disconnectSignals();
this._signalIds = [];
let id = this._userVerifier.connect('info', this._onInfo.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('problem', this._onProblem.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('info-query', this._onInfoQuery.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('service-unavailable', this._onServiceUnavailable.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('reset', this._onReset.bind(this));
this._signalIds.push(id);
id = this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
this._signalIds.push(id);
}
_disconnectSignals() {
if (!this._signalIds || !this._userVerifier)
return;
this._signalIds.forEach(s => this._userVerifier.disconnect(s));
this._signalIds = [];
this._userVerifier.connect('info', this._onInfo.bind(this));
this._userVerifier.connect('problem', this._onProblem.bind(this));
this._userVerifier.connect('info-query', this._onInfoQuery.bind(this));
this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this));
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
this._userVerifier.connect('reset', this._onReset.bind(this));
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
}
_getForegroundService() {
@ -521,17 +425,12 @@ var ShellUserVerifier = class {
return serviceName == this._defaultService;
}
serviceIsFingerprint(serviceName) {
return this._fingerprintReaderType !== FingerprintReaderType.NONE &&
serviceName === FINGERPRINT_SERVICE_NAME;
}
_updateDefaultService() {
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
this._defaultService = PASSWORD_SERVICE_NAME;
else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
this._defaultService = SMARTCARD_SERVICE_NAME;
else if (this._fingerprintReaderType !== FingerprintReaderType.NONE)
else if (this._haveFingerprintReader)
this._defaultService = FINGERPRINT_SERVICE_NAME;
if (!this._defaultService) {
@ -553,15 +452,9 @@ var ShellUserVerifier = class {
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
if (!this.serviceIsForeground(serviceName)) {
logError(e, 'Failed to start %s for %s'.format(serviceName, this._userName));
this._hold.release();
return;
}
this._reportInitError(this._userName
? 'Failed to start %s verification for user'.format(serviceName)
: 'Failed to start %s verification'.format(serviceName), e,
serviceName);
? 'Failed to start verification for user'
: 'Failed to start verification', e);
return;
}
this._hold.release();
@ -570,67 +463,30 @@ var ShellUserVerifier = class {
_beginVerification() {
this._startService(this._getForegroundService());
if (this._userName &&
this._fingerprintReaderType !== FingerprintReaderType.NONE &&
!this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
this._startService(FINGERPRINT_SERVICE_NAME);
}
_onInfo(client, serviceName, info) {
if (this.serviceIsForeground(serviceName)) {
this._queueMessage(serviceName, info, MessageType.INFO);
} else if (this.serviceIsFingerprint(serviceName)) {
this._queueMessage(info, MessageType.INFO);
} else if (serviceName == FINGERPRINT_SERVICE_NAME &&
this._haveFingerprintReader) {
// We don't show fingerprint messages directly since it's
// not the main auth service. Instead we use the messages
// as a cue to display our own message.
if (this._fingerprintReaderType === FingerprintReaderType.SWIPE) {
// Translators: this message is shown below the password entry field
// to indicate the user can swipe their finger on the fingerprint reader
this._queueMessage(serviceName, _('(or swipe finger across reader)'),
MessageType.HINT);
} else {
// Translators: this message is shown below the password entry field
// to indicate the user can place their finger on the fingerprint reader instead
this._queueMessage(serviceName, _('(or place finger on reader)'),
MessageType.HINT);
}
// Translators: this message is shown below the password entry field
// to indicate the user can swipe their finger instead
this._queueMessage(_("(or swipe finger)"), MessageType.HINT);
}
}
_onProblem(client, serviceName, problem) {
const isFingerprint = this.serviceIsFingerprint(serviceName);
if (!this.serviceIsForeground(serviceName) && !isFingerprint)
if (!this.serviceIsForeground(serviceName))
return;
this._queuePriorityMessage(serviceName, problem, MessageType.ERROR);
if (isFingerprint) {
// pam_fprintd allows the user to retry multiple (maybe even infinite!
// times before failing the authentication conversation.
// We don't want this behavior to bypass the max-tries setting the user has set,
// so we count the problem messages to know how many times the user has failed.
// Once we hit the max number of failures we allow, it's time to failure the
// conversation from our side. We can't do that right away, however, because
// we may drop pending messages coming from pam_fprintd. In order to make sure
// the user sees everything, we queue the failure up to get handled in the
// near future, after we've finished up the current round of messages.
this._failCounter++;
if (!this._canRetry()) {
if (this._fingerprintFailedId)
GLib.source_remove(this._fingerprintFailedId);
const cancellable = this._cancellable;
this._fingerprintFailedId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
FINGERPRINT_ERROR_TIMEOUT_WAIT, () => {
this._fingerprintFailedId = 0;
if (!cancellable.is_cancelled())
this._verificationFailed(serviceName, false);
return GLib.SOURCE_REMOVE;
});
}
}
this._queueMessage(problem, MessageType.ERROR);
}
_onInfoQuery(client, serviceName, question) {
@ -659,7 +515,6 @@ var ShellUserVerifier = class {
_onReset() {
// Clear previous attempts to authenticate
this._failCounter = 0;
this._unavailableServices.clear();
this._updateDefaultService();
this.emit('reset');
@ -674,69 +529,44 @@ var ShellUserVerifier = class {
this._onReset();
}
_retry(serviceName) {
this._hold = new Batch.Hold();
this._connectSignals();
this._startService(serviceName);
_retry() {
this.begin(this._userName, new Batch.Hold());
}
_canRetry() {
return this._userName &&
(this._reauthOnly || this._failCounter < this.allowedFailures);
}
_verificationFailed(serviceName, shouldRetry) {
if (serviceName === FINGERPRINT_SERVICE_NAME) {
if (this._fingerprintFailedId)
GLib.source_remove(this._fingerprintFailedId);
}
_verificationFailed(retry) {
// For Not Listed / enterprise logins, immediately reset
// the dialog
// Otherwise, when in login mode we allow ALLOWED_FAILURES attempts.
// After that, we go back to the welcome screen.
this._filterServiceMessages(serviceName, MessageType.ERROR);
const doneTrying = !shouldRetry || !this._canRetry();
if (doneTrying) {
this._disconnectSignals();
this._failCounter++;
let canRetry = retry && this._userName &&
(this._reauthOnly ||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY));
if (canRetry) {
if (!this.hasPendingMessages) {
this._retry();
} else {
let signalId = this.connect('no-more-messages', () => {
this.disconnect(signalId);
if (this._cancellable && !this._cancellable.is_cancelled())
this._retry();
});
}
} else {
// eslint-disable-next-line no-lonely-if
if (!this.hasPendingMessages) {
this._cancelAndReset();
} else {
const cancellable = this._cancellable;
let signalId = this.connect('no-more-messages', () => {
this.disconnect(signalId);
if (!cancellable.is_cancelled())
this._cancelAndReset();
this._cancelAndReset();
});
}
}
this.emit('verification-failed', serviceName, !doneTrying);
if (!this.hasPendingMessages) {
this._retry(serviceName);
} else {
const cancellable = this._cancellable;
let signalId = this.connect('no-more-messages', () => {
this.disconnect(signalId);
if (!cancellable.is_cancelled())
this._retry(serviceName);
});
}
}
_onServiceUnavailable(_client, serviceName, errorMessage) {
this._unavailableServices.add(serviceName);
if (!errorMessage)
return;
if (this.serviceIsForeground(serviceName) || this.serviceIsFingerprint(serviceName))
this._queueMessage(serviceName, errorMessage, MessageType.ERROR);
this.emit('verification-failed', canRetry);
}
_onConversationStopped(client, serviceName) {
@ -748,22 +578,15 @@ var ShellUserVerifier = class {
if (foregroundService) {
this._credentialManagers[foregroundService].token = null;
this._preemptingService = null;
this._verificationFailed(serviceName, false);
this._verificationFailed(false);
return;
}
this._filterServiceMessages(serviceName, MessageType.ERROR);
if (this._unavailableServices.has(serviceName))
return;
// 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))
this._failCounter++;
this._verificationFailed(serviceName, true);
this._verificationFailed(true);
}
};
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/shell">
<file>gdm/authPrompt.js</file>
<file>gdm/batch.js</file>
<file>gdm/fingerprint.js</file>
<file>gdm/loginDialog.js</file>
<file>gdm/oVirt.js</file>
<file>gdm/credentialManager.js</file>
@ -31,7 +32,6 @@
<file>misc/util.js</file>
<file>misc/weather.js</file>
<file>perf/basic.js</file>
<file>perf/core.js</file>
<file>perf/hwtest.js</file>
@ -40,7 +40,6 @@
<file>ui/animation.js</file>
<file>ui/appDisplay.js</file>
<file>ui/appFavorites.js</file>
<file>ui/appMenu.js</file>
<file>ui/audioDeviceSelection.js</file>
<file>ui/backgroundMenu.js</file>
<file>ui/background.js</file>
@ -64,7 +63,6 @@
<file>ui/ibusCandidatePopup.js</file>
<file>ui/iconGrid.js</file>
<file>ui/inhibitShortcutsDialog.js</file>
<file>ui/init.js</file>
<file>ui/kbdA11yDialog.js</file>
<file>ui/keyboard.js</file>
<file>ui/layout.js</file>
@ -72,6 +70,7 @@
<file>ui/locatePointer.js</file>
<file>ui/lookingGlass.js</file>
<file>ui/magnifier.js</file>
<file>ui/magnifierDBus.js</file>
<file>ui/main.js</file>
<file>ui/messageTray.js</file>
<file>ui/messageList.js</file>
@ -93,10 +92,10 @@
<file>ui/ripples.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>
<file>ui/screencast.js</file>
<file>ui/screenshot.js</file>
<file>ui/scripting.js</file>
<file>ui/search.js</file>
<file>ui/searchController.js</file>
<file>ui/sessionMode.js</file>
<file>ui/shellDBus.js</file>
<file>ui/shellEntry.js</file>
@ -107,7 +106,7 @@
<file>ui/switchMonitor.js</file>
<file>ui/unlockDialog.js</file>
<file>ui/userWidget.js</file>
<file>ui/welcomeDialog.js</file>
<file>ui/viewSelector.js</file>
<file>ui/windowAttentionHandler.js</file>
<file>ui/windowMenu.js</file>
<file>ui/windowManager.js</file>
@ -135,19 +134,12 @@
<file>ui/status/nightLight.js</file>
<file>ui/status/network.js</file>
<file>ui/status/power.js</file>
<file>ui/status/powerProfiles.js</file>
<file>ui/status/rfkill.js</file>
<file>ui/status/volume.js</file>
<file>ui/status/bluetooth.js</file>
<file>ui/status/remoteAccess.js</file>
<file>ui/status/screencast.js</file>
<file>ui/status/system.js</file>
<file>ui/status/thunderbolt.js</file>
<file>ui/realms/realmIndicator.js</file>
<file>ui/realms/realmManager.js</file>
<file>ui/realms/realmSearchProvider.js</file>
<file>ui/realms/realmSwitcher.js</file>
<file>ui/realms/realmWindowFrame.js</file>
<file>ui/realms/realmWindowMenu.js</file>
</gresource>
</gresources>

View File

@ -8,8 +8,6 @@ var PACKAGE_VERSION = '@PACKAGE_VERSION@';
var HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
/* 1 if networkmanager is available, 0 otherwise */
var HAVE_NETWORKMANAGER = @HAVE_NETWORKMANAGER@;
/* 1 if soup3 support is enabled, 0 otherwise */
var HAVE_SOUP2 = @HAVE_SOUP2@;
/* gettext package */
var GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
/* locale dir */

View File

@ -1,8 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ExtensionState, ExtensionType, getCurrentExtension,
getSettings, initTranslations, gettext, ngettext, pgettext,
openPrefs, isOutOfDate, installImporter, serializeExtension,
deserializeExtension */
getSettings, initTranslations, openPrefs, isOutOfDate,
installImporter, serializeExtension, deserializeExtension */
// Common utils for the extension system and the extension
// preferences tool
@ -10,6 +9,7 @@
const { Gio, GLib } = imports.gi;
const Gettext = imports.gettext;
const Lang = imports.lang;
const Config = imports.misc.config;
@ -113,64 +113,6 @@ function initTranslations(domain) {
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
Object.assign(extension, Gettext.domain(domain));
}
/**
* gettext:
* @param {string} str - the string to translate
*
* Translate @str using the extension's gettext domain
*
* @returns {string} - the translated string
*
*/
function gettext(str) {
return callExtensionGettextFunc('gettext', str);
}
/**
* ngettext:
* @param {string} str - the string to translate
* @param {string} strPlural - the plural form of the string
* @param {number} n - the quantity for which translation is needed
*
* Translate @str and choose plural form using the extension's
* gettext domain
*
* @returns {string} - the translated string
*
*/
function ngettext(str, strPlural, n) {
return callExtensionGettextFunc('ngettext', str, strPlural, n);
}
/**
* pgettext:
* @param {string} context - context to disambiguate @str
* @param {string} str - the string to translate
*
* Translate @str in the context of @context using the extension's
* gettext domain
*
* @returns {string} - the translated string
*
*/
function pgettext(context, str) {
return callExtensionGettextFunc('pgettext', context, str);
}
function callExtensionGettextFunc(func, ...args) {
const extension = getCurrentExtension();
if (!extension)
throw new Error(`${func}() can only be called from extensions`);
if (!extension[func])
throw new Error(`${func}() is used without calling initTranslations() first`);
return extension[func](...args);
}
/**
@ -232,13 +174,47 @@ function openPrefs() {
}
}
/**
* 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
*
* Check if a component is compatible for an extension.
* @required is an array, and at least one version must match.
* @current must be in the format <major>.<minor>.<point>.<micro>
* <micro> is always ignored
* <point> is ignored if <minor> is even (so you can target the
* whole stable release)
* <minor> and <major> must match
* Each target version must be at least <major> and <minor>
*/
function versionCheck(required, current) {
let currentArray = current.split('.');
let major = currentArray[0];
let minor = currentArray[1];
let point = currentArray[2];
for (let i = 0; i < required.length; i++) {
let requiredArray = required[i].split('.');
if (requiredArray[0] == major &&
requiredArray[1] == minor &&
((requiredArray[2] === undefined && parseInt(minor) % 2 == 0) ||
requiredArray[2] == point))
return true;
}
return false;
}
function isOutOfDate(extension) {
const [major] = Config.PACKAGE_VERSION.split('.');
return !extension.metadata['shell-version'].some(v => v.startsWith(major));
if (!versionCheck(extension.metadata['shell-version'], Config.PACKAGE_VERSION))
return true;
return false;
}
function serializeExtension(extension) {
let obj = { ...extension.metadata };
let obj = {};
Lang.copyProperties(extension.metadata, obj);
SERIALIZED_PROPERTIES.forEach(prop => {
obj[prop] = extension[prop];

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