Compare commits

..

1 Commits

Author SHA1 Message Date
Florian Müllner
078a1bda14 shellDBus: Return error on invalid app IDs
When passing an invalid or unknown app ID to FocusApp(), we currently
open the app picker and silently fail to select the desired app.
Instead of half-working like that, make it clear that the argument
was invalid by returning an appropriate error. (It's easy to get the
ID wrong, as unlike appstream/flatpak IDs, we include the ".desktop"
suffix).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/337
2019-01-08 22:40:56 +01:00
292 changed files with 33303 additions and 52337 deletions

1
.gitignore vendored
View File

@@ -80,4 +80,3 @@ tests/run-test.sh
*~
*.patch
*.sw?
.vscode

View File

@@ -1,88 +0,0 @@
stages:
- review
- source_check
- build
- test
variables:
JS_LOG: "js-report.txt"
POT_LOG: "pot-update.txt"
.only_default: &only_default
only:
- branches
- tags
- merge_requests
check_commit_log:
image: registry.gitlab.gnome.org/gnome/mutter/master:v1
stage: review
variables:
GIT_DEPTH: "100"
script:
- ./.gitlab-ci/check-commit-log.sh
only:
- merge_requests
js_check:
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
stage: source_check
script:
- find js -name '*.js' -exec js60 -c -s '{}' ';' 2>&1 | tee $JS_LOG
- (! grep -q . $JS_LOG)
<<: *only_default
only:
changes:
- js/**/*
artifacts:
paths:
- ${JS_LOG}
when: on_failure
build:
image: registry.gitlab.gnome.org/gnome/gnome-shell/master:v1
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
- ninja -C build
- ninja -C build install
<<: *only_default
artifacts:
expire_in: 1 day
paths:
- mutter
- build
test:
image: registry.gitlab.gnome.org/gnome/gnome-shell/master:v1
stage: test
before_script:
- ninja -C mutter/build install
script:
- 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-pot:
image: registry.gitlab.gnome.org/gnome/gnome-shell/master:v1
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

View File

@@ -1,19 +0,0 @@
FROM registry.gitlab.gnome.org/gnome/mutter/master:v1
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(copr)' && \
dnf copr enable -y fmuellner/gnome-shell-ci && \
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
# bt only exports HAVE_BLUETOOTH to js, rest are outdated build-requires
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel \
upower-devel python3-devel && \
# We'll build mutter ourselves
dnf remove -y --noautoremove mutter mutter-devel && \
# Needed for tests
dnf install -y '*/xvfb-run' gdm-lib accountsservice-libs && \
dnf clean all && \
rm -rf /var/cache/dnf

View File

@@ -1,18 +0,0 @@
FROM registry.fedoraproject.org/fedora:latest
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(copr)' && \
# For syntax checks with `find . -name '*.js' -exec js60 -c -s '{}' ';'`
dnf install -y findutils mozjs60-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 && \
rm -rf /var/cache/dnf

View File

@@ -1,31 +0,0 @@
#!/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,35 +0,0 @@
#!/usr/bin/bash
shell_branch=$(git describe --contains --all HEAD)
mutter_target=
git clone https://gitlab.gnome.org/GNOME/mutter.git
if [ $? -ne 0 ]; then
echo Checkout failed
exit 1
fi
cd mutter
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 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
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/$shell_branch)
mutter_target=${mutter_target:-$(git branch -r -l ${shell_branch#remotes/})}
mutter_target=${mutter_target:-origin/master}
echo Using $mutter_target instead
fi
git checkout -q $mutter_target

31
.project Normal file
View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>gnome-shell</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.linuxtools.cdt.autotools.genmakebuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.linuxtools.cdt.autotools.autotoolsNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,148 @@
#Fri Nov 28 14:33:30 EST 2008
eclipse.preferences.version=1
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
org.eclipse.cdt.core.formatter.alignment_for_compact_if=0
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=next_line_shifted
org.eclipse.cdt.core.formatter.brace_position_for_block=next_line_shifted
org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=next_line_shifted
org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line
org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=next_line
org.eclipse.cdt.core.formatter.brace_position_for_switch=next_line_shifted
org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=next_line
org.eclipse.cdt.core.formatter.compact_else_if=true
org.eclipse.cdt.core.formatter.continuation_indentation=2
org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=true
org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=true
org.eclipse.cdt.core.formatter.indent_empty_lines=false
org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.cdt.core.formatter.indentation.size=8
org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=insert
org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=insert
org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.cdt.core.formatter.lineSplit=80
org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.cdt.core.formatter.tabulation.char=space
org.eclipse.cdt.core.formatter.tabulation.size=2
org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false

View File

@@ -0,0 +1,4 @@
#Fri Nov 28 14:33:30 EST 2008
eclipse.preferences.version=1
formatter_profile=org.eclipse.cdt.ui.default.gnu_profile
formatter_settings_version=1

View File

@@ -0,0 +1,315 @@
#Fri Nov 28 14:43:43 EST 2008
eclipse.preferences.version=1
org.eclipse.wst.jsdt.core.codeComplete.argumentPrefixes=
org.eclipse.wst.jsdt.core.codeComplete.argumentSuffixes=
org.eclipse.wst.jsdt.core.codeComplete.fieldPrefixes=
org.eclipse.wst.jsdt.core.codeComplete.fieldSuffixes=
org.eclipse.wst.jsdt.core.codeComplete.localPrefixes=
org.eclipse.wst.jsdt.core.codeComplete.localSuffixes=
org.eclipse.wst.jsdt.core.codeComplete.staticFieldPrefixes=
org.eclipse.wst.jsdt.core.codeComplete.staticFieldSuffixes=
org.eclipse.wst.jsdt.core.compiler.codegen.inlineJsrBytecode=disabled
org.eclipse.wst.jsdt.core.compiler.codegen.targetPlatform=1.2
org.eclipse.wst.jsdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.wst.jsdt.core.compiler.compliance=1.4
org.eclipse.wst.jsdt.core.compiler.debug.lineNumber=generate
org.eclipse.wst.jsdt.core.compiler.debug.localVariable=generate
org.eclipse.wst.jsdt.core.compiler.debug.sourceFile=generate
org.eclipse.wst.jsdt.core.compiler.problem.assertIdentifier=warning
org.eclipse.wst.jsdt.core.compiler.problem.deprecation=warning
org.eclipse.wst.jsdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.wst.jsdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.wst.jsdt.core.compiler.problem.discouragedReference=warning
org.eclipse.wst.jsdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.wst.jsdt.core.compiler.problem.enumIdentifier=warning
org.eclipse.wst.jsdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.wst.jsdt.core.compiler.problem.fieldHiding=ignore
org.eclipse.wst.jsdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.wst.jsdt.core.compiler.problem.forbiddenReference=ignore
org.eclipse.wst.jsdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.wst.jsdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.wst.jsdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.wst.jsdt.core.compiler.problem.looseVarDecleration=warning
org.eclipse.wst.jsdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.wst.jsdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.wst.jsdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.wst.jsdt.core.compiler.problem.nullReference=ignore
org.eclipse.wst.jsdt.core.compiler.problem.optionalSemicolon=warning
org.eclipse.wst.jsdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.wst.jsdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
org.eclipse.wst.jsdt.core.compiler.problem.potentialNullReference=ignore
org.eclipse.wst.jsdt.core.compiler.problem.redundantNullCheck=ignore
org.eclipse.wst.jsdt.core.compiler.problem.undefinedField=warning
org.eclipse.wst.jsdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.wst.jsdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.wst.jsdt.core.compiler.problem.unresolvedFieldReference=ignore
org.eclipse.wst.jsdt.core.compiler.problem.unresolvedMethodReference=ignore
org.eclipse.wst.jsdt.core.compiler.problem.unresolvedTypeReference=ignore
org.eclipse.wst.jsdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.wst.jsdt.core.compiler.problem.unusedLabel=warning
org.eclipse.wst.jsdt.core.compiler.problem.unusedLocal=warning
org.eclipse.wst.jsdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.wst.jsdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.wst.jsdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.wst.jsdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.wst.jsdt.core.compiler.source=1.3
org.eclipse.wst.jsdt.core.formatter.align_type_members_on_columns=false
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_assignment=0
org.eclipse.wst.jsdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_compact_if=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.wst.jsdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.wst.jsdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.wst.jsdt.core.formatter.blank_lines_after_imports=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_after_package=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_field=0
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_imports=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_method=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_package=0
org.eclipse.wst.jsdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.wst.jsdt.core.formatter.blank_lines_between_type_declarations=0
org.eclipse.wst.jsdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_objlit_initializer=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.wst.jsdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.wst.jsdt.core.formatter.comment.format_block_comments=true
org.eclipse.wst.jsdt.core.formatter.comment.format_header=false
org.eclipse.wst.jsdt.core.formatter.comment.format_html=true
org.eclipse.wst.jsdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.wst.jsdt.core.formatter.comment.format_line_comments=true
org.eclipse.wst.jsdt.core.formatter.comment.format_source_code=true
org.eclipse.wst.jsdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.wst.jsdt.core.formatter.comment.indent_root_tags=true
org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.wst.jsdt.core.formatter.comment.line_length=80
org.eclipse.wst.jsdt.core.formatter.compact_else_if=true
org.eclipse.wst.jsdt.core.formatter.continuation_indentation=2
org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_objlit_initializer=1
org.eclipse.wst.jsdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.wst.jsdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.wst.jsdt.core.formatter.indent_empty_lines=false
org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.wst.jsdt.core.formatter.indentation.size=4
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_annotation=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_comma_in_objlit_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_objlit_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_objlit_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.wst.jsdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.wst.jsdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.wst.jsdt.core.formatter.keep_empty_objlit_initializer_on_one_line=false
org.eclipse.wst.jsdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.wst.jsdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.wst.jsdt.core.formatter.lineSplit=80
org.eclipse.wst.jsdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.wst.jsdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.wst.jsdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.wst.jsdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.wst.jsdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.wst.jsdt.core.formatter.tabulation.char=space
org.eclipse.wst.jsdt.core.formatter.tabulation.size=4
org.eclipse.wst.jsdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.wst.jsdt.core.formatter.wrap_before_binary_operator=true

View File

@@ -0,0 +1,10 @@
#Fri Nov 28 14:39:12 EST 2008
eclipse.preferences.version=1
formatter_profile=_gjs
formatter_settings_version=11
org.eclipse.wst.jsdt.ui.exception.name=e
org.eclipse.wst.jsdt.ui.gettersetter.use.is=true
org.eclipse.wst.jsdt.ui.javadoc=false
org.eclipse.wst.jsdt.ui.keywordthis=false
org.eclipse.wst.jsdt.ui.overrideannotation=true
org.eclipse.wst.jsdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>

View File

@@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

View File

@@ -0,0 +1 @@
Window

View File

@@ -80,7 +80,10 @@ e.g. `imports.ui.popupMenu`.
Each import block should be sorted alphabetically. Don't import modules you
don't use.
```javascript
const { GLib, Gio, St } = imports.gi;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
const Params = imports.misc.params;
@@ -118,53 +121,60 @@ See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/N
## Classes
There are many approaches to classes in JavaScript. We use standard ES6 classes
whenever possible, that is when not inheriting from GObjects.
There are many approaches to classes in JavaScript. We use our own class framework
(sigh), which is built in gjs. The advantage is that it supports inheriting from
GObjects, although this feature isn't used very often in the Shell itself.
```javascript
var IconLabelMenuItem = class extends PopupMenu.PopupMenuBaseItem {
constructor(icon, label) {
super({ reactive: false });
var IconLabelMenuItem = new Lang.Class({
Name: 'IconLabelMenuItem',
Extends: PopupMenu.PopupMenuBaseItem,
_init(icon, label) {
this.parent({ reactive: false });
this.actor.add_child(icon);
this.actor.add_child(label);
}
},
open() {
log("menu opened!");
}
};
```
For GObject inheritence, we use the GObject.registerClass() function provided
by gjs.
```javascript
var MyActor = GObject.registerClass(
class MyActor extends Clutter.Actor {
_init(params) {
super._init(params);
this.name = 'MyCustomActor';
}
});
```
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
automatically inherit from Object.
* Leave a blank line between the "class header" (Name, Extends, and other
things) and the "class body" (methods). Leave a blank line between each
method.
* No space before the colon, one space after.
* No trailing comma after the last item.
* Make sure to use a semicolon after the closing paren to the class. It's
still a giant function call, even though it may resemble a more
conventional syntax.
## GObject Introspection
GObject Introspection is a powerful feature that allows us to have native
bindings for almost any library built around GObject. If a library requires
you to inherit from a type to use it, you can do so:
```javascript
var MyClutterActor = GObject.registerClass(
class MyClutterActor extends Clutter.Actor {
var MyClutterActor = new Lang.Class({
Name: 'MyClutterActor',
Extends: Clutter.Actor,
vfunc_get_preferred_width(forHeight) {
vfunc_get_preferred_width(actor, forHeight) {
return [100, 100];
}
},
vfunc_get_preferred_height(forWidth) {
vfunc_get_preferred_height(actor, forWidth) {
return [100, 100];
}
},
vfunc_paint() {
vfunc_paint(actor) {
let alloc = this.get_allocation_box();
Cogl.set_source_color4ub(255, 0, 0, 255);
Cogl.rectangle(alloc.x1, alloc.y1,
@@ -197,18 +207,20 @@ that has a property called `actor`. We call this wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on
the actor itself:
```javascript
var MyClass = class {
constructor() {
var MyClass = new Lang.Class({
Name: 'MyClass',
_init() {
this.actor = new St.Button({ text: "This is a button" });
this.actor._delegate = this;
this.actor.connect('clicked', this._onClicked.bind(this));
}
},
_onClicked(actor) {
actor.set_label("You clicked the button!");
}
};
});
```
The 'delegate' property is important for anything which trying to get the
@@ -234,6 +246,8 @@ variable that can be captured in closures.
All closures should be wrapped with Function.prototype.bind or use arrow
notation.
```javascript
const Lang = imports.lang;
let closure1 = () => { this._fnorbate(); };
let closure2 = this._fnorbate.bind(this);
```
@@ -241,18 +255,19 @@ notation.
A more realistic example would be connecting to a signal on a method of a
prototype:
```javascript
const Lang = imports.lang;
const FnorbLib = imports.fborbLib;
var MyClass = class {
var MyClass = new Lang.Class({
_init() {
let fnorb = new FnorbLib.Fnorb();
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
}
},
_onFnorbFrobate(fnorb) {
this._updateFnorb();
}
};
});
```
## Object literal syntax
@@ -286,21 +301,23 @@ property.
```javascript
var ANIMATION_TIME = 2000;
var MyClass = class {
constructor() {
var MyClass = new Lang.Class({
Name: 'MyClass',
_init() {
this.actor = new St.BoxLayout();
this._position = 0;
}
},
get position() {
return this._position;
}
},
set position(value) {
this._position = value;
this.actor.set_position(value, value);
}
};
});
let myThing = new MyClass();
Tweener.addTween(myThing,

147
NEWS
View File

@@ -1,150 +1,3 @@
3.32.1
======
* Fix avatar scaling on login screen [Florian; #1024]
* Fix distortion of desktop zoom [Florian; #646]
* Fix mouse cursor visibility when using desktop zoom [Florian, Marco; #1020]
* Fix screen dimming after wake-up on lock screen [Xiaoguang; #900]
* Fix Alt+Esc switcher [Florian; #1064]
* Respect struts for popover placement [Andrea; #1102]
* Fix app icons updates after theme changes [Florian; #1117]
* Fix desktop zoom after resolution changes [Marco; #1120]
* Implement stick-to-finger workspace switch overview gestures [Florian; #516]
* Make World Clocks offsets relative to local time [Florian; #1157]
* Fix top app icon disappearing from dash [Florian; #1053]
* Update switch style to match new Adwaita [Jakub; !496]
* Ensure CSS units are pixel-aligned when scaling is used [Carlos; #91]
* Misc. bug fixes and cleanups [Florian, Jakub, Robert, Alex, Carlos, Phil,
Marco, Benjamin, AsciiWolf, Ray, verdre; !444, #1016, #1018, !449, #1036,
!455, #1094, !440, #1023, #624, #1017, !476, !473, !480, #1130, !485, !481,
!490, !489, #1151, !435, #1160, !482, #1150, #1166, !384]
Contributors:
AsciiWolf, Andrea Azzarone, Benjamin Berg, Carlos Garnacho, Victor Ibragimov,
Robert Mader, Alex Monday, Florian Müllner, Jakub Steiner, Ray Strode,
Marco Trevisan (Treviño), verdre, Xiaoguang Wang, Phil Wyett
Translators:
Victor Ibragimov [tg, af, et, ja], Bruce Cowan [en_GB], Piotr Drąg [tg],
Charles Monzat [fr], Khaled Hosny [ar], Goran Vidović [hr],
Cheng-Chia Tseng [zh_TW], Carmen Bianca BAKKER [eo], Daniel Mustieles [es],
Dušan Kazik [sk]
3.32.0
======
* Fix sizing issues in on-screen-keyboard emoji panel [Carlos; !439]
* Fix test linker failure on Debian/Ubuntu [Iain; !442]
* Avoid assertion when sizing fallback app icons from CSS [Florian; #1027]
* Fix mis-sized menu arrows after texture cache changes [Florian; !452]
Contributors:
Carlos Garnacho, Iain Lane, Florian Müllner
Translators:
Gábor Kelemen [hu], Victor Ibragimov [tg], Ryuta Fujii [ja], Piotr Drąg [af,
tg], Mart Raudsepp [et]
3.31.92
=======
* Fix visual glitch in submenus [Alex; #987]
* Support fractional scaling [Jonas, Marco; #765011, !5]
* Only consider visible children for :first-child/:last-child [Florian; !312]
* Hide trailing separator in search results [verdre; !311]
* Remember choice in inhibit-shortcuts dialogue [Olivier; !382]
* Don't toggle on-screen keyboard on every focus change [Carlos; !397]
* Fix legacy tray icons not responding to events on wayland [Florian; #191]
* Fix generating French OSK layout [Florian; #997]
* Use borderless round user images [Florian; #811]
* Misc. bug fixes and cleanups [Andrea, Robert, Florian, Marco, Niels,
Benjamin; !414, !417, !420, #996, !408, !422, !425, #1006, !427, !315,
#989, !430, !431, !432, #1015, !429, !423, !419, !434]
Contributors:
Jonas Ådahl, Alan, Andrea Azzarone, Benjamin Berg, Olivier Fourdan,
Carlos Garnacho, Niels De Graef, Robert Mader, Alex Monday, Florian Müllner,
Marco Trevisan (Treviño), verdre
Translators:
Carmen Bianca BAKKER [eo], Asier Sarasua Garmendia [eu], Stas Solovey [ru],
Changwoo Ryu [ko], Julien Humbert [fr], Milo Casagrande [it],
Марко Костић [sr], Ask Hjorth Larsen [da], Kukuh Syafaat [id],
Daniel Șerbănescu [ro], Bernd Homuth [de], Trần Ngọc Quân [vi],
Nathan Follens [nl], Rūdolfs Mazurs [lv], Aurimas Černius [lt]
3.31.91
=======
* Don't close on-screen-keyboard's language menu on hover [Florian; #171]
* Don't let unfullscreen gesture interfere with top bar taps [Jonas D.; #552]
* Always use symbolic user icon in system menu [Florian; #957]
* Add flags parameter in GrabAccelerators API [Andrea; #68]
* Misc. bug fixes and cleanups [Florian, Jonas A.; !399, !398, !400, !402,
!407, !410, !411]
Contributors:
Jonas Ådahl, Andrea Azzarone, Arnaud Bonatti, Jonas Dreßler, Florian Müllner
Translators:
Jordi Mas [ca], Ryuta Fujii [ja], Marek Cernocky [cs], Fran Dieguez [gl],
Jiri Grönroos [fi], Serdar Sağlam [tr], Anders Jonsson [sv],
Matej Urbančič [sl], Gun Chleoc [gd], Kukuh Syafaat [id],
Baurzhan Muftakhidinov [kk], Alan Mortensen [da], Rafael Fontenelle [pt_BR],
Sveinn í Felli [is]
3.31.90
=======
* Fix input methods after ibus restarts [Takao; #295]
* Refresh world clocks and weather sections [Florian; #262]
* Port to ES6 classes (update your extensions!) [Florian; !361]
* networkAgent: Advise users when WPS support is available [Lubomir; !329]
* Performance improvements [Carlos; #832, #815]
* Fix drag-and-drop with wacom pens [Carlos; #540]
* Fix CAPS LOCK indication on wayland [Carlos; #762881]
* Show details of non-sensitive notifications on lock screen [Philip; #726]
* Refine extension-prefs' error UI [Florian; !193]
* Add switch-to-application-n keybindings [Florian; #648000]
* Remove top bar translucency [Florian; #408]
* Support emojis and keypads in on-screen keyboard [Carlos; #675]
* Don't allow popups to re-enable keyboard shortcuts on lock screen
(CVE-2019-3820) [Florian, Ray; #851]
* Replace app menu [Florian; #624]
* Include commonly copied+pasted extension helpers [Florian; !150]
* Misc. bug fixes and cleanups [Florian, Daniel, Philip, Sergio, Pascal,
Georges, verdre, Carlos, Christopher; #780, #909, !316, !308, !309, #915,
!350, !362, !357, !365, !366, !283, !367, #942, !371, !373, !374, !343,
!375, !292, !317, !377, !379, !346, !383, #953, !388]
Contributors:
Sergio Costas, Christopher Davis, Bilal Elmoussaoui, Takao Fujiwara,
Carlos Garnacho, Niels De Graef, Christian Kellner, Ignat Loskutov,
Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, Lubomir Rintel,
Jakub Steiner, Ray Strode, verdre, Daniel van Vugt, Philip Withnall
Translators:
Daniel Mustieles [es], Carmen Bianca BAKKER [eo], Charles Monzat [fr],
Pieter Schalk Schoeman [af], Jordi Mas [ca], Matej Urbančič [sl],
Fran Dieguez [gl], Balázs Úr [hu], A S Alam [pa], Fabio Tomat [fur],
Aurimas Černius [lt], Piotr Drąg [pl], Marek Cernocky [cs], Ryuta Fujii [ja]
3.31.4
======
* Improve icon grid performance [Daniel; #174]
* Remove browser plugin [Michael; #766776]
* Add DBus API for introspecting the application state [Jonas, Olivier; !326]
* Always allow leaving the overview via the hot-corner [Pascal; #429]
* Misc. bug fixes [Florian, Jasper, Andrea, Sam, Dani, Cosimo, Jonas, Carlos;
#643595, #673767, !293, #783, #781, !298, !297, #782, !301, !314, !305, #799,
#632, !327]
Contributors:
Jonas Ådahl, Andrea Azzarone, Michael Catanzaro, Cosimo Cecchi, daniruiz,
Olivier Fourdan, Carlos Garnacho, Sam Hewitt, Andre Klapper, Florian Müllner,
Pascal Nowack, Jasper St. Pierre, RyuzakiKK, Marco Trevisan (Treviño),
João Paulo Rechi Vita, Daniel van Vugt
Translators:
Kristjan SCHMIDT [eo], Matej Urbančič [sl], Daniel Mustieles [es],
Fabio Tomat [fur], Emin Tufan Çetin [tr], Anders Jonsson [sv],
Ryuta Fujii [ja]
3.31.2
======
* Port away from and remove ShellGenericContainer [Georges; !153]

View File

@@ -11,14 +11,6 @@ see the [project wiki][project-wiki].
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
## Contributing
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/gnome-shell.
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.
## 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.

View File

@@ -1,40 +0,0 @@
cldr2json
=========
This script converts Unicode CLDR android keyboard layouts to JSON usable by
GNOME Shell.
CLDR keyboard layouts can be found at
<http://www.unicode.org/Public/cldr/latest/keyboards.zip>
Usage
=====
./cldr2json <input file or directory> <output directory>
example:
./cldr2json cldr/keyboards/android/ json_layouts/
Keyboard layout mapping
=======================
Unicode CLDR layout identifiers are language codes, while XKB layout
identifiers are... something else. The mapping between the two currently uses
heuristic based on the layout descriptions, in this order:
- if the CLDR layout description matches an XKB layout description, chose its
XKB identifier
- if one word of the CLDR layout description matches an XKB layout
description, chose its XKB identifier
- if the CLDR layout description matches one word of an XKB layout description,
chose its XKB identifier
That doesn't always work. For instance it fails for "en" language, that should
match "us" XKB identifier. For such cases, there is a mapping in
LOCALE_TO_XKB_OVERRIDES at the top of the script. If you discover a weird
mapping of if you get a "failed to find XKB mapping for <locale>" warning then
please consider adding an override there.

View File

@@ -1,208 +0,0 @@
#!/usr/bin/python3
#
# Copyright 2015 Daiki Ueno <dueno@src.gnome.org>
# 2016 Parag Nemade <pnemade@redhat.com>
# 2017 Alan <alan@boum.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see
# <http://www.gnu.org/licenses/>.
import glob
import json
import locale
import logging
import os
import re
import sys
import xml.etree.ElementTree
import gi
gi.require_version('GnomeDesktop', '3.0') # NOQA: E402
from gi.repository import GnomeDesktop
ESCAPE_PATTERN = re.compile(r'\\u\{([0-9A-Fa-f]+?)\}')
ISO_PATTERN = re.compile(r'[A-E]([0-9]+)')
LOCALE_TO_XKB_OVERRIDES = {
'af': 'za',
'en': 'us',
'en-GB': 'uk',
'es-US': 'latam',
'fr-CA': 'ca',
'hi': 'in+bolnagri',
'ky': 'kg',
'nl-BE': 'be',
'zu': None
}
def parse_single_key(value):
def unescape(m):
return chr(int(m.group(1), 16))
value = ESCAPE_PATTERN.sub(unescape, value)
return value
def parse_rows(keymap):
unsorted_rows = {}
for _map in keymap.iter('map'):
value = _map.get('to')
key = [parse_single_key(value)]
iso = _map.get('iso')
if not ISO_PATTERN.match(iso):
sys.stderr.write('invalid ISO key name: %s\n' % iso)
continue
if not iso[0] in unsorted_rows:
unsorted_rows[iso[0]] = []
unsorted_rows[iso[0]].append((int(iso[1:]), key))
# add subkeys
longPress = _map.get('longPress')
if longPress:
for value in longPress.split(' '):
subkey = parse_single_key(value)
key.append(subkey)
rows = []
for k, v in sorted(list(unsorted_rows.items()),
key=lambda x: x[0],
reverse=True):
row = []
for key in sorted(v, key=lambda x: x):
row.append(key[1])
rows.append(row)
return rows
def convert_xml(tree):
root = {}
for xml_keyboard in tree.iter("keyboard"):
locale_full = xml_keyboard.get("locale")
locale, sep, end = locale_full.partition("-t-")
root["locale"] = locale
for xml_name in tree.iter("name"):
name = xml_name.get("value")
root["name"] = name
root["levels"] = []
# parse levels
for index, keymap in enumerate(tree.iter('keyMap')):
# FIXME: heuristics here
modifiers = keymap.get('modifiers')
if not modifiers:
mode = 'default'
modifiers = ''
elif 'shift' in modifiers.split(' '):
mode = 'latched'
modifiers = 'shift'
else:
mode = 'locked'
level = {}
level["level"] = modifiers
level["mode"] = mode
level["rows"] = parse_rows(keymap)
root["levels"].append(level)
return root
def locale_to_xkb(locale, name):
if locale in sorted(LOCALE_TO_XKB_OVERRIDES.keys()):
xkb = LOCALE_TO_XKB_OVERRIDES[locale]
logging.debug("override for %s%s",
locale, xkb)
if xkb:
return xkb
else:
raise KeyError("layout %s explicitely disabled in overrides"
% locale)
xkb_names = sorted(name_to_xkb.keys())
if name in xkb_names:
return name_to_xkb[name]
else:
logging.debug("name %s failed" % name)
for sub_name in name.split(' '):
if sub_name in xkb_names:
xkb = name_to_xkb[sub_name]
logging.debug("dumb mapping failed but match with locale word: "
"%s (%s) → %s (%s)",
locale, name, xkb, sub_name)
return xkb
else:
logging.debug("sub_name failed")
for xkb_name in xkb_names:
for xkb_sub_name in xkb_name.split(' '):
if xkb_sub_name.strip('()') == name:
xkb = name_to_xkb[xkb_name]
logging.debug("dumb mapping failed but match with xkb word: "
"%s (%s) → %s (%s)",
locale, name, xkb, xkb_name)
return xkb
raise KeyError("failed to find XKB mapping for %s" % locale)
def convert_file(source_file, destination_path):
logging.info("Parsing %s", source_file)
itree = xml.etree.ElementTree.ElementTree()
itree.parse(source_file)
root = convert_xml(itree)
try:
xkb_name = locale_to_xkb(root["locale"], root["name"])
except KeyError as e:
logging.warn(e)
return False
destination_file = os.path.join(destination_path, xkb_name + ".json")
with open(destination_file, 'w', encoding="utf-8") as dest_fd:
json.dump(root, dest_fd, ensure_ascii=False, indent=2, sort_keys=True)
logging.debug("written %s", destination_file)
def load_xkb_mappings():
xkb = GnomeDesktop.XkbInfo()
layouts = xkb.get_all_layouts()
name_to_xkb = {}
for layout in layouts:
name = xkb.get_layout_info(layout).display_name
name_to_xkb[name] = layout
return name_to_xkb
locale.setlocale(locale.LC_ALL, "C")
name_to_xkb = load_xkb_mappings()
if __name__ == "__main__":
if "DEBUG" in os.environ:
logging.basicConfig(level=logging.DEBUG)
if len(sys.argv) < 2:
print("supply a CLDR keyboard file")
sys.exit(1)
if len(sys.argv) < 3:
print("supply an output directory")
sys.exit(1)
source = sys.argv[1]
destination = sys.argv[2]
if os.path.isfile(source):
convert_file(source, destination)
elif os.path.isdir(source):
for path in glob.glob(source + "/*-t-k0-android.xml"):
convert_file(path, destination)

View File

@@ -1,6 +1,5 @@
dbus_interfaces = [
'org.gnome.Shell.Extensions.xml',
'org.gnome.Shell.Introspect.xml',
'org.gnome.Shell.PadOsd.xml',
'org.gnome.Shell.Screencast.xml',
'org.gnome.Shell.Screenshot.xml',

View File

@@ -1,12 +0,0 @@
<node>
<interface name="org.gnome.Shell.CalendarServer">
<method name="GetEvents">
<arg type="x" direction="in" />
<arg type="x" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sssbxxa{sv})" direction="out" />
</method>
<property name="HasCalendars" type="b" access="read" />
<signal name="Changed" />
</interface>
</node>

View File

@@ -1,61 +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.Shell.Introspect:
@short_description: Introspection interface
The interface used to introspect the state of Shell, such as running
applications, currently active application, etc.
-->
<interface name="org.gnome.Shell.Introspect">
<!--
RunningApplicationsChanged:
@short_description: Notifies when the running applications changes
-->
<signal name="RunningApplicationsChanged" />
<!--
GetRunningApplications:
@short_description: Retrieves the description of all running applications
Each application is associated by an application ID. The details of
each application consists of a varlist of keys and values. Available
keys are listed below.
'active-on-seats' - (as) list of seats the application is active on
(a seat only has at most one active
application)
-->
<method name="GetRunningApplications">
<arg name="apps" direction="out" type="a{sa{sv}}" />
</method>
<!--
GetWindows:
@short_description: Retrieves the current list of windows and their properties
A window is exposed as:
* t ID: unique ID of the window
* a{sv} properties: high-level properties
Known properties:
- "title" (s): (readonly) title of the window
- "app-id" (s): (readonly) application ID of the window
- "wm-class" (s): (readonly) class of the window
- "client-type" (u): (readonly) 0 for Wayland, 1 for X11
- "is-hidden" (b): (readonly) if the window is currently hidden
- "has-focus" (b): (readonly) if the window currently have
keyboard focus
- "width" (u): (readonly) width of the window
- "height" (u): (readonly) height of the window
-->
<method name="GetWindows">
<arg name="windows" direction="out" type="a{ta{sv}}" />
</method>
</interface>
</node>

View File

@@ -9,6 +9,9 @@
<method name="ShowOSD">
<arg type="a{sv}" direction="in" name="params"/>
</method>
<method name="ShowMonitorLabels">
<arg type="a{uv}" direction="in" name="params"/>
</method>
<method name="ShowMonitorLabels2">
<arg type="a{sv}" direction="in" name="params"/>
</method>
@@ -19,22 +22,17 @@
<method name="ShowApplications"/>
<method name="GrabAccelerator">
<arg type="s" direction="in" name="accelerator"/>
<arg type="u" direction="in" name="modeFlags"/>
<arg type="u" direction="in" name="grabFlags"/>
<arg type="u" direction="in" name="flags"/>
<arg type="u" direction="out" name="action"/>
</method>
<method name="GrabAccelerators">
<arg type="a(suu)" direction="in" name="accelerators"/>
<arg type="a(su)" direction="in" name="accelerators"/>
<arg type="au" direction="out" name="actions"/>
</method>
<method name="UngrabAccelerator">
<arg type="u" direction="in" name="action"/>
<arg type="b" direction="out" name="success"/>
</method>
<method name="UngrabAccelerators">
<arg type="au" direction="in" name="action"/>
<arg type="b" direction="out" name="success"/>
</method>
<signal name="AcceleratorActivated">
<arg name="action" type="u"/>
<arg name="parameters" type="a{sv}"/>

File diff suppressed because it is too large Load Diff

View File

@@ -39,9 +39,7 @@
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Rfkill.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.CalendarServer.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.PerfHelper.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.PortalHelper.xml</file>

View File

@@ -6,7 +6,6 @@
<file>be.json</file>
<file>bg.json</file>
<file>by.json</file>
<file>ca.json</file>
<file>cz.json</file>
<file>de.json</file>
<file>dk.json</file>
@@ -55,6 +54,5 @@
<file>us.json</file>
<file>vn.json</file>
<file>za.json</file>
<file>emoji.json</file>
</gresource>
</gresources>

View File

@@ -21,8 +21,10 @@
<file>noise-texture.png</file>
<file>pad-osd.css</file>
<file>process-working.svg</file>
<file>toggle-off-us.svg</file>
<file>toggle-off-intl.svg</file>
<file>toggle-off-hc.svg</file>
<file>toggle-on-us.svg</file>
<file>toggle-on-intl.svg</file>
<file>toggle-on-hc.svg</file>
</gresource>

View File

@@ -90,14 +90,6 @@
adapter is ever seen not to have devices associated to it.
</description>
</key>
<key name="introspect" type="b">
<default>false</default>
<summary>Enable introspection API</summary>
<description>
Enables a D-Bus API that allows to introspect the application state of
the shell.
</description>
</key>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
</schema>
@@ -145,42 +137,6 @@
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
<description></description>
</key>
<key name="switch-to-application-1" type="as">
<default>["&lt;Super&gt;1"]</default>
<summary>Switch to application 1</summary>
</key>
<key name="switch-to-application-2" type="as">
<default>["&lt;Super&gt;2"]</default>
<summary>Switch to application 2</summary>
</key>
<key name="switch-to-application-3" type="as">
<default>["&lt;Super&gt;3"]</default>
<summary>Switch to application 3</summary>
</key>
<key name="switch-to-application-4" type="as">
<default>["&lt;Super&gt;4"]</default>
<summary>Switch to application 4</summary>
</key>
<key name="switch-to-application-5" type="as">
<default>["&lt;Super&gt;5"]</default>
<summary>Switch to application 5</summary>
</key>
<key name="switch-to-application-6" type="as">
<default>["&lt;Super&gt;6"]</default>
<summary>Switch to application 6</summary>
</key>
<key name="switch-to-application-7" type="as">
<default>["&lt;Super&gt;7"]</default>
<summary>Switch to application 7</summary>
</key>
<key name="switch-to-application-8" type="as">
<default>["&lt;Super&gt;8"]</default>
<summary>Switch to application 8</summary>
</key>
<key name="switch-to-application-9" type="as">
<default>["&lt;Super&gt;9"]</default>
<summary>Switch to application 9</summary>
</key>
</schema>
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"

View File

@@ -1,599 +0,0 @@
{
"levels": [
{
"level": "",
"mode": "default",
"rows": [
[
[
"q"
],
[
"w"
],
[
"e",
"é",
"è",
"ê",
"ë",
"%",
"ę",
"ė",
"ē"
],
[
"r"
],
[
"t"
],
[
"y",
"%",
"ÿ"
],
[
"u",
"ù",
"û",
"%",
"ü",
"ú",
"ū"
],
[
"i",
"î",
"%",
"ï",
"ì",
"í",
"į",
"ī"
],
[
"o",
"ô",
"œ",
"%",
"ö",
"ò",
"ó",
"õ",
"ø",
"ō",
"º"
],
[
"p"
]
],
[
[
"a",
"à",
"â",
"%",
"æ",
"á",
"ä",
"ã",
"å",
"ā",
"ª"
],
[
"s"
],
[
"d"
],
[
"f"
],
[
"g"
],
[
"h"
],
[
"j"
],
[
"k"
],
[
"l"
]
],
[
[
"z"
],
[
"x"
],
[
"c",
"ç",
"ć",
"č"
],
[
"v"
],
[
"b"
],
[
"n"
],
[
"m"
]
],
[
[
","
],
[
" "
],
[
".",
"#",
"!",
",",
"?",
"-",
":",
"'",
"@"
]
]
]
},
{
"level": "shift",
"mode": "latched",
"rows": [
[
[
"Q"
],
[
"W"
],
[
"E",
"É",
"È",
"Ê",
"Ë",
"%",
"Ę",
"Ė",
"Ē"
],
[
"R"
],
[
"T"
],
[
"Y",
"%",
"Ÿ"
],
[
"U",
"Ù",
"Û",
"%",
"Ü",
"Ú",
"Ū"
],
[
"I",
"Î",
"%",
"Ï",
"Ì",
"Í",
"Į",
"Ī"
],
[
"O",
"Ô",
"Œ",
"%",
"Ö",
"Ò",
"Ó",
"Õ",
"Ø",
"Ō",
"º"
],
[
"P"
]
],
[
[
"A",
"À",
"Â",
"%",
"Æ",
"Á",
"Ä",
"Ã",
"Å",
"Ā",
"ª"
],
[
"S"
],
[
"D"
],
[
"F"
],
[
"G"
],
[
"H"
],
[
"J"
],
[
"K"
],
[
"L"
]
],
[
[
"Z"
],
[
"X"
],
[
"C",
"Ç",
"Ć",
"Č"
],
[
"V"
],
[
"B"
],
[
"N"
],
[
"M"
]
],
[
[
","
],
[
" "
],
[
".",
"#",
"!",
",",
"?",
"-",
":",
"'",
"@"
]
]
]
},
{
"level": "opt",
"mode": "locked",
"rows": [
[
[
"1",
"¹",
"½",
"⅓",
"¼",
"⅛"
],
[
"2",
"²",
"⅔"
],
[
"3",
"³",
"¾",
"⅜"
],
[
"4",
"⁴"
],
[
"5",
"⅝"
],
[
"6"
],
[
"7",
"⅞"
],
[
"8"
],
[
"9"
],
[
"0",
"ⁿ",
"∅"
]
],
[
[
"@"
],
[
"#"
],
[
"$",
"¢",
"£",
"€",
"¥",
"₱"
],
[
"%",
"‰"
],
[
"&"
],
[
"-",
"_",
"",
"—",
"·"
],
[
"+",
"±"
],
[
"(",
"<",
"{",
"["
],
[
")",
">",
"}",
"]"
]
],
[
[
"*",
"†",
"‡",
"★"
],
[
"\"",
"“",
"”",
"«",
"»"
],
[
"'",
"",
"",
"",
""
],
[
":"
],
[
";"
],
[
"!",
"¡"
],
[
"?",
"¿"
]
],
[
[
"_"
],
[
"/"
],
[
" "
],
[
","
],
[
".",
"…"
]
]
]
},
{
"level": "opt+shift",
"mode": "locked",
"rows": [
[
[
"~"
],
[
"`"
],
[
"|"
],
[
"•",
"♪",
"♥",
"♠",
"♦",
"♣"
],
[
"√"
],
[
"Π",
"π"
],
[
"÷"
],
[
"×"
],
[
"¶",
"§"
],
[
"∆"
]
],
[
[
"£"
],
[
"¢"
],
[
"€"
],
[
"¥"
],
[
"^",
"↑",
"↓",
"←",
"→"
],
[
"°",
"",
"″"
],
[
"=",
"≠",
"≈",
"∞"
],
[
"{"
],
[
"}"
]
],
[
[
"\\"
],
[
"©"
],
[
"®"
],
[
"™"
],
[
"℅"
],
[
"["
],
[
"]"
]
],
[
[
"<",
"",
"≤",
"«"
],
[
">",
"",
"≥",
"»"
],
[
" "
],
[
","
],
[
".",
"…"
]
]
]
}
],
"locale": "fr-CA",
"name": "French Canada"
}

View File

@@ -6,20 +6,10 @@
"rows": [
[
[
"a",
"à",
"â",
"%",
"æ",
"á",
"ä",
"ã",
"å",
"ā",
"ª"
"q"
],
[
"z"
"w"
],
[
"e",
@@ -81,7 +71,17 @@
],
[
[
"q"
"a",
"à",
"â",
"%",
"æ",
"á",
"ä",
"ã",
"å",
"ā",
"ª"
],
[
"s"
@@ -106,14 +106,11 @@
],
[
"l"
],
[
"m"
]
],
[
[
"w"
"z"
],
[
"x"
@@ -134,11 +131,7 @@
"n"
],
[
"'",
"",
"",
"",
""
"m"
]
],
[
@@ -168,20 +161,10 @@
"rows": [
[
[
"A",
"À",
"Â",
"%",
"Æ",
"Á",
"Ä",
"Ã",
"Å",
"Ā",
"ª"
"Q"
],
[
"Z"
"W"
],
[
"E",
@@ -243,7 +226,17 @@
],
[
[
"Q"
"A",
"À",
"Â",
"%",
"Æ",
"Á",
"Ä",
"Ã",
"Å",
"Ā",
"ª"
],
[
"S"
@@ -268,14 +261,11 @@
],
[
"L"
],
[
"M"
]
],
[
[
"W"
"Z"
],
[
"X"
@@ -296,11 +286,7 @@
"N"
],
[
"'",
"",
"",
"",
""
"M"
]
],
[
@@ -383,10 +369,10 @@
"#"
],
[
"",
"$",
"¢",
"£",
"$",
"",
"¥",
"₱"
],
@@ -524,16 +510,15 @@
[
"£"
],
[
"¢"
],
[
"€"
],
[
"¥"
],
[
"$",
"¢"
],
[
"¢"
],
[
"^",
"↑",
@@ -609,6 +594,6 @@
]
}
],
"locale": "fr",
"name": "French"
"locale": "fr-CA",
"name": "French Canada"
}

View File

@@ -2,23 +2,26 @@
// it gets @if ed depending on $variant
$base_color: if($variant == 'light', #ffffff, lighten(desaturate(#241f31, 20%), 2%));
$bg_color: if($variant == 'light', #f6f5f4, desaturate(#3d3846, 10%));
$fg_color: if($variant == 'light', #2e3436, #eeeeec);
$base_color: if($variant =='light', #ffffff, #292929);
$bg_color: if($variant =='light', #ededed, #393f3f);
$fg_color: if($variant =='light', #2e3436, #eeeeec);
$selected_fg_color: #ffffff;
$selected_bg_color: if($variant == 'light', #3584e4, darken(#3584e4, 20%));
$selected_borders_color: if($variant== 'light', darken($selected_bg_color, 15%), darken($selected_bg_color, 30%));
$borders_color: if($variant == 'light', darken($bg_color, 18%), darken($bg_color, 10%));
$borders_edge: if($variant == 'light', transparentize(white, 0.2), transparentize($fg_color, 0.93));
$link_color: if($variant == 'light', darken($selected_bg_color, 10%), lighten($selected_bg_color, 20%));
$link_visited_color: if($variant == 'light', darken($selected_bg_color, 20%), lighten($selected_bg_color, 10%));
$selected_bg_color: if($variant == 'light', #4a90d9, darken(#4a90d9,20%));
$selected_borders_color: if($variant=='light', darken($selected_bg_color, 30%),
darken($selected_bg_color, 20%));
$borders_color: if($variant =='light', darken($bg_color,30%), darken($bg_color,12%));
$borders_edge: if($variant =='light', white, transparentize($fg_color, 0.9));
$link_color: if($variant == 'light', darken($selected_bg_color,10%),
lighten($selected_bg_color,20%));
$link_visited_color: if($variant == 'light', darken($selected_bg_color,20%),
lighten($selected_bg_color,10%));
$top_hilight: $borders_edge;
$warning_color: #f57900;
$error_color: #ff8080;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$error_color: #cc0000;
$success_color: if($variant =='light', #73d216, darken(#73d216,10%));
$destructive_color: if($variant =='light', #ef2929, darken(#ef2929,10%));
$osd_fg_color: #eeeeec;
$osd_bg_color: #2e3436;

View File

@@ -157,13 +157,18 @@ StScrollBar {
/* Switches */
.toggle-switch {
width: 46px;
width: 65px;
height: 22px;
background-size: contain;
background-image: url("resource:///org/gnome/shell/theme/toggle-off-intl.svg");
&:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-intl.svg"); }
}
@each $v in us, intl {
.toggle-switch-#{$v} {
background-image: url("resource:///org/gnome/shell/theme/toggle-off-#{$v}.svg");
&:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-#{$v}.svg"); }
}
}
/* links */
.shell-link {
color: $link_color;
@@ -262,7 +267,8 @@ StScrollBar {
}
.end-session-dialog-logout-icon {
border-radius: 99px;
//border: 2px solid #8b8b8b;
border-radius: 5px;
width: 48px;
height: 48px;
background-size: contain;
@@ -387,7 +393,7 @@ StScrollBar {
.prompt-dialog-error-label {
font-size: 10pt;
color: $warning_color;
color: $error_color;
padding-bottom: 8px;
}
@@ -422,7 +428,7 @@ StScrollBar {
}
.polkit-dialog-user-icon {
border-radius: 99px;
border-radius: 5px;
background-size: contain;
width: 48px;
height: 48px;
@@ -502,7 +508,6 @@ StScrollBar {
.popup-menu-arrow { } //defined globally in the TOP BAR
.popup-sub-menu {
padding-bottom: 1px;
background-color: darken($bg_color,2%);
box-shadow: inset 0 -1px 0px lighten($borders_color,5%);
}
@@ -724,7 +729,9 @@ StScrollBar {
/* TOP BAR */
#panel {
background-color: black;
background-color: rgba(0, 0, 0, 0.35);
/* transition from solid to transparent */
transition-duration: 500ms;
font-weight: bold;
height: 1.86em;
font-feature-settings: "tnum";
@@ -741,7 +748,7 @@ StScrollBar {
.panel-corner {
-panel-corner-radius: $panel-corner-radius;
-panel-corner-background-color: black;
-panel-corner-background-color: rgba(0, 0, 0, 0.35);
-panel-corner-border-width: 2px;
-panel-corner-border-color: transparent;
@@ -760,7 +767,9 @@ StScrollBar {
-natural-hpadding: 12px;
-minimum-hpadding: 6px;
font-weight: bold;
color: #ccc;
color: #eee;
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
transition-duration: 100ms;
.app-menu-icon {
-st-icon-style: symbolic;
@@ -769,8 +778,21 @@ StScrollBar {
//dimensions of the icon are hardcoded
}
.system-status-icon,
.app-menu-icon > StIcon,
.popup-menu-arrow {
icon-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
}
&:hover {
color: lighten($fg_color, 10%);
text-shadow: 0px 1px 6px rgba(0, 0, 0, 1);
.system-status-icon,
.app-menu-icon > StIcon,
.popup-menu-arrow {
icon-shadow: 0px 1px 6px rgba(0, 0, 0, 1);
}
}
&:active, &:overview, &:focus, &:checked {
@@ -779,6 +801,8 @@ StScrollBar {
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0px lighten($selected_bg_color,5%);
color: lighten($fg_color,10%);
& > .system-status-icon { icon-shadow: black 0 2px 2px; }
}
.system-status-icon { icon-size: 1.09em; padding: 0 5px; }
@@ -803,6 +827,31 @@ StScrollBar {
.screencast-indicator { color: $warning_color; }
.remote-access-indicator { color: $warning_color; }
&.solid {
background-color: black;
/* transition from transparent to solid */
transition-duration: 300ms;
.panel-corner {
-panel-corner-background-color: black;
}
.panel-button {
color: #ccc;
text-shadow: none;
&:hover, &:active, &:overview, &:focus, &:checked {
color: lighten($fg_color, 10%);
}
}
.system-status-icon,
.app-menu-icon > StIcon,
.popup-menu-arrow {
icon-shadow: none;
}
}
}
// calendar popover
@@ -873,47 +922,14 @@ StScrollBar {
font-weight: bold;
}
.weather-header.location {
font-weight: normal;
font-size: 0.9em;
}
.world-clocks-grid,
.weather-grid {
.world-clocks-grid {
spacing-rows: 0.4em;
spacing-columns: 0.8em;
}
.weather-box {
spacing: 0.4em;
}
.world-clocks-city {
font-weight: bold;
font-size: 0.9em;
}
.world-clocks-time {
color: darken($fg_color,20%);
font-feature-settings: "tnum";
font-size: 1.2em;
}
.world-clocks-timezone {
color: darken($fg_color,40%);
font-feature-settings: "tnum";
font-size: 0.9em;
}
.weather-forecast-icon {
icon-size: 2.18em;
}
.weather-forecast-time {
color: darken($fg_color,40%);
font-size: 0.8em;
}
.calendar-month-label {
color: darken($fg_color,5%);
font-weight: bold;
@@ -1026,11 +1042,6 @@ StScrollBar {
-st-icon-style: symbolic;
}
.message-icon-bin > .fallback-window-icon {
width: 1.09em;
height: 1.09em;
}
.message-secondary-bin {
padding: 0 0.82em;;
}
@@ -1073,14 +1084,18 @@ StScrollBar {
background-color: $bg_color;
border: 2px solid $bg_color;
border-radius: 2px;
icon-size: 32px !important;
padding: 6px; }
icon-size: 16px;
padding: 8px; }
}
// a little unstructured mess:
.system-switch-user-submenu-icon {
.system-switch-user-submenu-icon.user-icon {
icon-size: 20px;
padding: 0 2px;
}
.system-switch-user-submenu-icon.default-icon {
icon-size: 16px;
padding: 0 4px;
}
@@ -1092,11 +1107,6 @@ StScrollBar {
.label-shadow { color: transparent; }
}
.app-menu,
.app-well-menu {
max-width: 27.25em;
}
.aggregate-menu {
min-width: 21em;
.popup-menu-icon { padding: 0 4px; }
@@ -1137,36 +1147,32 @@ StScrollBar {
.ripple-box:rtl { border-radius: 0 0 0 52px; } // just a simple change to the border radius position
// Rubberband for select-area screenshots
.select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color;
}
// not really top bar only
.popup-menu-arrow { icon-size: 1.09em; }
.popup-menu-arrow { width: 16px; height: 16px; }
.popup-menu-icon { icon-size: 1.09em; }
//close buttons
.window-close {
background-color: $selected_bg_color;
color: white;
background-color: white;
border-radius: 24px;
border: 2px solid $selected_bg_color;
border: 4px solid $selected_bg_color;
box-shadow: inset 0 -4px 0 0 transparentize($selected_bg_color, 0.5);
color: $selected_bg_color;
height: 24px;
width: 24px;
-shell-close-overlap: 11px;
box-shadow: -1px 1px 5px 0px transparentize(black, 0.5);
-shell-close-overlap: 14px;
&:hover {
background-color: lighten($selected_bg_color, 5%);
border-color: lighten($selected_bg_color, 5%);
background-color: $selected_bg_color;
border-color: white;
color: white;
}
&:active {
background-color: darken($selected_bg_color, 5%);
border-color: darken($selected_bg_color, 5%);
background-color: mix(white, $selected_bg_color, 75%);
border-color: $selected_bg_color;
color: $selected_bg_color;
}
}
@@ -1231,14 +1237,13 @@ StScrollBar {
}
.window-clone-border {
$_bg: transparentize(white, 0.65);
border: 5px solid $_bg;
border-radius: 6px;
border: 4px solid $selected_bg_color;
border-radius: 4px;
// 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 $_bg;
}
box-shadow: inset 0px 0px 0px 1px $selected_bg_color;
}
.window-caption {
spacing: 25px;
color: $selected_fg_color;
@@ -1289,8 +1294,6 @@ StScrollBar {
.search-section-separator { height: 2px; background-color: rgba(255, 255, 255, 0.2); }
.search-section:last-child .search-section-separator { background-color: transparent; }
.list-search-result-content { spacing: 30px; }
.list-search-result-title { color: darken($osd_fg_color,5%); spacing: 12px; }
.list-search-result-description { color: transparentize(darken($osd_fg_color,15%), 0.5); }
@@ -1453,13 +1456,13 @@ StScrollBar {
height: 12px;
background-color: transparent;
border: 2px solid rgba(255, 255, 255, 0.4);
border-radius: 12px;
border-radius:12px;
}
&:hover .page-indicator-icon { border-color: white; }
&:active .page-indicator-icon { border: none; margin: 2px; background-color: white; }
&:active .page-indicator-icon { border: none; margin: 2px; background-color:#fff; }
&:checked .page-indicator-icon,
&:checked:active .page-indicator-icon { background-color: white;}
&:checked:active { background-color: #fff;}
}
.no-frequent-applications-label { @extend %status_text; }
@@ -1643,15 +1646,6 @@ StScrollBar {
#keyboard {
background-color: transparentize($osd_bg_color, 0.3);
.page-indicator {
padding: 4px 4px;
.page-indicator-icon {
width: 6px;
height: 6px
}
}
}
.key-container {
@@ -1661,8 +1655,8 @@ StScrollBar {
.keyboard-key {
background-color: #393f3f;
min-height: 1.2em;
min-width: 1.2em;
min-height: 2em;
min-width: 2em;
font-size: 16pt;
border-radius: 3px;
border: 1px solid #464d4d;
@@ -1713,20 +1707,6 @@ StScrollBar {
-boxpointer-gap: 5px;
}
.emoji-page {
.keyboard-key {
background-color: transparent;
border: none;
}
}
.emoji-panel {
.keyboard-key:latched {
border-color: #005684;
background-color: #006098;
}
}
// IBus Candidate Popup
.candidate-popup-content {
@@ -1761,11 +1741,13 @@ StScrollBar {
/* Auth Dialogs & Screen Shield */
.user-icon {
.framed-user-icon {
background-size: contain;
border: 2px solid $osd_fg_color;
color: $osd_fg_color;
border-radius: 99px;
border-radius: 3px;
&:hover {
border-color: lighten($osd_fg_color,30%);
color: lighten($osd_fg_color,30%);
}
}

View File

@@ -10,62 +10,124 @@
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="46"
width="65"
height="22"
viewBox="0 0 46 22"
id="svg2857"
version="1.1"
id="svg2751"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="toggle-off-intl.svg">
inkscape:version="0.48.5 r10040"
sodipodi:docname="toggle-off-us.svg">
<defs
id="defs2745">
id="defs2859">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
<inkscape:perspective
id="perspective2843"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
id="linearGradient3329">
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#39393a;stop-opacity:1;"
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop3325" />
id="stop76471-7-1-5" />
<stop
style="stop-color:#302f30;stop-opacity:1"
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop3327" />
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4-0"
is_visible="true" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient37802-8"
id="linearGradient12311-3-1-0-5-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
x1="610.13782"
y1="501.43866"
x2="610.13782"
y2="492.52756" />
<linearGradient
id="linearGradient37802-8"
inkscape:collect="always">
<stop
id="stop37804-1"
offset="0"
style="stop-color:#2c2c2c;stop-opacity:1" />
<stop
id="stop37806-8"
offset="1"
style="stop-color:#16191a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3329"
id="linearGradient3331"
x1="53"
y1="294.42917"
x2="53"
y2="309.80417"
y2="492.52756"
x2="610.13782"
y1="501.43866"
x1="610.13782"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-42.760724)" />
id="linearGradient13602"
xlink:href="#linearGradient37802-8"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#535353"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-19.436775"
inkscape:cy="-13.499723"
inkscape:cx="-5.0602834"
inkscape:cy="16.473273"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:current-layer="g37994"
showgrid="false"
units="px"
inkscape:pagecheckerboard="true"
inkscape:window-width="2560"
inkscape:window-height="1375"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid3298" />
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2748">
id="metadata2862">
<rdf:RDF>
<cc:Work
rdf:about="">
@@ -80,24 +142,68 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.17916)">
<rect
style="opacity:1;vector-effect:none;fill:#323233;fill-opacity:1;stroke:#272728;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
id="rect3296"
width="44.446434"
height="20.910645"
x="0.625"
y="291.71494"
rx="10.455324"
ry="10.073335" />
<rect
ry="10.455322"
rx="10.455322"
y="291.71494"
x="0.5428465"
height="20.910645"
width="21.142862"
id="rect3300"
style="opacity:1;vector-effect:none;fill:url(#linearGradient3331);fill-opacity:1;stroke:#151515;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
</g>
<g
transform="translate(-49.946213,-1.890275)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
sodipodi:type="arc"
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.15627193;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="path13479"
sodipodi:cx="16.4375"
sodipodi:cy="10.8125"
sodipodi:rx="4.3125"
sodipodi:ry="4.3125"
d="m 20.75,10.8125 a 4.3125,4.3125 0 1 1 -8.625,0 4.3125,4.3125 0 1 1 8.625,0 z"
transform="matrix(1.4212691,0,0,1.1514287,577.38488,1761.1138)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -0,0 +1,255 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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="65"
height="22"
id="svg2857"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="toggle-on-intl.svg">
<defs
id="defs2859">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
<inkscape:perspective
id="perspective2843"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient37802"
id="linearGradient12311-3-1-0-5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
x1="610.13782"
y1="501.43866"
x2="610.13782"
y2="492.52756" />
<linearGradient
id="linearGradient37802"
inkscape:collect="always">
<stop
id="stop37804"
offset="0"
style="stop-color:#2c2c2c;stop-opacity:1" />
<stop
id="stop37806"
offset="1"
style="stop-color:#16191a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4-3"
id="linearGradient77680"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.0322581,717.71949,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4-3">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5-7" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0-9" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4-0"
is_visible="true" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient37802-8"
id="linearGradient12311-3-1-0-5-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
x1="610.13782"
y1="501.43866"
x2="610.13782"
y2="492.52756" />
<linearGradient
id="linearGradient37802-8"
inkscape:collect="always">
<stop
id="stop37804-1"
offset="0"
style="stop-color:#2c2c2c;stop-opacity:1" />
<stop
id="stop37806-8"
offset="1"
style="stop-color:#16191a;stop-opacity:1" />
</linearGradient>
<linearGradient
y2="492.52756"
x2="610.13782"
y1="501.43866"
x1="610.13782"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)"
gradientUnits="userSpaceOnUse"
id="linearGradient13602"
xlink:href="#linearGradient37802-8"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="16.760995"
inkscape:cy="21.955673"
inkscape:document-units="px"
inkscape:current-layer="g37994"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1375"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2862">
<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
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
</g>
<g
transform="translate(-49.946213,-1.890275)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
</g>
<text
xml:space="preserve"
style="font-size:13.79166794px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
x="520.29974"
y="1997.0011"
id="text75614"
sodipodi:linespacing="125%"
transform="scale(1.1236771,0.88993537)"><tspan
sodipodi:role="line"
id="tspan75616"
x="520.29974"
y="1997.0011">OFF</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -10,69 +10,117 @@
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="46"
width="65"
height="22"
viewBox="0 0 46 22"
id="svg2857"
version="1.1"
id="svg2751"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
inkscape:version="0.91 r13725"
sodipodi:docname="toggle-on-intl.svg">
<defs
id="defs2745">
id="defs2859">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
<inkscape:perspective
id="perspective2843"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
id="linearGradient3329">
xlink:href="#linearGradient77461"
id="linearGradient77551"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3066667,0,0,1,-841.64667,-483)"
x1="1164.7644"
y1="962.93695"
x2="1164.7644"
y2="970.51404" />
<linearGradient
id="linearGradient77461"
inkscape:collect="always">
<stop
style="stop-color:#39393a;stop-opacity:1;"
id="stop77463"
offset="0"
id="stop3325" />
style="stop-color:#182f4c;stop-opacity:1" />
<stop
style="stop-color:#302f30;stop-opacity:1"
id="stop77465"
offset="1"
id="stop3327" />
style="stop-color:#205b9a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3329"
id="linearGradient3331"
x1="53"
y1="294.42917"
x2="53"
y2="309.80417"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-19)" />
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#535353"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="13.588971"
inkscape:cy="14.124546"
inkscape:cx="37.410841"
inkscape:cy="16.009314"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:current-layer="g37994"
showgrid="false"
units="px"
inkscape:pagecheckerboard="true"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid3298" />
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2748">
id="metadata2862">
<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>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -80,24 +128,65 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.17916)">
<rect
style="opacity:1;vector-effect:none;fill:#15539e;fill-opacity:1;stroke:#030e1b;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"
id="rect3296"
width="44.446434"
height="20.910645"
x="0.625"
y="291.71494"
rx="10.455324"
ry="10.073335" />
<rect
ry="10.455322"
rx="10.455322"
y="291.71494"
x="24.30357"
height="20.910645"
width="21.142862"
id="rect3300"
style="opacity:1;vector-effect:none;fill:url(#linearGradient3331);fill-opacity:1;stroke:#030e1b;stroke-width:1.08532763;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal" />
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient77551);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
transform="translate(2.0625,-2)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
</g>
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect13678"
width="3.0646207"
height="12.414008"
x="554.77728"
y="1767.3566" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

207
data/theme/toggle-on-us.svg Normal file
View File

@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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="65"
height="22"
id="svg2857"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="toggle-on-us.svg">
<defs
id="defs2859">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
<inkscape:perspective
id="perspective2843"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
<linearGradient
id="linearGradient77461-1"
inkscape:collect="always">
<stop
id="stop77463-1"
offset="0"
style="stop-color:#182f4c;stop-opacity:1" />
<stop
id="stop77465-4"
offset="1"
style="stop-color:#205b9a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient77461-1"
id="linearGradient77551-6-5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8527367,0,0,0.80554422,-969.41608,-778.00299)"
x1="1164.7644"
y1="962.93695"
x2="1164.7644"
y2="970.51404" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient77461-1"
id="linearGradient11198"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3066667,0,0,1,-1066.3709,794.25325)"
x1="1322.5831"
y1="-312.51855"
x2="1322.5831"
y2="-306.53461" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-26.798898"
inkscape:cy="5.3753009"
inkscape:document-units="px"
inkscape:current-layer="g37994"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2862">
<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>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient11198);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;clip-rule:nonzero;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;filter-blend-mode:normal;filter-gaussianBlur-deviation:0;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto" />
</g>
<g
transform="translate(2.0625,-2)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
</g>
<text
transform="scale(1.1000946,0.90901274)"
sodipodi:linespacing="125%"
id="text38018"
y="1955.5205"
x="495.94223"
style="font-size:13.29953671px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
xml:space="preserve"><tspan
y="1955.5205"
x="495.94223"
id="tspan38020"
sodipodi:role="line">ON</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -40,7 +40,6 @@ do
done
cat >>$TMP_GRESOURCE_FILE <<EOF
<file>emoji.json</file>
</gresource>
</gresources>
EOF

View File

@@ -1,5 +1,12 @@
const Lang = imports.lang;
const Gettext = imports.gettext;
const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
const Pango = imports.gi.Pango;
const Format = imports.format;
const _ = Gettext.gettext;
@@ -17,8 +24,9 @@ function stripPrefix(string, prefix) {
return string;
}
var Application = class {
constructor() {
var Application = new Lang.Class({
Name: 'Application',
_init() {
GLib.set_prgname('gnome-shell-extension-prefs');
this.application = new Gtk.Application({
application_id: 'org.gnome.shell.ExtensionPrefs',
@@ -34,7 +42,7 @@ var Application = class {
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
}
},
_extensionAvailable(uuid) {
let extension = ExtensionUtils.extensions[uuid];
@@ -46,7 +54,7 @@ var Application = class {
return false;
return true;
}
},
_getExtensionPrefsModule(extension) {
let uuid = extension.metadata.uuid;
@@ -61,7 +69,7 @@ var Application = class {
this._extensionPrefsModules[uuid] = prefsModule;
return prefsModule;
}
},
_selectExtension(uuid) {
if (!this._extensionAvailable(uuid))
@@ -96,115 +104,33 @@ var Application = class {
dialog.set_default_size(600, 400);
dialog.add(widget);
dialog.show();
}
},
_buildErrorUI(extension, exc) {
let scroll = new Gtk.ScrolledWindow({
hscrollbar_policy: Gtk.PolicyType.NEVER,
propagate_natural_height: true
});
let box = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL,
spacing: 12,
margin: 100,
margin_bottom: 60
});
scroll.add(box);
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
let label = new Gtk.Label({
label: '<span size="x-large">%s</span>'.format(_("Somethings gone wrong")),
use_markup: true
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
box.add(label);
label = new Gtk.Label({
label: _("Were very sorry, but theres been a problem: the settings for this extension cant be displayed. We recommend that you report the issue to the extension authors."),
justify: Gtk.Justification.CENTER,
wrap: true
label: _("There was an error loading the preferences dialog for %s:").format(extension.metadata.name)
});
box.add(label);
let expander = new Expander({
label: _("Technical Details"),
margin_top: 12
});
box.add(expander);
let errortext = '';
errortext += exc;
errortext += '\n\n';
errortext += 'Stack trace:\n';
let errortext = `${exc}\n\nStack trace:\n${
// Indent stack trace.
exc.stack.split('\n').map(line => ` ${line}`).join('\n')
}`;
// Indent stack trace.
errortext += exc.stack.split('\n').map(line => ' ' + line).join('\n');
let scroll = new Gtk.ScrolledWindow({ vexpand: true });
let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({
buffer: buffer,
wrap_mode: Gtk.WrapMode.WORD,
monospace: true,
editable: false,
top_margin: 12,
bottom_margin: 12,
left_margin: 12,
right_margin: 12
});
let textview = new Gtk.TextView({ buffer: buffer });
textview.override_font(Pango.font_description_from_string('monospace'));
scroll.add(textview);
box.add(scroll);
let toolbar = new Gtk.Toolbar();
let provider = new Gtk.CssProvider();
provider.load_from_data(`* {
border: 0 solid @borders;
border-top-width: 1px;
}`);
toolbar.get_style_context().add_provider(
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
let copyButton = new Gtk.ToolButton({
icon_name: 'edit-copy-symbolic',
tooltip_text: _("Copy Error")
});
toolbar.add(copyButton);
copyButton.connect('clicked', w => {
let clipboard = Gtk.Clipboard.get_default(w.get_display());
let backticks = '```';
clipboard.set_text(
// markdown for pasting in gitlab issues
`The settings of extension ${extension.uuid} had an error:\n${
backticks}\n${exc}\n${backticks}\n\nStack trace:\n${
backticks}\n${exc.stack}${backticks}\n`, -1
);
});
let spacing = new Gtk.SeparatorToolItem({ draw: false });
toolbar.add(spacing);
toolbar.child_set_property(spacing, "expand", true);
let urlButton = new Gtk.ToolButton({
label: _("Homepage"),
tooltip_text: _("Visit extension homepage"),
no_show_all: true,
visible: extension.metadata.url != null
});
toolbar.add(urlButton);
urlButton.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
Gio.AppInfo.launch_default_for_uri(extension.metadata.url, context);
});
let expandedBox = new Gtk.Box({
orientation: Gtk.Orientation.VERTICAL
});
expandedBox.add(textview);
expandedBox.add(toolbar);
expander.add(expandedBox);
scroll.show_all();
return scroll;
}
box.show_all();
return box;
},
_buildUI(app) {
this._window = new Gtk.ApplicationWindow({ application: app,
@@ -224,12 +150,8 @@ var Application = class {
Gio.SettingsBindFlags.DEFAULT |
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._mainStack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE
});
this._window.add(this._mainStack);
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
this._window.add(scroll);
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
this._extensionSelector.set_sort_func(this._sortList.bind(this));
@@ -237,8 +159,6 @@ var Application = class {
scroll.add(this._extensionSelector);
this._mainStack.add_named(scroll, 'listing');
this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder');
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => {
@@ -247,13 +167,13 @@ var Application = class {
});
this._window.show_all();
}
},
_sortList(row1, row2) {
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
return name1.localeCompare(name2);
}
},
_updateHeader(row, before) {
if (!before || row.get_header())
@@ -261,14 +181,14 @@ var Application = class {
let sep = new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL });
row.set_header(sep);
}
},
_scanExtensions() {
let finder = new ExtensionUtils.ExtensionFinder();
finder.connect('extension-found', this._extensionFound.bind(this));
finder.scanExtensions();
this._extensionsLoaded();
}
},
_extensionFound(finder, extension) {
let row = new ExtensionRow(extension.uuid);
@@ -280,29 +200,24 @@ var Application = class {
row.show_all();
this._extensionSelector.add(row);
}
},
_extensionsLoaded() {
if (this._extensionSelector.get_children().length > 0)
this._mainStack.visible_child_name = 'listing';
else
this._mainStack.visible_child_name = 'placeholder';
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
this._selectExtension(this._startupUuid);
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
}
},
_onActivate() {
this._window.present();
}
},
_onStartup(app) {
this._buildUI(app);
this._scanExtensions();
}
},
_onCommandLine(app, commandLine) {
app.activate();
@@ -325,187 +240,26 @@ var Application = class {
}
return 0;
}
};
var Expander = GObject.registerClass({
Properties: {
'label': GObject.ParamSpec.string(
'label', 'label', 'label',
GObject.ParamFlags.READWRITE,
null
)
}
}, class Expander extends Gtk.Box {
_init(params = {}) {
this._labelText = null;
super._init(Object.assign(params, {
orientation: Gtk.Orientation.VERTICAL,
spacing: 0
}));
this._frame = new Gtk.Frame({
shadow_type: Gtk.ShadowType.IN,
hexpand: true
});
let eventBox = new Gtk.EventBox();
this._frame.add(eventBox);
let hbox = new Gtk.Box({
spacing: 6,
margin: 12
});
eventBox.add(hbox);
this._arrow = new Gtk.Image({
icon_name: 'pan-end-symbolic'
});
hbox.add(this._arrow);
this._label = new Gtk.Label({ label: this._labelText });
hbox.add(this._label);
this._revealer = new Gtk.Revealer();
this._childBin = new Gtk.Frame({
shadow_type: Gtk.ShadowType.IN
});
this._revealer.add(this._childBin);
// Directly chain up to parent for internal children
super.add(this._frame);
super.add(this._revealer);
let provider = new Gtk.CssProvider();
provider.load_from_data('* { border-top-width: 0; }');
this._childBin.get_style_context().add_provider(
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
this._gesture = new Gtk.GestureMultiPress({
widget: this._frame,
button: 0,
exclusive: true
});
this._gesture.connect('released', (gesture, nPress) => {
if (nPress == 1)
this._revealer.reveal_child = !this._revealer.reveal_child;
});
this._revealer.connect('notify::reveal-child', () => {
if (this._revealer.reveal_child)
this._arrow.icon_name = 'pan-down-symbolic';
else
this._arrow.icon_name = 'pan-end-symbolic';
});
}
get label() {
return this._labelText;
}
set label(text) {
if (this._labelText == text)
return;
if (this._label)
this._label.label = text;
this._labelText = text;
this.notify('label');
}
add(child) {
// set expanded child
this._childBin.get_children().forEach(c => {
this._childBin.remove(c);
});
if (child)
this._childBin.add(child);
}
});
var EmptyPlaceholder = GObject.registerClass(
class EmptyPlaceholder extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 6,
margin: 32
});
var DescriptionLabel = new Lang.Class({
Name: 'DescriptionLabel',
Extends: Gtk.Label,
let image = new Gtk.Image({
icon_name: 'application-x-addon-symbolic',
pixel_size: 96,
visible: true,
vexpand: true,
valign: Gtk.Align.END
});
image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(image);
let label = new Gtk.Label({
label: `<b><span size="x-large">${_("No Extensions Installed" )}</span></b>`,
use_markup: true,
visible: true
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop');
let desc = new Gtk.Label({
label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."),
use_markup: true,
wrap: true,
justify: Gtk.Justification.CENTER,
visible: true,
max_width_chars: 50,
hexpand: true,
vexpand: (appInfo == null),
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START
});
this.add(desc);
if (appInfo) {
let button = new Gtk.Button({
label: _("Browse in Software"),
image: new Gtk.Image({
icon_name: "org.gnome.Software-symbolic"
}),
always_show_image: true,
margin_top: 12,
visible: true,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
vexpand: true
});
this.add(button);
button.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
appInfo.launch([], context);
});
}
}
});
var DescriptionLabel = GObject.registerClass(
class DescriptionLabel extends Gtk.Label {
vfunc_get_preferred_height_for_width(width) {
// Hack: Request the maximum height allowed by the line limit
if (this.lines > 0)
return super.vfunc_get_preferred_height_for_width(0);
return super.vfunc_get_preferred_height_for_width(width);
return this.parent(0);
return this.parent(width);
}
});
var ExtensionRow = GObject.registerClass(
class ExtensionRow extends Gtk.ListBoxRow {
var ExtensionRow = new Lang.Class({
Name: 'ExtensionRow',
Extends: Gtk.ListBoxRow,
_init(uuid) {
super._init();
this.parent();
this.uuid = uuid;
@@ -523,7 +277,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
});
this._buildUI();
}
},
_buildUI() {
let extension = ExtensionUtils.extensions[this.uuid];
@@ -551,9 +305,9 @@ class ExtensionRow extends Gtk.ListBoxRow {
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
no_show_all: true });
button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.add(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.get_style_context().add_class('circular');
hbox.add(button);
@@ -570,7 +324,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
});
this._switch.connect('state-set', () => true);
hbox.add(this._switch);
}
},
_canEnable() {
let extension = ExtensionUtils.extensions[this.uuid];
@@ -578,12 +332,12 @@ class ExtensionRow extends Gtk.ListBoxRow {
return !this._settings.get_boolean('disable-user-extensions') &&
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
}
},
_isEnabled() {
let extensions = this._settings.get_strv('enabled-extensions');
return extensions.indexOf(this.uuid) != -1;
}
},
_enable() {
let extensions = this._settings.get_strv('enabled-extensions');
@@ -592,7 +346,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
extensions.push(this.uuid);
this._settings.set_strv('enabled-extensions', extensions);
}
},
_disable() {
let extensions = this._settings.get_strv('enabled-extensions');

View File

@@ -1,7 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Pango, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Signals = imports.signals;
const St = imports.gi.St;
const Animation = imports.ui.animation;
const Batch = imports.gdm.batch;
@@ -34,8 +38,10 @@ var BeginRequestType = {
DONT_PROVIDE_USERNAME: 1
};
var AuthPrompt = class {
constructor(gdmClient, mode) {
var AuthPrompt = new Lang.Class({
Name: 'AuthPrompt',
_init(gdmClient, mode) {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient;
@@ -93,7 +99,7 @@ var AuthPrompt = class {
x_align: St.Align.START });
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
ShellEntry.addContextMenu(this._entry, { isPassword: true });
this.actor.add(this._entry,
{ expand: true,
@@ -121,16 +127,17 @@ var AuthPrompt = class {
this._initButtons();
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
this._defaultButtonWell.add_child(this._spinner.actor);
}
},
_onDestroy() {
this._userVerifier.destroy();
this._userVerifier = null;
}
},
_initButtons() {
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
@@ -178,7 +185,7 @@ var AuthPrompt = class {
if (this.nextButton.reactive)
this.emit('next');
});
}
},
_onAskQuestion(verifier, serviceName, question, passwordChar) {
if (this._queryingService)
@@ -204,12 +211,12 @@ var AuthPrompt = class {
this.updateSensitivity(true);
this.emit('prompted');
}
},
_onOVirtUserAuthenticated() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
}
},
_onSmartcardStatusChanged() {
this.smartcardDetected = this._userVerifier.smartcardDetected;
@@ -228,12 +235,12 @@ var AuthPrompt = class {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
}
},
_onShowMessage(userVerifier, message, type) {
this.setMessage(message, type);
this.emit('prompted');
}
},
_onVerificationFailed(userVerifier, canRetry) {
this._queryingService = null;
@@ -242,22 +249,22 @@ var AuthPrompt = class {
this.updateSensitivity(canRetry);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
}
},
_onVerificationComplete() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
}
},
_onReset() {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.reset();
}
},
addActorToDefaultButtonWell(actor) {
this._defaultButtonWell.add_child(actor);
}
},
setActorInDefaultButtonWell(actor, animate) {
if (!this._defaultButtonWellActor &&
@@ -321,25 +328,25 @@ var AuthPrompt = class {
}
this._defaultButtonWellActor = actor;
}
},
startSpinning() {
this.setActorInDefaultButtonWell(this._spinner.actor, true);
}
},
stopSpinning() {
this.setActorInDefaultButtonWell(null, false);
}
},
clear() {
this._entry.text = '';
this.stopSpinning();
}
},
setPasswordChar(passwordChar) {
this._entry.clutter_text.set_password_char(passwordChar);
this._entry.menu.isPassword = passwordChar != '';
}
},
setQuestion(question) {
this._label.set_text(question);
@@ -348,7 +355,7 @@ var AuthPrompt = class {
this._entry.show();
this._entry.grab_key_focus();
}
},
getAnswer() {
let text;
@@ -361,7 +368,7 @@ var AuthPrompt = class {
}
return text;
}
},
_fadeOutMessage() {
if (this._message.opacity == 0)
@@ -372,7 +379,7 @@ var AuthPrompt = class {
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
},
setMessage(message, type) {
if (type == GdmUtil.MessageType.ERROR)
@@ -392,18 +399,18 @@ var AuthPrompt = class {
} else {
this._message.opacity = 0;
}
}
},
_updateNextButtonSensitivity(sensitive) {
this.nextButton.reactive = sensitive;
this.nextButton.can_focus = sensitive;
}
},
updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
}
},
hide() {
this.setActorInDefaultButtonWell(null, true);
@@ -414,7 +421,7 @@ var AuthPrompt = class {
this.updateSensitivity(true);
this._entry.set_text('');
}
},
setUser(user) {
let oldChild = this._userWell.get_child();
@@ -425,7 +432,7 @@ var AuthPrompt = class {
let userWidget = new UserWidget.UserWidget(user);
this._userWell.set_child(userWidget.actor);
}
}
},
reset() {
let oldStatus = this.verificationStatus;
@@ -463,7 +470,7 @@ var AuthPrompt = class {
}
this.emit('reset', beginRequestType);
}
},
addCharacter(unichar) {
if (!this._entry.visible)
@@ -471,7 +478,7 @@ var AuthPrompt = class {
this._entry.grab_key_focus();
this._entry.clutter_text.insert_unichar(unichar);
}
},
begin(params) {
params = Params.parse(params, { userName: null,
@@ -485,7 +492,7 @@ var AuthPrompt = class {
this._userVerifier.begin(params.userName, hold);
this.verificationStatus = AuthPromptStatus.VERIFYING;
}
},
finish(onComplete) {
if (!this._userVerifier.hasPendingMessages) {
@@ -499,7 +506,7 @@ var AuthPrompt = class {
this._userVerifier.clear();
onComplete();
});
}
},
cancel() {
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
@@ -508,5 +515,5 @@ var AuthPrompt = class {
this.reset();
this.emit('cancelled');
}
};
});
Signals.addSignalMethods(AuthPrompt.prototype);

View File

@@ -44,39 +44,45 @@
* replaced by something else.
*/
const Lang = imports.lang;
const Signals = imports.signals;
var Task = class {
constructor(scope, handler) {
var Task = new Lang.Class({
Name: 'Task',
_init(scope, handler) {
if (scope)
this.scope = scope;
else
this.scope = this;
this.handler = handler;
}
},
run() {
if (this.handler)
return this.handler.call(this.scope);
return null;
}
};
},
});
Signals.addSignalMethods(Task.prototype);
var Hold = class extends Task {
constructor() {
super(null, () => this);
var Hold = new Lang.Class({
Name: 'Hold',
Extends: Task,
_init() {
this.parent(this, () => this);
this._acquisitions = 1;
}
},
acquire() {
if (this._acquisitions <= 0)
throw new Error("Cannot acquire hold after it's been released");
this._acquisitions++;
}
},
acquireUntilAfter(hold) {
if (!hold.isAcquired())
@@ -87,24 +93,27 @@ var Hold = class extends Task {
hold.disconnect(signalId);
this.release();
});
}
},
release() {
this._acquisitions--;
if (this._acquisitions == 0)
this.emit('release');
}
},
isAcquired() {
return this._acquisitions > 0;
}
};
});
Signals.addSignalMethods(Hold.prototype);
var Batch = class extends Task {
constructor(scope, tasks) {
super();
var Batch = new Lang.Class({
Name: 'Batch',
Extends: Task,
_init(scope, tasks) {
this.parent();
this.tasks = [];
@@ -121,11 +130,11 @@ var Batch = class extends Task {
this.tasks.push(task);
}
}
},
process() {
throw new Error('Not implemented');
}
},
runTask() {
if (!(this._currentTaskIndex in this.tasks)) {
@@ -133,11 +142,11 @@ var Batch = class extends Task {
}
return this.tasks[this._currentTaskIndex].run();
}
},
_finish() {
this.hold.release();
}
},
nextTask() {
this._currentTaskIndex++;
@@ -150,7 +159,7 @@ var Batch = class extends Task {
}
this.process();
}
},
_start() {
// acquire a hold to get released when the entire
@@ -158,7 +167,7 @@ var Batch = class extends Task {
this.hold = new Hold();
this._currentTaskIndex = 0;
this.process();
}
},
run() {
this._start();
@@ -166,15 +175,18 @@ var Batch = class extends Task {
// hold may be destroyed at this point
// if we're already done running
return this.hold;
}
},
cancel() {
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
}
};
});
Signals.addSignalMethods(Batch.prototype);
var ConcurrentBatch = class extends Batch {
var ConcurrentBatch = new Lang.Class({
Name: 'ConcurrentBatch',
Extends: Batch,
process() {
let hold = this.runTask();
@@ -187,10 +199,13 @@ var ConcurrentBatch = class extends Batch {
// concurrently.
this.nextTask();
}
};
});
Signals.addSignalMethods(ConcurrentBatch.prototype);
var ConsecutiveBatch = class extends Batch {
var ConsecutiveBatch = new Lang.Class({
Name: 'ConsecutiveBatch',
Extends: Batch,
process() {
let hold = this.runTask();
@@ -207,5 +222,5 @@ var ConsecutiveBatch = class extends Batch {
this.nextTask();
}
}
};
});
Signals.addSignalMethods(ConsecutiveBatch.prototype);

View File

@@ -1,6 +1,9 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const FprintManagerIface = `
<node>

View File

@@ -16,9 +16,20 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
const { AccountsService, Atk, Clutter, Gdm, Gio,
GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
const AccountsService = imports.gi.AccountsService;
const Atk = imports.gi.Atk;
const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const AuthPrompt = imports.gdm.authPrompt;
const Batch = imports.gdm.batch;
@@ -39,8 +50,10 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = class {
constructor(user) {
var UserListItem = new Lang.Class({
Name: 'UserListItem',
_init(user) {
this.user = user;
this._userChangedId = this.user.connect('changed',
this._onUserChanged.bind(this));
@@ -78,26 +91,26 @@ var UserListItem = class {
this.actor.connect('clicked', this._onClicked.bind(this));
this._onUserChanged();
}
},
_onUserChanged() {
this._updateLoggedIn();
}
},
_updateLoggedIn() {
if (this.user.is_logged_in())
this.actor.add_style_pseudo_class('logged-in');
else
this.actor.remove_style_pseudo_class('logged-in');
}
},
_onDestroy() {
this.user.disconnect(this._userChangedId);
}
},
_onClicked() {
this.emit('activate');
}
},
_setSelected(selected) {
if (selected) {
@@ -106,7 +119,7 @@ var UserListItem = class {
} else {
this.actor.remove_style_pseudo_class('selected');
}
}
},
showTimedLoginIndicator(time) {
let hold = new Batch.Hold();
@@ -134,7 +147,7 @@ var UserListItem = class {
GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
return hold;
}
},
hideTimedLoginIndicator() {
if (this._timedLoginTimeoutId) {
@@ -145,14 +158,16 @@ var UserListItem = class {
this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.;
}
};
});
Signals.addSignalMethods(UserListItem.prototype);
var UserList = class {
constructor() {
var UserList = new Lang.Class({
Name: 'UserList',
_init() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
this.actor.set_policy(St.PolicyType.NEVER,
St.PolicyType.AUTOMATIC);
this.actor.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
this._box = new St.BoxLayout({ vertical: true,
style_class: 'login-dialog-user-list',
@@ -162,7 +177,7 @@ var UserList = class {
this._items = {};
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
}
},
_moveFocusToItems() {
let hasItems = Object.keys(this._items).length > 0;
@@ -173,18 +188,18 @@ var UserList = class {
if (global.stage.get_key_focus() != this.actor)
return;
let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
if (!focusSet) {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._moveFocusToItems();
return false;
});
}
}
},
_onItemActivated(activatedItem) {
this.emit('activate', activatedItem);
}
},
updateStyle(isExpanded) {
let tasks = [];
@@ -198,7 +213,7 @@ var UserList = class {
let item = this._items[userName];
item.actor.sync_hover();
}
}
},
scrollToItem(item) {
let box = item.actor.get_allocation_box();
@@ -211,7 +226,7 @@ var UserList = class {
{ value: value,
time: _SCROLL_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
jumpToItem(item) {
let box = item.actor.get_allocation_box();
@@ -221,7 +236,7 @@ var UserList = class {
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
adjustment.set_value(value);
}
},
getItemFromUserName(userName) {
let item = this._items[userName];
@@ -230,11 +245,11 @@ var UserList = class {
return null;
return item;
}
},
containsUser(user) {
return this._items[user.get_user_name()] != null;
}
},
addUser(user) {
if (!user.is_loaded)
@@ -266,7 +281,7 @@ var UserList = class {
this._moveFocusToItems();
this.emit('item-added', item);
}
},
removeUser(user) {
if (!user.is_loaded)
@@ -284,16 +299,18 @@ var UserList = class {
item.actor.destroy();
delete this._items[userName];
}
},
numItems() {
return Object.keys(this._items).length;
}
};
});
Signals.addSignalMethods(UserList.prototype);
var SessionMenuButton = class {
constructor() {
var SessionMenuButton = new Lang.Class({
Name: 'SessionMenuButton',
_init() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
reactive: true,
@@ -325,8 +342,7 @@ var SessionMenuButton = class {
this._button.remove_style_pseudo_class('active');
});
this._manager = new PopupMenu.PopupMenuManager(this._button,
{ actionMode: Shell.ActionMode.NONE });
this._manager = new PopupMenu.PopupMenuManager({ actor: this._button });
this._manager.addMenu(this._menu);
this._button.connect('clicked', () => { this._menu.toggle(); });
@@ -334,13 +350,13 @@ var SessionMenuButton = class {
this._items = {};
this._activeSessionId = null;
this._populate();
}
},
updateSensitivity(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
this._menu.close(BoxPointer.PopupAnimation.NONE);
}
},
_updateOrnament() {
let itemIds = Object.keys(this._items);
@@ -350,7 +366,7 @@ var SessionMenuButton = class {
else
this._items[itemIds[i]].setOrnament(PopupMenu.Ornament.NONE);
}
}
},
setActiveSession(sessionId) {
if (sessionId == this._activeSessionId)
@@ -358,11 +374,11 @@ var SessionMenuButton = class {
this._activeSessionId = sessionId;
this._updateOrnament();
}
},
close() {
this._menu.close();
}
},
_populate() {
let ids = Gdm.get_session_ids();
@@ -387,14 +403,16 @@ var SessionMenuButton = class {
});
}
}
};
});
Signals.addSignalMethods(SessionMenuButton.prototype);
var LoginDialog = GObject.registerClass({
var LoginDialog = new Lang.Class({
Name: 'LoginDialog',
Extends: St.Widget,
Signals: { 'failed': {} },
}, class LoginDialog extends St.Widget {
_init(parentActor) {
super._init({ style_class: 'login-dialog',
this.parent({ style_class: 'login-dialog',
visible: false });
this.get_accessible().set_role(Atk.Role.WINDOW);
@@ -464,8 +482,8 @@ var LoginDialog = GObject.registerClass({
this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
opacity: 0,
vscrollbar_policy: St.PolicyType.AUTOMATIC,
hscrollbar_policy: St.PolicyType.NEVER });
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER });
this.add_child(this._bannerView);
let bannerBox = new St.BoxLayout({ vertical: true });
@@ -481,9 +499,6 @@ var LoginDialog = GObject.registerClass({
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END });
this._logoBin.connect('resource-scale-changed', () => {
this._updateLogoTexture(this._textureCache, this._logoFile);
});
this.add_child(this._logoBin);
this._updateLogo();
@@ -515,7 +530,7 @@ var LoginDialog = GObject.registerClass({
// focus later
this._startupCompleteId = Main.layoutManager.connect('startup-complete',
this._updateDisableUserList.bind(this));
}
},
_getBannerAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
@@ -529,7 +544,7 @@ var LoginDialog = GObject.registerClass({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
},
_getLogoBinAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
@@ -543,7 +558,7 @@ var LoginDialog = GObject.registerClass({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
},
_getCenterActorAllocation(dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
@@ -561,7 +576,7 @@ var LoginDialog = GObject.registerClass({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
},
vfunc_allocate(dialogBox, flags) {
this.set_allocation(dialogBox, flags);
@@ -704,7 +719,7 @@ var LoginDialog = GObject.registerClass({
if (logoAllocation)
this._logoBin.allocate(logoAllocation, flags);
}
},
_ensureUserListLoaded() {
if (!this._userManager.is_loaded) {
@@ -720,7 +735,7 @@ var LoginDialog = GObject.registerClass({
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, this._loadUserList.bind(this));
GLib.Source.set_name_by_id(id, '[gnome-shell] _loadUserList');
}
}
},
_updateDisableUserList() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
@@ -735,7 +750,7 @@ var LoginDialog = GObject.registerClass({
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
}
}
},
_updateCancelButton() {
let cancelVisible;
@@ -748,7 +763,7 @@ var LoginDialog = GObject.registerClass({
cancelVisible = true;
this._authPrompt.cancelButton.visible = cancelVisible;
}
},
_updateBanner() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
@@ -760,7 +775,7 @@ var LoginDialog = GObject.registerClass({
} else {
this._bannerLabel.hide();
}
}
},
_fadeInBannerView() {
this._bannerView.show();
@@ -768,34 +783,33 @@ var LoginDialog = GObject.registerClass({
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
_hideBannerView() {
Tweener.removeTweens(this._bannerView);
this._bannerView.opacity = 0;
this._bannerView.hide();
}
},
_updateLogoTexture(cache, file) {
if (this._logoFile && !this._logoFile.equal(file))
return;
this._logoBin.destroy_all_children();
if (this._logoFile && this._logoBin.resource_scale > 0) {
if (this._logoFile) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
-1, _LOGO_ICON_HEIGHT,
scaleFactor,
this._logoBin.resource_scale));
scaleFactor));
}
}
},
_updateLogo() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFile = path ? Gio.file_new_for_path(path) : null;
this._updateLogoTexture(this._textureCache, this._logoFile);
}
},
_onPrompted() {
if (this._shouldShowSessionMenuButton()) {
@@ -805,7 +819,7 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton.updateSensitivity(false);
}
this._showPrompt();
}
},
_resetGreeterProxy() {
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
@@ -821,7 +835,7 @@ var LoginDialog = GObject.registerClass({
this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
this._onTimedLoginRequested.bind(this));
}
}
},
_onReset(authPrompt, beginRequest) {
this._resetGreeterProxy();
@@ -842,11 +856,11 @@ var LoginDialog = GObject.registerClass({
} else {
this._hideUserListAndBeginVerification();
}
}
},
_onDefaultSessionChanged(client, sessionId) {
this._sessionMenuButton.setActiveSession(sessionId);
}
},
_shouldShowSessionMenuButton() {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
@@ -857,7 +871,7 @@ var LoginDialog = GObject.registerClass({
return false;
return true;
}
},
_showPrompt() {
if (this._authPrompt.actor.visible)
@@ -869,7 +883,7 @@ var LoginDialog = GObject.registerClass({
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
this._fadeInBannerView();
}
},
_showRealmLoginHint(realmManager, hint) {
if (!hint)
@@ -882,7 +896,7 @@ var LoginDialog = GObject.registerClass({
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
}
},
_askForUsernameAndBeginVerification() {
this._authPrompt.setPasswordChar('');
@@ -909,7 +923,7 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton.updateSensitivity(false);
this._authPrompt.updateSensitivity(true);
this._showPrompt();
}
},
_loginScreenSessionActivated() {
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
@@ -933,7 +947,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.reset();
},
onCompleteScope: this });
}
},
_gotGreeterSessionProxy(proxy) {
this._greeterSessionProxy = proxy;
@@ -942,7 +956,7 @@ var LoginDialog = GObject.registerClass({
if (proxy.Active)
this._loginScreenSessionActivated();
});
}
},
_startSession(serviceName) {
Tweener.addTween(this,
@@ -962,11 +976,11 @@ var LoginDialog = GObject.registerClass({
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
},
onCompleteScope: this });
}
},
_onSessionOpened(client, serviceName) {
this._authPrompt.finish(() => { this._startSession(serviceName); });
}
},
_waitForItemForUser(userName) {
let item = this._userList.getItemFromUserName(userName);
@@ -986,7 +1000,7 @@ var LoginDialog = GObject.registerClass({
hold.connect('release', () => { this._userList.disconnect(signalId); });
return hold;
}
},
_blockTimedLoginUntilIdle() {
let hold = new Batch.Hold();
@@ -999,7 +1013,7 @@ var LoginDialog = GObject.registerClass({
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginIdleTimeOutId');
return hold;
}
},
_startTimedLogin(userName, delay) {
let firstRun = true;
@@ -1072,7 +1086,7 @@ var LoginDialog = GObject.registerClass({
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
return this._timedLoginBatch.run();
}
},
_onTimedLoginRequested(client, userName, seconds) {
if (this._timedLoginBatch)
@@ -1089,28 +1103,28 @@ var LoginDialog = GObject.registerClass({
return Clutter.EVENT_PROPAGATE;
});
}
},
_setUserListExpanded(expanded) {
this._userList.updateStyle(expanded);
this._userSelectionBox.visible = expanded;
}
},
_hideUserList() {
this._setUserListExpanded(false);
if (this._userSelectionBox.visible)
GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
}
},
_hideUserListAskForUsernameAndBeginVerification() {
this._hideUserList();
this._askForUsernameAndBeginVerification();
}
},
_hideUserListAndBeginVerification() {
this._hideUserList();
this._authPrompt.begin();
}
},
_showUserList() {
this._ensureUserListLoaded();
@@ -1120,7 +1134,7 @@ var LoginDialog = GObject.registerClass({
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.actor.grab_key_focus();
}
},
_beginVerificationForItem(item) {
this._authPrompt.setUser(item.user);
@@ -1131,7 +1145,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.begin({ userName: userName,
hold: hold });
return hold;
}
},
_onUserListActivated(activatedItem) {
this._user = activatedItem.user;
@@ -1141,7 +1155,7 @@ var LoginDialog = GObject.registerClass({
let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox),
this._beginVerificationForItem(activatedItem)]);
batch.run();
}
},
_onDestroy() {
if (this._userManagerLoadedId) {
@@ -1182,7 +1196,7 @@ var LoginDialog = GObject.registerClass({
this._realmManager.release();
this._realmManager = null;
}
}
},
_loadUserList() {
if (this._userListLoaded)
@@ -1220,7 +1234,7 @@ var LoginDialog = GObject.registerClass({
});
return GLib.SOURCE_REMOVE;
}
},
open() {
Main.ctrlAltTabManager.addGroup(this,
@@ -1239,22 +1253,22 @@ var LoginDialog = GObject.registerClass({
transition: 'easeInQuad' });
return true;
}
},
close() {
Main.popModal(this);
Main.ctrlAltTabManager.removeGroup(this);
}
},
cancel() {
this._authPrompt.cancel();
}
},
addCharacter(unichar) {
// Don't allow type ahead at the login screen
}
},
finish(onComplete) {
this._authPrompt.finish(onComplete);
}
},
});

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const OVirtCredentialsIface = `
@@ -27,32 +28,33 @@ function OVirtCredentials() {
return self;
}
var OVirtCredentialsManager = class {
constructor() {
var OVirtCredentialsManager = new Lang.Class({
Name: 'OVirtCredentialsManager',
_init() {
this._token = null;
this._credentials = new OVirtCredentials();
this._credentials.connectSignal('UserAuthenticated',
this._onUserAuthenticated.bind(this));
}
},
_onUserAuthenticated(proxy, sender, [token]) {
this._token = token;
this.emit('user-authenticated', token);
}
},
hasToken() {
return this._token != null;
}
},
getToken() {
return this._token;
}
},
resetToken() {
this._token = null;
}
};
});
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
function getOVirtCredentialsManager() {

View File

@@ -1,6 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;
@@ -14,8 +16,10 @@ const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
const RealmIface = loadInterfaceXML("org.freedesktop.realmd.Realm");
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
var Manager = class {
constructor(parentActor) {
var Manager = new Lang.Class({
Name: 'Manager',
_init(parentActor) {
this._aggregateProvider = Provider(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
@@ -27,7 +31,7 @@ var Manager = class {
if ('Realms' in properties.deep_unpack())
this._reloadRealms();
});
}
},
_reloadRealms() {
let realmPaths = this._aggregateProvider.Realms;
@@ -41,7 +45,7 @@ var Manager = class {
realmPaths[i],
this._onRealmLoaded.bind(this));
}
}
},
_reloadRealm(realm) {
if (!realm.Configured) {
@@ -54,7 +58,7 @@ var Manager = class {
this._realms[realm.get_object_path()] = realm;
this._updateLoginFormat();
}
},
_onRealmLoaded(realm, error) {
if (error)
@@ -66,7 +70,7 @@ var Manager = class {
if ('Configured' in properties.deep_unpack())
this._reloadRealm(realm);
});
}
},
_updateLoginFormat() {
let newLoginFormat;
@@ -83,7 +87,7 @@ var Manager = class {
this._loginFormat = newLoginFormat;
this.emit('login-format-changed', newLoginFormat);
}
}
},
get loginFormat() {
if (this._loginFormat !== undefined)
@@ -92,7 +96,7 @@ var Manager = class {
this._updateLoginFormat();
return this._loginFormat;
}
},
release() {
Service(Gio.DBus.system,
@@ -103,5 +107,5 @@ var Manager = class {
this._realms = { };
this._updateLoginFormat();
}
};
});
Signals.addSignalMethods(Manager.prototype)

View File

@@ -1,13 +1,19 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const OVirt = imports.gdm.oVirt;
const Main = imports.ui.main;
const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry;
const SmartcardManager = imports.misc.smartcardManager;
const Tweener = imports.ui.tweener;
@@ -113,8 +119,10 @@ function cloneAndFadeOutActor(actor) {
return hold;
}
var ShellUserVerifier = class {
constructor(client, params) {
var ShellUserVerifier = new Lang.Class({
Name: 'ShellUserVerifier',
_init(client, params) {
params = Params.parse(params, { reauthenticationOnly: false });
this._reauthOnly = params.reauthenticationOnly;
@@ -157,7 +165,7 @@ var ShellUserVerifier = class {
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
this._oVirtUserAuthenticated.bind(this));
}
},
begin(userName, hold) {
this._cancellable = new Gio.Cancellable();
@@ -175,7 +183,7 @@ var ShellUserVerifier = class {
} else {
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
}
}
},
cancel() {
if (this._cancellable)
@@ -185,14 +193,14 @@ var ShellUserVerifier = class {
this._userVerifier.call_cancel_sync(null);
this.clear();
}
}
},
_clearUserVerifier() {
if (this._userVerifier) {
this._userVerifier.run_dispose();
this._userVerifier = null;
}
}
},
clear() {
if (this._cancellable) {
@@ -202,7 +210,7 @@ var ShellUserVerifier = class {
this._clearUserVerifier();
this._clearMessageQueue();
}
},
destroy() {
this.clear();
@@ -216,7 +224,7 @@ var ShellUserVerifier = class {
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
this._oVirtCredentialsManager = null;
}
},
answerQuery(serviceName, answer) {
if (!this.hasPendingMessages) {
@@ -227,12 +235,12 @@ var ShellUserVerifier = class {
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
});
}
}
},
_getIntervalForMessage(message) {
// We probably could be smarter here
return message.length * USER_READ_TIME;
}
},
finishMessageQueue() {
if (!this.hasPendingMessages)
@@ -242,7 +250,7 @@ var ShellUserVerifier = class {
this.hasPendingMessages = false;
this.emit('no-more-messages');
}
},
_queueMessageTimeout() {
if (this._messageQueue.length == 0) {
@@ -265,7 +273,7 @@ var ShellUserVerifier = class {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
}
},
_queueMessage(message, messageType) {
let interval = this._getIntervalForMessage(message);
@@ -273,7 +281,7 @@ var ShellUserVerifier = class {
this.hasPendingMessages = true;
this._messageQueue.push({ text: message, type: messageType, interval: interval });
this._queueMessageTimeout();
}
},
_clearMessageQueue() {
this.finishMessageQueue();
@@ -283,7 +291,7 @@ var ShellUserVerifier = class {
this._messageQueueTimeoutId = 0;
}
this.emit('show-message', null, MessageType.NONE);
}
},
_checkForFingerprintReader() {
this._haveFingerprintReader = false;
@@ -301,12 +309,12 @@ var ShellUserVerifier = class {
this._updateDefaultService();
}
});
}
},
_oVirtUserAuthenticated(token) {
this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('ovirt-user-authenticated');
}
},
_checkForSmartcard() {
let smartcardDetected;
@@ -328,7 +336,7 @@ var ShellUserVerifier = class {
this.emit('smartcard-status-changed');
}
}
},
_reportInitError(where, error) {
logError(error, where);
@@ -336,7 +344,7 @@ var ShellUserVerifier = class {
this._queueMessage(_("Authentication error"), MessageType.ERROR);
this._verificationFailed(false);
}
},
_reauthenticationChannelOpened(client, result) {
try {
@@ -363,7 +371,7 @@ var ShellUserVerifier = class {
this._connectSignals();
this._beginVerification();
this._hold.release();
}
},
_userVerifierGot(client, result) {
try {
@@ -379,7 +387,7 @@ var ShellUserVerifier = class {
this._connectSignals();
this._beginVerification();
this._hold.release();
}
},
_connectSignals() {
this._userVerifier.connect('info', this._onInfo.bind(this));
@@ -389,22 +397,22 @@ var ShellUserVerifier = class {
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() {
if (this._preemptingService)
return this._preemptingService;
return this._defaultService;
}
},
serviceIsForeground(serviceName) {
return serviceName == this._getForegroundService();
}
},
serviceIsDefault(serviceName) {
return serviceName == this._defaultService;
}
},
_updateDefaultService() {
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
@@ -418,7 +426,7 @@ var ShellUserVerifier = class {
log("no authentication service is enabled, using password authentication");
this._defaultService = PASSWORD_SERVICE_NAME;
}
}
},
_startService(serviceName) {
this._hold.acquire();
@@ -454,14 +462,14 @@ var ShellUserVerifier = class {
this._hold.release();
});
}
}
},
_beginVerification() {
this._startService(this._getForegroundService());
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
this._startService(FINGERPRINT_SERVICE_NAME);
}
},
_onInfo(client, serviceName, info) {
if (this.serviceIsForeground(serviceName)) {
@@ -476,21 +484,21 @@ var ShellUserVerifier = class {
// to indicate the user can swipe their finger instead
this._queueMessage(_("(or swipe finger)"), MessageType.HINT);
}
}
},
_onProblem(client, serviceName, problem) {
if (!this.serviceIsForeground(serviceName))
return;
this._queueMessage(problem, MessageType.ERROR);
}
},
_onInfoQuery(client, serviceName, question) {
if (!this.serviceIsForeground(serviceName))
return;
this.emit('ask-question', serviceName, question, '');
}
},
_onSecretInfoQuery(client, serviceName, secretQuestion) {
if (!this.serviceIsForeground(serviceName))
@@ -503,7 +511,7 @@ var ShellUserVerifier = class {
}
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
}
},
_onReset() {
// Clear previous attempts to authenticate
@@ -511,20 +519,20 @@ var ShellUserVerifier = class {
this._updateDefaultService();
this.emit('reset');
}
},
_onVerificationComplete() {
this.emit('verification-complete');
}
},
_cancelAndReset() {
this.cancel();
this._onReset();
}
},
_retry() {
this.begin(this._userName, new Batch.Hold());
}
},
_verificationFailed(retry) {
// For Not Listed / enterprise logins, immediately reset
@@ -559,7 +567,7 @@ var ShellUserVerifier = class {
}
this.emit('verification-failed', canRetry);
}
},
_onConversationStopped(client, serviceName) {
// If the login failed with the preauthenticated oVirt credentials
@@ -578,6 +586,6 @@ var ShellUserVerifier = class {
if (this.serviceIsForeground(serviceName)) {
this._verificationFailed(true);
}
}
};
},
});
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@@ -16,7 +16,6 @@
<file>misc/history.js</file>
<file>misc/ibusManager.js</file>
<file>misc/inputMethod.js</file>
<file>misc/introspect.js</file>
<file>misc/jsParse.js</file>
<file>misc/keyboardManager.js</file>
<file>misc/loginManager.js</file>
@@ -78,11 +77,11 @@
<file>ui/overview.js</file>
<file>ui/overviewControls.js</file>
<file>ui/padOsd.js</file>
<file>ui/pageIndicators.js</file>
<file>ui/panel.js</file>
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>
<file>ui/popupMenu.js</file>
<file>ui/remoteMenu.js</file>
<file>ui/remoteSearch.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>

View File

@@ -3,7 +3,7 @@
// Common utils for the extension system and the extension
// preferences tool
const Gettext = imports.gettext;
const Lang = imports.lang;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
@@ -64,66 +64,6 @@ function getCurrentExtension() {
return null;
}
/**
* initTranslations:
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
*/
function initTranslations(domain) {
let extension = getCurrentExtension();
if (!extension)
throw new Error('initTranslations() can only be called from extensions');
domain = domain || extension.metadata['gettext-domain'];
// Expect USER extensions to have a locale/ subfolder, otherwise assume a
// SYSTEM extension that has been installed in the same prefix as the shell
let localeDir = extension.dir.get_child('locale');
if (localeDir.query_exists(null))
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
/**
* getSettings:
* @schema: (optional): the GSettings schema id
*
* Builds and returns a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is omitted, it is taken from
* metadata['settings-schema'].
*/
function getSettings(schema) {
let extension = getCurrentExtension();
if (!extension)
throw new Error('getSettings() can only be called from extensions');
schema = schema || extension.metadata['settings-schema'];
const GioSSS = Gio.SettingsSchemaSource;
// Expect USER extensions to have a schemas/ subfolder, otherwise assume a
// SYSTEM extension that has been installed in the same prefix as the shell
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
else
schemaSource = GioSSS.get_default();
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
throw new Error(`Schema ${schema} could not be found for extension ${extension.metadata.uuid}. Please check your installation`);
return new Gio.Settings({ settings_schema: schemaObj });
}
/**
* versionCheck:
* @required: an array of versions we're compatible with
@@ -220,7 +160,9 @@ function installImporter(extension) {
imports.searchPath = oldSearchPath;
}
var ExtensionFinder = class {
var ExtensionFinder = new Lang.Class({
Name: 'ExtensionFinder',
_loadExtension(extensionDir, info, perUserDir) {
let fileType = info.get_file_type();
if (fileType != Gio.FileType.DIRECTORY)
@@ -242,7 +184,7 @@ var ExtensionFinder = class {
return;
}
this.emit('extension-found', extension);
}
},
scanExtensions() {
let perUserDir = Gio.File.new_for_path(global.userdatadir);
@@ -250,5 +192,5 @@ var ExtensionFinder = class {
this._loadExtension(dir, info, perUserDir);
});
}
};
});
Signals.addSignalMethods(ExtensionFinder.prototype);

View File

@@ -1,7 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib } = imports.gi;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Config = imports.misc.config;
const Params = imports.misc.params;
function collectFromDatadirs(subdir, includeUserDir, processFile) {
let dataDirs = GLib.get_system_data_dirs();

View File

@@ -1,6 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;

View File

@@ -1,13 +1,16 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const Clutter = imports.gi.Clutter;
const Params = imports.misc.params;
var DEFAULT_LIMIT = 512;
var HistoryManager = class {
constructor(params) {
var HistoryManager = new Lang.Class({
Name: 'HistoryManager',
_init(params) {
params = Params.parse(params, { gsettingsKey: null,
limit: DEFAULT_LIMIT,
entry: null });
@@ -31,12 +34,12 @@ var HistoryManager = class {
this._entry.connect('key-press-event',
this._onEntryKeyPress.bind(this));
}
}
},
_historyChanged() {
this._history = global.settings.get_strv(this._key);
this._historyIndex = this._history.length;
}
},
_setPrevItem(text) {
if (this._historyIndex <= 0)
@@ -47,7 +50,7 @@ var HistoryManager = class {
this._historyIndex--;
this._indexChanged();
return true;
}
},
_setNextItem(text) {
if (this._historyIndex >= this._history.length)
@@ -58,7 +61,7 @@ var HistoryManager = class {
this._historyIndex++;
this._indexChanged();
return true;
}
},
lastItem() {
if (this._historyIndex != this._history.length) {
@@ -67,7 +70,7 @@ var HistoryManager = class {
}
return this._historyIndex ? this._history[this._historyIndex -1] : null;
}
},
addItem(input) {
if (this._history.length == 0 ||
@@ -78,7 +81,7 @@ var HistoryManager = class {
this._save();
}
this._historyIndex = this._history.length;
}
},
_onEntryKeyPress(entry, event) {
let symbol = event.get_key_symbol();
@@ -88,7 +91,7 @@ var HistoryManager = class {
return this._setNextItem(entry.get_text());
}
return Clutter.EVENT_PROPAGATE;
}
},
_indexChanged() {
let current = this._history[this._historyIndex] || '';
@@ -96,7 +99,7 @@ var HistoryManager = class {
if (this._entry)
this._entry.set_text(current);
}
},
_save() {
if (this._history.length > this._limit)
@@ -105,5 +108,5 @@ var HistoryManager = class {
if (this._key)
global.settings.set_strv(this._key, this._history);
}
};
});
Signals.addSignalMethods(HistoryManager.prototype);

View File

@@ -1,9 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib, IBus } = imports.gi;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const IBus = imports.gi.IBus;
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
// Ensure runtime version matches
@@ -29,16 +32,17 @@ function getIBusManager() {
return _ibusManager;
}
var IBusManager = class {
constructor() {
var IBusManager = new Lang.Class({
Name: 'IBusManager',
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
_MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms
_PRELOAD_ENGINES_DELAY_TIME: 30, // sec
_init() {
IBus.init();
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
this._MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
this._PRELOAD_ENGINES_DELAY_TIME = 30; // sec
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
this._panelService = null;
@@ -56,7 +60,7 @@ var IBusManager = class {
this._ibus.connect('global-engine-changed', this._engineChanged.bind(this));
this._spawn();
}
},
_spawn() {
try {
@@ -65,7 +69,7 @@ var IBusManager = class {
} catch(e) {
log('Failed to launch ibus-daemon: ' + e.message);
}
}
},
_clear() {
if (this._panelService)
@@ -81,7 +85,7 @@ var IBusManager = class {
this.emit('ready', false);
this._spawn();
}
},
_onConnected() {
this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
@@ -89,7 +93,7 @@ var IBusManager = class {
IBus.BusNameFlag.REPLACE_EXISTING,
-1, null,
this._initPanelService.bind(this));
}
},
_initEngines(ibus, result) {
let enginesList = this._ibus.list_engines_async_finish(result);
@@ -102,7 +106,7 @@ var IBusManager = class {
} else {
this._clear();
}
}
},
_initPanelService(ibus, result) {
let success = this._ibus.request_name_async_finish(result);
@@ -147,13 +151,13 @@ var IBusManager = class {
} else {
this._clear();
}
}
},
_updateReadiness() {
this._ready = (Object.keys(this._engines).length > 0 &&
this._panelService != null);
this.emit('ready', this._ready);
}
},
_engineChanged(bus, engineName) {
if (!this._ready)
@@ -174,26 +178,26 @@ var IBusManager = class {
this.emit('properties-registered', this._currentEngineName, props);
});
}
},
_updateProperty(panel, prop) {
this.emit('property-updated', this._currentEngineName, prop);
}
},
_setContentType(panel, purpose, hints) {
this.emit('set-content-type', purpose, hints);
}
},
activateProperty(key, state) {
this._panelService.property_activate(key, state);
}
},
getEngineDesc(id) {
if (!this._ready || !this._engines.hasOwnProperty(id))
return null;
return this._engines[id];
}
},
setEngine(id, callback) {
// Send id even if id == this._currentEngineName
@@ -207,7 +211,7 @@ var IBusManager = class {
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, callback || null);
}
},
preloadEngines(ids) {
if (!this._ibus || ids.length == 0)
@@ -229,6 +233,6 @@ var IBusManager = class {
this._preloadEnginesId = 0;
return GLib.SOURCE_REMOVE;
});
}
};
},
});
Signals.addSignalMethods(IBusManager.prototype);

View File

@@ -1,21 +1,23 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GLib, GObject, IBus } = imports.gi;
const Clutter = imports.gi.Clutter;
const IBus = imports.gi.IBus;
const Keyboard = imports.ui.status.keyboard;
const Lang = imports.lang;
const Signals = imports.signals;
var HIDE_PANEL_TIME = 50;
var InputMethod = new Lang.Class({
Name: 'InputMethod',
Extends: Clutter.InputMethod,
var InputMethod = GObject.registerClass(
class InputMethod extends Clutter.InputMethod {
_init() {
super._init();
this.parent();
this._hints = 0;
this._purpose = 0;
this._enabled = true;
this._currentFocus = null;
this._preeditStr = '';
this._preeditPos = 0;
this._preeditVisible = false;
this._hidePanelId = 0;
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', this._onConnected.bind(this));
this._ibus.connect('disconnected', this._clear.bind(this));
@@ -28,11 +30,11 @@ class InputMethod extends Clutter.InputMethod {
if (this._ibus.is_connected())
this._onConnected();
}
},
get currentFocus() {
return this._currentFocus;
}
},
_updateCapabilities() {
let caps = 0;
@@ -47,19 +49,21 @@ class InputMethod extends Clutter.InputMethod {
if (this._context)
this._context.set_capabilities(caps);
}
},
_onSourceChanged() {
this._currentSource = this._inputSourceManager.currentSource;
}
},
_onConnected() {
this._ibus.create_input_context_async ('gnome-shell', -1, null,
this._setContext.bind(this));
}
},
_setContext(bus, res) {
this._context = this._ibus.create_input_context_async_finish(res);
this._context.connect('enabled', () => { this._enabled = true });
this._context.connect('disabled', () => { this._enabled = false });
this._context.connect('commit-text', this._onCommitText.bind(this));
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
@@ -68,29 +72,30 @@ class InputMethod extends Clutter.InputMethod {
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
this._updateCapabilities();
}
},
_clear() {
this._context = null;
this._hints = 0;
this._purpose = 0;
this._enabled = false;
this._preeditStr = ''
this._preeditPos = 0;
this._preeditVisible = false;
}
},
_emitRequestSurrounding() {
if (this._context.needs_surrounding_text())
this.emit('request-surrounding');
}
},
_onCommitText(context, text) {
this.commit(text.get_text());
}
},
_onDeleteSurroundingText(context) {
this.delete_surrounding();
}
},
_onUpdatePreeditText(context, text, pos, visible) {
if (text == null)
@@ -106,17 +111,17 @@ class InputMethod extends Clutter.InputMethod {
this._preeditStr = preedit;
this._preeditPos = pos;
this._preeditVisible = visible;
}
},
_onShowPreeditText(context) {
this._preeditVisible = true;
this.set_preedit_text(this._preeditStr, this._preeditPos);
}
},
_onHidePreeditText(context) {
this.set_preedit_text(null, this._preeditPos);
this._preeditVisible = false;
}
},
_onForwardKeyEvent(context, keyval, keycode, state) {
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
@@ -130,7 +135,7 @@ class InputMethod extends Clutter.InputMethod {
time = global.display.get_current_time_roundtrip();
this.forward_key(keyval, keycode + 8, state & Clutter.ModifierType.MODIFIER_MASK, time, press);
}
},
vfunc_focus_in(focus) {
this._currentFocus = focus;
@@ -139,12 +144,7 @@ class InputMethod extends Clutter.InputMethod {
this._updateCapabilities();
this._emitRequestSurrounding();
}
if (this._hidePanelId) {
GLib.source_remove(this._hidePanelId);
this._hidePanelId = 0;
}
}
},
vfunc_focus_out() {
this._currentFocus = null;
@@ -158,13 +158,7 @@ class InputMethod extends Clutter.InputMethod {
this.set_preedit_text(null, 0);
this._preeditStr = null;
}
this._hidePanelId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, HIDE_PANEL_TIME, () => {
this.set_input_panel_state(Clutter.InputPanelState.OFF);
this._hidePanelId = 0;
return GLib.SOURCE_REMOVE;
});
}
},
vfunc_reset() {
if (this._context) {
@@ -177,7 +171,7 @@ class InputMethod extends Clutter.InputMethod {
this.set_preedit_text(null, 0);
this._preeditStr = null;
}
}
},
vfunc_set_cursor_location(rect) {
if (this._context) {
@@ -185,7 +179,7 @@ class InputMethod extends Clutter.InputMethod {
rect.get_width(), rect.get_height());
this._emitRequestSurrounding();
}
}
},
vfunc_set_surrounding(text, cursor, anchor) {
if (!this._context || !text)
@@ -193,7 +187,7 @@ class InputMethod extends Clutter.InputMethod {
let ibusText = IBus.Text.new_from_string(text);
this._context.set_surrounding_text(ibusText, cursor, anchor);
}
},
vfunc_update_content_hints(hints) {
let ibusHints = 0;
@@ -213,7 +207,7 @@ class InputMethod extends Clutter.InputMethod {
this._hints = ibusHints;
if (this._context)
this._context.set_content_type(this._purpose, this._hints);
}
},
vfunc_update_content_purpose(purpose) {
let ibusPurpose = 0;
@@ -239,10 +233,10 @@ class InputMethod extends Clutter.InputMethod {
this._purpose = ibusPurpose;
if (this._context)
this._context.set_content_type(this._purpose, this._hints);
}
},
vfunc_filter_key_event(event) {
if (!this._context)
if (!this._context || !this._enabled)
return false;
if (!this._currentSource)
return false;
@@ -266,5 +260,5 @@ class InputMethod extends Clutter.InputMethod {
}
});
return true;
}
},
});

View File

@@ -1,160 +0,0 @@
const { Gio, GLib, Meta, Shell } = imports.gi;
const INTROSPECT_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect';
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const { loadInterfaceXML } = imports.misc.fileUtils;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
var IntrospectService = class {
constructor() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Introspect');
Gio.DBus.session.own_name('org.gnome.Shell.Introspect',
Gio.BusNameOwnerFlags.REPLACE,
null, null);
this._runningApplications = {};
this._runningApplicationsDirty = true;
this._activeApplication = null;
this._activeApplicationDirty = true;
this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('app-state-changed',
() => {
this._runningApplicationsDirty = true;
this._syncRunningApplications();
});
this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app',
() => {
this._activeApplicationDirty = true;
this._syncRunningApplications();
});
this._syncRunningApplications();
}
_isStandaloneApp(app) {
let windows = app.get_windows();
return app.get_windows().some(w => w.transient_for == null);
}
_isIntrospectEnabled() {
return this._settings.get_boolean(INTROSPECT_KEY);
}
_isSenderWhitelisted(sender) {
return APP_WHITELIST.includes(sender);
}
_syncRunningApplications() {
let tracker = Shell.WindowTracker.get_default();
let apps = this._appSystem.get_running();
let seatName = "seat0";
let newRunningApplications = {};
let newActiveApplication = null;
let focusedApp = tracker.focus_app;
for (let app of apps) {
let appInfo = {};
let isAppActive = (focusedApp == app);
if (!this._isStandaloneApp(app))
continue;
if (isAppActive) {
appInfo['active-on-seats'] = new GLib.Variant('as', [seatName]);
newActiveApplication = app.get_id();
}
newRunningApplications[app.get_id()] = appInfo;
}
if (this._runningApplicationsDirty ||
(this._activeApplicationDirty &&
this._activeApplication != newActiveApplication)) {
this._runningApplications = newRunningApplications;
this._activeApplication = newActiveApplication;
this._dbusImpl.emit_signal('RunningApplicationsChanged', null);
}
this._runningApplicationsDirty = false;
this._activeApplicationDirty = false;
}
_isEligibleWindow(window) {
if (window.is_override_redirect())
return false;
let type = window.get_window_type();
return (type == Meta.WindowType.NORMAL ||
type == Meta.WindowType.DIALOG ||
type == Meta.WindowType.MODAL_DIALOG ||
type == Meta.WindowType.UTILITY);
}
GetRunningApplicationsAsync(params, invocation) {
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
return;
}
invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
}
GetWindowsAsync(params, invocation) {
let focusWindow = global.display.get_focus_window();
let apps = this._appSystem.get_running();
let windowsList = {};
if (!this._isIntrospectEnabled()) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
return;
}
for (let app of apps) {
let windows = app.get_windows();
for (let window of windows) {
if (!this._isEligibleWindow(window))
continue;
let windowId = window.get_id();
let frameRect = window.get_frame_rect();
let title = window.get_title();
let wmClass = window.get_wm_class();
windowsList[windowId] = {
'app-id': GLib.Variant.new('s', app.get_id()),
'client-type': GLib.Variant.new('u', window.get_client_type()),
'is-hidden': GLib.Variant.new('b', window.is_hidden()),
'has-focus': GLib.Variant.new('b', (window == focusWindow)),
'width': GLib.Variant.new('u', frameRect.width),
'height': GLib.Variant.new('u', frameRect.height)
};
// These properties may not be available for all windows:
if (title != null)
windowsList[windowId]['title'] = GLib.Variant.new('s', title);
if (wmClass != null)
windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
}
}
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
}
};

View File

@@ -1,6 +1,9 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { GLib, GnomeDesktop, Meta } = imports.gi;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
@@ -35,20 +38,22 @@ function holdKeyboard() {
global.display.freeze_keyboard(global.get_current_time());
}
var KeyboardManager = class {
constructor() {
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
this.MAX_LAYOUTS_PER_GROUP = 4;
var KeyboardManager = new Lang.Class({
Name: 'KeyboardManager',
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
MAX_LAYOUTS_PER_GROUP: 4,
_init() {
this._xkbInfo = getXkbInfo();
this._current = null;
this._localeLayoutInfo = this._getLocaleLayout();
this._layoutInfos = {};
this._currentKeymap = null;
}
},
_applyLayoutGroup(group) {
let options = this._buildOptionsString();
@@ -62,11 +67,11 @@ var KeyboardManager = class {
this._currentKeymap = {layouts, variants, options};
Meta.get_backend().set_keymap(layouts, variants, options);
}
},
_applyLayoutGroupIndex(idx) {
Meta.get_backend().lock_layout_group(idx);
}
},
apply(id) {
let info = this._layoutInfos[id];
@@ -82,7 +87,7 @@ var KeyboardManager = class {
}
this._current = info;
}
},
reapply() {
if (!this._current)
@@ -90,7 +95,7 @@ var KeyboardManager = class {
this._applyLayoutGroup(this._current.group);
this._applyLayoutGroupIndex(this._current.groupIndex);
}
},
setUserLayouts(ids) {
this._current = null;
@@ -121,7 +126,7 @@ var KeyboardManager = class {
i += 1;
}
}
},
_getLocaleLayout() {
let locale = GLib.get_language_names()[0];
@@ -138,21 +143,21 @@ var KeyboardManager = class {
return { layout: _layout, variant: _variant };
else
return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
}
},
_buildGroupStrings(_group) {
let group = _group.concat(this._localeLayoutInfo);
let layouts = group.map(g => g.layout).join(',');
let variants = group.map(g => g.variant).join(',');
return [layouts, variants];
}
},
setKeyboardOptions(options) {
this._xkbOptions = options;
}
},
_buildOptionsString() {
let options = this._xkbOptions.join(',');
return options;
}
};
});

View File

@@ -1,6 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { GLib, Gio } = imports.gi;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;
@@ -66,8 +70,10 @@ function getLoginManager() {
return _loginManager;
}
var LoginManagerSystemd = class {
constructor() {
var LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd',
_init() {
this._proxy = new SystemdLoginManager(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
@@ -76,7 +82,7 @@ var LoginManagerSystemd = class {
'/org/freedesktop/login1/user/self');
this._proxy.connectSignal('PrepareForSleep',
this._prepareForSleep.bind(this));
}
},
getCurrentSessionProxy(callback) {
if (this._currentSession) {
@@ -123,7 +129,7 @@ var LoginManagerSystemd = class {
callback(this._currentSession);
}
});
}
},
canSuspend(asyncCallback) {
this._proxy.CanSuspendRemote((result, error) => {
@@ -135,7 +141,7 @@ var LoginManagerSystemd = class {
asyncCallback(canSuspend, needsAuth);
}
});
}
},
listSessions(asyncCallback) {
this._proxy.ListSessionsRemote((result, error) => {
@@ -144,11 +150,11 @@ var LoginManagerSystemd = class {
else
asyncCallback(result[0]);
});
}
},
suspend() {
this._proxy.SuspendRemote(true);
}
},
inhibit(reason, callback) {
let inVariant = GLib.Variant.new('(ssss)',
@@ -168,36 +174,38 @@ var LoginManagerSystemd = class {
callback(null);
}
});
}
},
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
this.emit('prepare-for-sleep', aboutToSuspend);
}
};
});
Signals.addSignalMethods(LoginManagerSystemd.prototype);
var LoginManagerDummy = class {
var LoginManagerDummy = new Lang.Class({
Name: 'LoginManagerDummy',
getCurrentSessionProxy(callback) {
// we could return a DummySession object that fakes whatever callers
// expect (at the time of writing: connect() and connectSignal()
// methods), but just never calling the callback should be safer
}
},
canSuspend(asyncCallback) {
asyncCallback(false, false);
}
},
listSessions(asyncCallback) {
asyncCallback([]);
}
},
suspend() {
this.emit('prepare-for-sleep', true);
this.emit('prepare-for-sleep', false);
}
},
inhibit(reason, callback) {
callback(null);
}
};
});
Signals.addSignalMethods(LoginManagerDummy.prototype);

View File

@@ -1,6 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, NMA } = imports.gi;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const NMA = imports.gi.NMA;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;
@@ -98,8 +100,10 @@ const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInter
const ModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager.Modem.Cdma');
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
var ModemGsm = class {
constructor(path) {
var ModemGsm = new Lang.Class({
Name: 'ModemGsm',
_init(path) {
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
@@ -135,11 +139,13 @@ var ModemGsm = class {
this.emit('notify::signal-quality');
});
}
};
});
Signals.addSignalMethods(ModemGsm.prototype);
var ModemCdma = class {
constructor(path) {
var ModemCdma = new Lang.Class({
Name: 'ModemCdma',
_init(path) {
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
@@ -163,7 +169,7 @@ var ModemCdma = class {
}
this.emit('notify::signal-quality');
});
}
},
_refreshServingSystem() {
this._proxy.GetServingSystemRemote(([result], err) => {
@@ -178,7 +184,7 @@ var ModemCdma = class {
this.emit('notify::operator-name');
});
}
};
});
Signals.addSignalMethods(ModemCdma.prototype);
@@ -195,8 +201,10 @@ const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gp
const BroadbandModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem.ModemCdma');
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
var BroadbandModem = class {
constructor(path, capabilities) {
var BroadbandModem = new Lang.Class({
Name: 'BroadbandModem',
_init(path, capabilities) {
this._proxy = new BroadbandModemProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_3gpp = new BroadbandModem3gppProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_cdma = new BroadbandModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
@@ -221,13 +229,13 @@ var BroadbandModem = class {
this._reloadCdmaOperatorName();
});
this._reloadCdmaOperatorName();
}
},
_reloadSignalQuality() {
let [quality, recent] = this._proxy.SignalQuality;
this.signal_quality = quality;
this.emit('notify::signal-quality');
}
},
_reloadOperatorName() {
let new_name = "";
@@ -242,19 +250,19 @@ var BroadbandModem = class {
this.operator_name = new_name;
this.emit('notify::operator-name');
}
},
_reload3gppOperatorName() {
let name = this._proxy_3gpp.OperatorName;
let code = this._proxy_3gpp.OperatorCode;
this.operator_name_3gpp = _findProviderForMccMnc(name, code);
this._reloadOperatorName();
}
},
_reloadCdmaOperatorName() {
let sid = this._proxy_cdma.Sid;
this.operator_name_cdma = _findProviderForSid(sid);
this._reloadOperatorName();
}
};
});
Signals.addSignalMethods(BroadbandModem.prototype);

View File

@@ -1,6 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib } = imports.gi;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Params = imports.misc.params;
const Signals = imports.signals;
@@ -25,8 +27,9 @@ const ObjectManagerIface = `
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
var ObjectManager = class {
constructor(params) {
var ObjectManager = new Lang.Class({
Name: 'ObjectManager',
_init(params) {
params = Params.parse(params, { connection: null,
name: null,
objectPath: null,
@@ -60,7 +63,7 @@ var ObjectManager = class {
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
this._cancellable,
this._onManagerProxyLoaded.bind(this));
}
},
_tryToCompleteLoad() {
if (this._numLoadInhibitors == 0)
@@ -71,7 +74,7 @@ var ObjectManager = class {
if (this._onLoaded)
this._onLoaded();
}
}
},
_addInterface(objectPath, interfaceName, onFinished) {
let info = this._interfaceInfos[interfaceName];
@@ -126,7 +129,7 @@ var ObjectManager = class {
if (onFinished)
onFinished();
});
}
},
_removeInterface(objectPath, interfaceName) {
if (!this._objects[objectPath])
@@ -152,14 +155,14 @@ var ObjectManager = class {
delete this._objects[objectPath];
this.emit('object-removed', objectPath);
}
}
},
_onManagerProxyLoaded(initable, result) {
let error = null;
try {
initable.init_finish(result);
} catch(e) {
logError(e, 'could not initialize object manager for object ' + this._serviceName);
logError(e, 'could not initialize object manager for object ' + params.name);
this._tryToCompleteLoad();
return;
@@ -191,7 +194,7 @@ var ObjectManager = class {
if (this._managerProxy.g_name_owner)
this._onNameAppeared();
}
},
_onNameAppeared() {
this._managerProxy.GetManagedObjectsRemote((result, error) => {
@@ -229,7 +232,7 @@ var ObjectManager = class {
}
this._tryToCompleteLoad();
});
}
},
_onNameVanished() {
let objectPaths = Object.keys(this._objects);
@@ -245,14 +248,14 @@ var ObjectManager = class {
this._removeInterface(objectPath, interfaceName);
}
}
}
},
_registerInterfaces(interfaces) {
for (let i = 0; i < interfaces.length; i++) {
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
this._interfaceInfos[info.name] = info;
}
}
},
getProxy(objectPath, interfaceName) {
let object = this._objects[objectPath];
@@ -261,7 +264,7 @@ var ObjectManager = class {
return null;
return object[interfaceName];
}
},
getProxiesForInterface(interfaceName) {
let proxyList = this._interfaces[interfaceName];
@@ -270,7 +273,7 @@ var ObjectManager = class {
return [];
return proxyList;
}
},
getAllProxies() {
let proxies = [];
@@ -280,8 +283,8 @@ var ObjectManager = class {
let object = this._objects[objectPaths];
let interfaceNames = Object.keys(object);
for (let j = 0; j < interfaceNames.length; j++) {
let interfaceName = interfaceNames[j];
for (let j = 0; i < interfaceNames.length; i++) {
let interfaceName = interfaceNames[i];
if (object[interfaceName])
proxies.push(object(interfaceName));
}
@@ -289,5 +292,5 @@ var ObjectManager = class {
return proxies;
}
};
});
Signals.addSignalMethods(ObjectManager.prototype);

View File

@@ -1,6 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const ObjectManager = imports.misc.objectManager;
@@ -24,8 +26,9 @@ function getSmartcardManager() {
return _smartcardManager;
}
var SmartcardManager = class {
constructor() {
var SmartcardManager = new Lang.Class({
Name: 'SmartcardManager',
_init() {
this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
name: "org.gnome.SettingsDaemon.Smartcard",
objectPath: '/org/gnome/SettingsDaemon/Smartcard',
@@ -33,7 +36,7 @@ var SmartcardManager = class {
onLoaded: this._onLoaded.bind(this) });
this._insertedTokens = {};
this._loginToken = null;
}
},
_onLoaded() {
let tokens = this._objectManager.getProxiesForInterface('org.gnome.SettingsDaemon.Smartcard.Token');
@@ -50,7 +53,7 @@ var SmartcardManager = class {
if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
this._removeToken(proxy);
});
}
},
_updateToken(token) {
let objectPath = token.get_object_path();
@@ -62,7 +65,7 @@ var SmartcardManager = class {
if (token.UsedToLogin)
this._loginToken = token;
}
},
_addToken(token) {
this._updateToken(token);
@@ -82,7 +85,7 @@ var SmartcardManager = class {
// Emit a smartcard-inserted at startup if it's already plugged in
if (token.IsInserted)
this.emit('smartcard-inserted', token);
}
},
_removeToken(token) {
let objectPath = token.get_object_path();
@@ -96,11 +99,11 @@ var SmartcardManager = class {
this._loginToken = null;
token.disconnectAll();
}
},
hasInsertedTokens() {
return Object.keys(this._insertedTokens).length > 0;
}
},
hasInsertedLoginToken() {
if (!this._loginToken)
@@ -112,5 +115,5 @@ var SmartcardManager = class {
return true;
}
};
});
Signals.addSignalMethods(SmartcardManager.prototype);

View File

@@ -1,4 +1,11 @@
const { AccountsService, Clutter, Gdm, Gio, GLib, GObject, Meta } = imports.gi;
const AccountsService = imports.gi.AccountsService;
const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const GObject = imports.gi.GObject;
const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager;
@@ -37,7 +44,9 @@ function getDefault() {
return _singleton;
}
const SystemActions = GObject.registerClass({
const SystemActions = new Lang.Class({
Name: 'SystemActions',
Extends: GObject.Object,
Properties: {
'can-power-off': GObject.ParamSpec.boolean('can-power-off',
'can-power-off',
@@ -74,10 +83,10 @@ const SystemActions = GObject.registerClass({
'orientation-lock-icon',
GObject.ParamFlags.READWRITE,
null)
}
}, class SystemActions extends GObject.Object {
},
_init() {
super._init();
this.parent();
this._canHavePowerOff = true;
this._canHaveSuspend = true;
@@ -177,35 +186,35 @@ const SystemActions = GObject.registerClass({
Main.sessionMode.connect('updated', () => { this._sessionUpdated(); });
this._sessionUpdated();
}
},
get can_power_off() {
return this._actions.get(POWER_OFF_ACTION_ID).available;
}
},
get can_suspend() {
return this._actions.get(SUSPEND_ACTION_ID).available;
}
},
get can_lock_screen() {
return this._actions.get(LOCK_SCREEN_ACTION_ID).available;
}
},
get can_switch_user() {
return this._actions.get(SWITCH_USER_ACTION_ID).available;
}
},
get can_logout() {
return this._actions.get(LOGOUT_ACTION_ID).available;
}
},
get can_lock_orientation() {
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).available;
}
},
get orientation_lock_icon() {
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
}
},
_sensorProxyAppeared() {
this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
@@ -218,7 +227,7 @@ const SystemActions = GObject.registerClass({
() => { this._updateOrientationLock(); });
this._updateOrientationLock();
});
}
},
_updateOrientationLock() {
let available = false;
@@ -229,7 +238,7 @@ const SystemActions = GObject.registerClass({
this._actions.get(LOCK_ORIENTATION_ACTION_ID).available = available;
this.notify('can-lock-orientation');
}
},
_updateOrientationLockIcon() {
let locked = this._orientationSettings.get_boolean('orientation-lock');
@@ -238,14 +247,14 @@ const SystemActions = GObject.registerClass({
this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = iconName;
this.notify('orientation-lock-icon');
}
},
_sessionUpdated() {
this._updateLockScreen();
this._updatePowerOff();
this._updateSuspend();
this._updateMultiUser();
}
},
forceUpdate() {
// Whether those actions are available or not depends on both lockdown
@@ -253,7 +262,7 @@ const SystemActions = GObject.registerClass({
// latter, so their value may be outdated; force an update now
this._updateHaveShutdown();
this._updateHaveSuspend();
}
},
getMatchingActions(terms) {
// terms is a list of strings
@@ -266,15 +275,15 @@ const SystemActions = GObject.registerClass({
results.push(key);
return results;
}
},
getName(id) {
return this._actions.get(id).name;
}
},
getIconName(id) {
return this._actions.get(id).iconName;
}
},
activateAction(id) {
switch (id) {
@@ -297,14 +306,14 @@ const SystemActions = GObject.registerClass({
this.activateLockOrientation();
break;
}
}
},
_updateLockScreen() {
let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
this._actions.get(LOCK_SCREEN_ACTION_ID).available = showLock && allowLockScreen && LoginManager.canLock();
this.notify('can-lock-screen');
}
},
_updateHaveShutdown() {
this._session.CanShutdownRemote((result, error) => {
@@ -314,7 +323,7 @@ const SystemActions = GObject.registerClass({
this._canHavePowerOff = result[0];
this._updatePowerOff();
});
}
},
_updatePowerOff() {
let disabled = Main.sessionMode.isLocked ||
@@ -322,7 +331,7 @@ const SystemActions = GObject.registerClass({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled;
this.notify('can-power-off');
}
},
_updateHaveSuspend() {
this._loginManager.canSuspend(
@@ -331,7 +340,7 @@ const SystemActions = GObject.registerClass({
this._suspendNeedsAuth = needsAuth;
this._updateSuspend();
});
}
},
_updateSuspend() {
let disabled = (Main.sessionMode.isLocked &&
@@ -340,12 +349,12 @@ const SystemActions = GObject.registerClass({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(SUSPEND_ACTION_ID).available = this._canHaveSuspend && !disabled;
this.notify('can-suspend');
}
},
_updateMultiUser() {
this._updateLogout();
this._updateSwitchUser();
}
},
_updateSwitchUser() {
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
@@ -357,7 +366,7 @@ const SystemActions = GObject.registerClass({
this.notify('can-switch-user');
return visible;
}
},
_updateLogout() {
let user = this._userManager.get_user(GLib.get_user_name());
@@ -375,7 +384,7 @@ const SystemActions = GObject.registerClass({
this.notify('can-logout');
return visible;
}
},
activateLockOrientation() {
if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
@@ -383,14 +392,14 @@ const SystemActions = GObject.registerClass({
let locked = this._orientationSettings.get_boolean('orientation-lock');
this._orientationSettings.set_boolean('orientation-lock', !locked);
}
},
activateLockScreen() {
if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available)
throw new Error('The lock-screen action is not available!');
Main.screenShield.lock(true);
}
},
activateSwitchUser() {
if (!this._actions.get(SWITCH_USER_ACTION_ID).available)
@@ -403,7 +412,7 @@ const SystemActions = GObject.registerClass({
Gdm.goto_login_session_sync(null);
return false;
});
}
},
activateLogout() {
if (!this._actions.get(LOGOUT_ACTION_ID).available)
@@ -411,14 +420,14 @@ const SystemActions = GObject.registerClass({
Main.overview.hide();
this._session.LogoutRemote(0);
}
},
activatePowerOff() {
if (!this._actions.get(POWER_OFF_ACTION_ID).available)
throw new Error('The power-off action is not available!');
this._session.ShutdownRemote(0);
}
},
activateSuspend() {
if (!this._actions.get(SUSPEND_ACTION_ID).available)

View File

@@ -1,9 +1,14 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
@@ -343,10 +348,12 @@ function insertSorted(array, val, cmp) {
return pos;
}
var CloseButton = GObject.registerClass(
class CloseButton extends St.Button {
var CloseButton = new Lang.Class({
Name: 'CloseButton',
Extends: St.Button,
_init(boxpointer) {
super._init({ style_class: 'notification-close'});
this.parent({ style_class: 'notification-close'});
// This is a bit tricky. St.Bin has its own x-align/y-align properties
// that compete with Clutter's properties. This should be fixed for
@@ -363,10 +370,10 @@ class CloseButton extends St.Button {
this._boxPointer = boxpointer;
if (boxpointer)
this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
}
},
_computeBoxPointerOffset() {
if (!this._boxPointer || !this._boxPointer.get_stage())
if (!this._boxPointer || !this._boxPointer.actor.get_stage())
return 0;
let side = this._boxPointer.arrowSide;
@@ -374,7 +381,7 @@ class CloseButton extends St.Button {
return this._boxPointer.getArrowHeight();
else
return 0;
}
},
_sync() {
let themeNode = this.get_theme_node();
@@ -382,12 +389,12 @@ class CloseButton extends St.Button {
let offY = this._computeBoxPointerOffset();
this.translation_x = themeNode.get_length('-shell-close-overlap-x')
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
}
},
vfunc_style_changed() {
this._sync();
super.vfunc_style_changed();
}
this.parent();
},
});
function makeCloseButton(boxpointer) {
@@ -430,8 +437,10 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
transition: 'easeOutQuad' });
}
var AppSettingsMonitor = class {
constructor(appId, schemaId) {
var AppSettingsMonitor = new Lang.Class({
Name: 'AppSettingsMonitor',
_init(appId, schemaId) {
this._appId = appId;
this._schemaId = schemaId;
@@ -445,23 +454,23 @@ var AppSettingsMonitor = class {
this._appSystem.connect('installed-changed',
this._onInstalledChanged.bind(this));
this._onInstalledChanged();
}
},
get available() {
return this._app != null && this._settings != null;
}
},
activateApp() {
if (this._app)
this._app.activate();
}
},
watchSetting(key, callback) {
let handler = { id: 0, key: key, callback: callback };
this._handlers.push(handler);
this._connectHandler(handler);
}
},
_connectHandler(handler) {
if (!this._settings || handler.id > 0)
@@ -470,13 +479,13 @@ var AppSettingsMonitor = class {
handler.id = this._settings.connect('changed::' + handler.key,
handler.callback);
handler.callback(this._settings, handler.key);
}
},
_disconnectHandler(handler) {
if (this._settings && handler.id > 0)
this._settings.disconnect(handler.id);
handler.id = 0;
}
},
_onInstalledChanged() {
let hadApp = (this._app != null);
@@ -490,7 +499,7 @@ var AppSettingsMonitor = class {
this._checkSettings();
else
this._setSettings(null);
}
},
_setSettings(settings) {
this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
@@ -503,7 +512,7 @@ var AppSettingsMonitor = class {
if (hadSettings != haveSettings)
this.emit('available-changed');
}
},
_checkSettings() {
let schema = this._schemaSource.lookup(this._schemaId, true);
@@ -516,5 +525,5 @@ var AppSettingsMonitor = class {
});
}
}
};
});
Signals.addSignalMethods(AppSettingsMonitor.prototype);

View File

@@ -1,6 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Geoclue, Gio, GLib, GWeather } = imports.gi;
const Geoclue = imports.gi.Geoclue;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Signals = imports.signals;
const PermissionStore = imports.misc.permissionStore;
@@ -9,8 +13,10 @@ const Util = imports.misc.util;
// Minimum time between updates to show loading indication
var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
var WeatherClient = class {
constructor() {
var WeatherClient = new Lang.Class({
Name: 'WeatherClient',
_init() {
this._loading = false;
this._locationValid = false;
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
@@ -30,14 +36,6 @@ var WeatherClient = class {
return;
}
if (this._permStore.g_name_owner == null) {
// Failed to auto-start, likely because xdg-desktop-portal
// isn't installed; don't restrict access to location service
this._weatherAuthorized = true;
this._updateAutoLocation();
return;
}
this._permStore.LookupRemote('gnome', 'geolocation', (res, error) => {
if (error)
log('Error looking up permission: ' + error.message);
@@ -66,34 +64,34 @@ var WeatherClient = class {
this.emit('changed');
});
this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.desktop',
'org.gnome.Weather');
this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.Application.desktop',
'org.gnome.Weather.Application');
this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); });
this._weatherAppMon.watchSetting('automatic-location',
this._onAutomaticLocationChanged.bind(this));
this._weatherAppMon.watchSetting('locations',
this._onLocationsChanged.bind(this));
}
},
get available() {
return this._weatherAppMon.available;
}
},
get loading() {
return this._loading;
}
},
get hasLocation() {
return this._locationValid;
}
},
get info() {
return this._weatherInfo;
}
},
activateApp() {
this._weatherAppMon.activateApp();
}
},
update() {
if (!this._locationValid)
@@ -106,13 +104,13 @@ var WeatherClient = class {
this._weatherInfo.update();
else
this._loadInfo();
}
},
get _useAutoLocation() {
return this._autoLocationRequested &&
this._locationSettings.get_boolean('enabled') &&
this._weatherAuthorized;
}
},
_loadInfo() {
let id = this._weatherInfo.connect('updated', () => {
@@ -124,7 +122,7 @@ var WeatherClient = class {
this.emit('changed');
this._weatherInfo.update();
}
},
_locationsEqual(loc1, loc2) {
if (loc1 == loc2)
@@ -134,7 +132,7 @@ var WeatherClient = class {
return false;
return loc1.equal(loc2);
}
},
_setLocation(location) {
if (this._locationsEqual(this._weatherInfo.location, location))
@@ -150,7 +148,7 @@ var WeatherClient = class {
this._loadInfo();
else
this.emit('changed');
}
},
_updateLocationMonitoring() {
if (this._useAutoLocation) {
@@ -166,7 +164,7 @@ var WeatherClient = class {
this._gclueService.disconnect(this._gclueLocationChangedId);
this._gclueLocationChangedId = 0;
}
}
},
_startGClueService() {
if (this._gclueStarting)
@@ -187,7 +185,7 @@ var WeatherClient = class {
this._gclueService.get_client().distance_threshold = 100;
this._updateLocationMonitoring();
});
}
},
_onGClueLocationChanged() {
let geoLocation = this._gclueService.location;
@@ -196,7 +194,7 @@ var WeatherClient = class {
geoLocation.latitude,
geoLocation.longitude);
this._setLocation(location);
}
},
_onAutomaticLocationChanged(settings, key) {
let useAutoLocation = settings.get_boolean(key);
@@ -206,7 +204,7 @@ var WeatherClient = class {
this._autoLocationRequested = useAutoLocation;
this._updateAutoLocation();
}
},
_updateAutoLocation() {
this._updateLocationMonitoring();
@@ -215,7 +213,7 @@ var WeatherClient = class {
this._startGClueService();
else
this._setLocation(this._mostRecentLocation);
}
},
_onLocationsChanged(settings, key) {
let serialized = settings.get_value(key).deep_unpack().shift();
@@ -231,7 +229,7 @@ var WeatherClient = class {
if (!this._useAutoLocation || !this._gclueStarted)
this._setLocation(this._mostRecentLocation);
}
},
_onPermStoreChanged(proxy, sender, params) {
let [table, id, deleted, data, perms] = params;
@@ -239,11 +237,11 @@ var WeatherClient = class {
if (table != 'gnome' || id != 'geolocation')
return;
let permission = perms['org.gnome.Weather'] || ['NONE'];
let permission = perms['org.gnome.Weather.Application'] || ['NONE'];
let [accuracy] = permission;
this._weatherAuthorized = accuracy != 'NONE';
this._updateAutoLocation();
}
};
});
Signals.addSignalMethods(WeatherClient.prototype);

View File

@@ -10,7 +10,7 @@ const Scripting = imports.ui.scripting;
// someone should be able to get an idea of how well the shell is performing
// on a particular system.
var METRICS = {
let METRICS = {
overviewLatencyFirst:
{ description: "Time to first frame after triggering overview, first time",
units: "us" },
@@ -65,7 +65,7 @@ let WINDOW_CONFIGS = [
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' }
];
function *run() {
function run() {
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");

View File

@@ -1,8 +1,12 @@
const { Clutter, Gio, Shell } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
const Scripting = imports.ui.scripting;
const Shell = imports.gi.Shell;
var METRICS = {
let METRICS = {
timeToDesktop:
{ description: "Time from starting graphical.target to desktop showing",
units: "us" },
@@ -85,7 +89,7 @@ function extractBootTimestamp() {
return result;
}
function *run() {
function run() {
Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
@@ -104,10 +108,7 @@ function *run() {
yield Scripting.waitLeisure();
Scripting.scriptEvent('desktopShown');
let interfaceSettings = new Gio.Settings({
schema_id: 'org.gnome.desktop.interface'
});
interfaceSettings.set_boolean('enable-animations', false);
Gtk.Settings.get_default().gtk_enable_animations = false;
Scripting.scriptEvent('overviewShowStart');
Main.overview.show();
@@ -203,7 +204,7 @@ function *run() {
yield Scripting.sleep(1000);
interfaceSettings.set_boolean('enable-animations', true);
Gtk.Settings.get_default().gtk_enable_animations = true;
}
let overviewShowStart;

View File

@@ -1,6 +1,13 @@
const Format = imports.format;
const Gettext = imports.gettext;
const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Soup = imports.gi.Soup;
const WebKit = imports.gi.WebKit2;
const _ = Gettext.gettext;
@@ -26,10 +33,12 @@ const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
var PortalHeaderBar = GObject.registerClass(
class PortalHeaderBar extends Gtk.HeaderBar {
var PortalHeaderBar = new Lang.Class({
Name: 'PortalHeaderBar',
Extends: Gtk.HeaderBar,
_init() {
super._init({ show_close_button: true });
this.parent({ show_close_button: true });
// See ephy-title-box.c in epiphany for the layout
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
@@ -64,11 +73,11 @@ class PortalHeaderBar extends Gtk.HeaderBar {
hbox.add(this.subtitleLabel);
vbox.show_all();
}
},
setSubtitle(label) {
this.subtitleLabel.set_text(label);
}
},
setSecurityIcon(securityLevel) {
switch (securityLevel) {
@@ -86,13 +95,15 @@ class PortalHeaderBar extends Gtk.HeaderBar {
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
break;
}
}
},
});
var PortalWindow = GObject.registerClass(
class PortalWindow extends Gtk.ApplicationWindow {
var PortalWindow = new Lang.Class({
Name: 'PortalWindow',
Extends: Gtk.ApplicationWindow,
_init(application, url, timestamp, doneCallback) {
super._init({ application: application });
this.parent({ application: application });
this.connect('delete-event', this.destroyWindow.bind(this));
this._headerBar = new PortalHeaderBar();
@@ -133,11 +144,11 @@ class PortalWindow extends Gtk.ApplicationWindow {
this.present_with_time(timestamp);
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
}
},
destroyWindow() {
this.destroy();
}
},
_syncUri() {
let uri = this._webView.uri;
@@ -145,12 +156,12 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
else
this._headerBar.setSubtitle('');
}
},
refresh() {
this._everSeenRedirect = false;
this._webView.load_uri(this._originalUrl);
}
},
vfunc_delete_event(event) {
if (this._recheckAtExit)
@@ -158,7 +169,7 @@ class PortalWindow extends Gtk.ApplicationWindow {
else
this._doneCallback(PortalHelperResult.CANCELLED);
return false;
}
},
_onLoadChanged(view, loadEvent) {
if (loadEvent == WebKit.LoadEvent.STARTED) {
@@ -172,11 +183,11 @@ class PortalWindow extends Gtk.ApplicationWindow {
else
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
}
}
},
_onInsecureContentDetected() {
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
}
},
_onLoadFailedWithTlsErrors(view, failingURI, certificate, errors) {
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
@@ -184,7 +195,7 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
this._webView.load_uri(failingURI);
return true;
}
},
_onDecidePolicy(view, decision, type) {
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
@@ -251,13 +262,15 @@ class PortalWindow extends Gtk.ApplicationWindow {
decision.use();
return true;
}
},
});
var WebPortalHelper = GObject.registerClass(
class WebPortalHelper extends Gtk.Application {
var WebPortalHelper = new Lang.Class({
Name: 'WebPortalHelper',
Extends: Gtk.Application,
_init() {
super._init({ application_id: 'org.gnome.Shell.PortalHelper',
this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
flags: Gio.ApplicationFlags.IS_SERVICE,
inactivity_timeout: 30000 });
@@ -267,30 +280,30 @@ class WebPortalHelper extends Gtk.Application {
let action = new Gio.SimpleAction({ name: 'quit' });
action.connect('activate', () => { this.active_window.destroyWindow(); });
this.add_action(action);
}
},
vfunc_dbus_register(connection, path) {
this._dbusImpl.export(connection, path);
super.vfunc_dbus_register(connection, path);
this.parent(connection, path);
return true;
}
},
vfunc_dbus_unregister(connection, path) {
this._dbusImpl.unexport_from_connection(connection);
super.vfunc_dbus_unregister(connection, path);
}
this.parent(connection, path);
},
vfunc_activate() {
// If launched manually (for example for testing), force a dummy authentication
// session with the default url
this.Authenticate('/org/gnome/dummy', '', 0);
}
},
Authenticate(connection, url, timestamp) {
this._queue.push({ connection: connection, url: url, timestamp: timestamp });
this._processQueue();
}
},
Close(connection) {
for (let i = 0; i < this._queue.length; i++) {
@@ -305,7 +318,7 @@ class WebPortalHelper extends Gtk.Application {
}
this._processQueue();
}
},
Refresh(connection) {
for (let i = 0; i < this._queue.length; i++) {
@@ -317,7 +330,7 @@ class WebPortalHelper extends Gtk.Application {
break;
}
}
}
},
_processQueue() {
if (this._queue.length == 0)
@@ -330,7 +343,7 @@ class WebPortalHelper extends Gtk.Application {
top.window = new PortalWindow(this, top.url, top.timestamp, result => {
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
});
}
},
});
function initEnvironment() {

View File

@@ -1,4 +1,10 @@
const { Clutter, Gio, GLib, Shell } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const CheckBox = imports.ui.checkBox;
const Dialog = imports.ui.dialog;
@@ -15,9 +21,12 @@ var DialogResponse = {
CLOSED: 2
};
var AccessDialog = class extends ModalDialog.ModalDialog {
constructor(invocation, handle, title, subtitle, body, options) {
super({ styleClass: 'access-dialog' });
var AccessDialog = new Lang.Class({
Name: 'AccessDialog',
Extends: ModalDialog.ModalDialog,
_init(invocation, handle, title, subtitle, body, options) {
this.parent({ styleClass: 'access-dialog' });
this._invocation = invocation;
this._handle = handle;
@@ -29,7 +38,7 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
options[option] = options[option].deep_unpack();
this._buildLayout(title, subtitle, body, options);
}
},
_buildLayout(title, subtitle, body, options) {
// No support for non-modal system dialogs, so ignore the option
@@ -69,14 +78,14 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
action: () => {
this._sendResponse(DialogResponse.OK);
}});
}
},
open() {
super.open();
this.parent();
let connection = this._invocation.get_connection();
this._requestExported = this._request.export(connection, this._handle);
}
},
CloseAsync(invocation, params) {
if (this._invocation.get_sender() != invocation.get_sender()) {
@@ -87,7 +96,7 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
}
this._sendResponse(DialogResponse.CLOSED);
}
},
_sendResponse(response) {
if (this._requestExported)
@@ -109,10 +118,12 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
});
this.close();
}
};
});
var AccessDialogDBus = class {
constructor() {
var AccessDialogDBus = new Lang.Class({
Name: 'AccessDialogDBus',
_init() {
this._accessDialog = null;
this._windowTracker = Shell.WindowTracker.get_default();
@@ -121,7 +132,7 @@ var AccessDialogDBus = class {
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/portal/desktop');
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
AccessDialogAsync(params, invocation) {
if (this._accessDialog) {
@@ -149,4 +160,4 @@ var AccessDialogDBus = class {
this._accessDialog = dialog;
}
};
});

View File

@@ -1,7 +1,15 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Atk = imports.gi.Atk;
const Main = imports.ui.main;
const SwitcherPopup = imports.ui.switcherPopup;
@@ -51,10 +59,12 @@ function getWindows(workspace) {
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
}
var AppSwitcherPopup = GObject.registerClass(
class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
var AppSwitcherPopup = new Lang.Class({
Name: 'AppSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init() {
super._init();
this.parent();
this._thumbnails = null;
this._thumbnailTimeoutId = 0;
@@ -69,10 +79,10 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._switcherList = new AppSwitcher(apps, this);
this._items = this._switcherList.icons;
}
},
vfunc_allocate(box, flags) {
super.vfunc_allocate(box, flags);
this.parent(box, flags);
// Allocate the thumbnails
// We try to avoid overflowing the screen so we base the resulting size on
@@ -107,7 +117,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
childBox.y2 = childBox.y1 + childNaturalHeight;
this._thumbnails.allocate(childBox, flags);
}
}
},
_initialSelection(backward, binding) {
if (binding == 'switch-group') {
@@ -130,7 +140,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
} else {
this._select(1);
}
}
},
_nextWindow() {
// We actually want the second window if we're in the unset state
@@ -138,15 +148,14 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._currentWindow = 0;
return SwitcherPopup.mod(this._currentWindow + 1,
this._items[this._selectedIndex].cachedWindows.length);
}
},
_previousWindow() {
// Also assume second window here
if (this._currentWindow == -1)
this._currentWindow = 1;
return SwitcherPopup.mod(this._currentWindow - 1,
this._items[this._selectedIndex].cachedWindows.length);
}
},
_closeAppWindow(appIndex, windowIndex) {
let appIcon = this._items[appIndex];
@@ -158,7 +167,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
return;
window.delete(global.get_current_time());
}
},
_quitApplication(appIndex) {
let appIcon = this._items[appIndex];
@@ -166,7 +175,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
return;
appIcon.app.request_quit();
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
@@ -205,7 +214,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
return Clutter.EVENT_STOP;
}
},
_scrollHandler(direction) {
if (direction == Clutter.ScrollDirection.UP) {
@@ -235,7 +244,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._select(this._next());
}
}
}
},
_itemActivatedHandler(n) {
// If the user clicks on the selected app, activate the
@@ -245,24 +254,24 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._select(n, this._currentWindow);
else
this._select(n);
}
},
_itemEnteredHandler(n) {
this._select(n);
}
},
_windowActivated(thumbnailList, n) {
let appIcon = this._items[this._selectedIndex];
Main.activateWindow(appIcon.cachedWindows[n]);
this.fadeAndDestroy();
}
},
_windowEntered(thumbnailList, n) {
if (!this.mouseActive)
return;
this._select(this._selectedIndex, n);
}
},
_windowRemoved(thumbnailList, n) {
let appIcon = this._items[this._selectedIndex];
@@ -273,7 +282,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
let newIndex = Math.min(n, appIcon.cachedWindows.length - 1);
this._select(this._selectedIndex, newIndex);
}
}
},
_finish(timestamp) {
let appIcon = this._items[this._selectedIndex];
@@ -282,17 +291,17 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
else if (appIcon.cachedWindows[this._currentWindow])
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
super._finish(timestamp);
}
this.parent();
},
_onDestroy() {
super._onDestroy();
this.parent();
if (this._thumbnails)
this._destroyThumbnails();
if (this._thumbnailTimeoutId != 0)
Mainloop.source_remove(this._thumbnailTimeoutId);
}
},
/**
* _select:
@@ -348,7 +357,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._timeoutPopupThumbnails.bind(this));
GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
}
}
},
_timeoutPopupThumbnails() {
if (!this._thumbnails)
@@ -356,7 +365,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._thumbnailTimeoutId = 0;
this._thumbnailsFocused = false;
return GLib.SOURCE_REMOVE;
}
},
_destroyThumbnails() {
let thumbnailsActor = this._thumbnails;
@@ -370,9 +379,9 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
});
this._thumbnails = null;
if (this._switcherList._items[this._selectedIndex])
if (this._switcherList._items[this._selectedIndex])
this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
}
},
_createThumbnails() {
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
@@ -402,8 +411,10 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
});
class CyclerHighlight {
constructor() {
var CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
@@ -423,7 +434,7 @@ class CyclerHighlight {
this.actor.connect('notify::allocation',
this._onAllocationChanged.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
}
},
set window(w) {
if (this._window == w)
@@ -441,7 +452,7 @@ class CyclerHighlight {
windowActor.hide();
this._clone.source = windowActor;
}
},
_onAllocationChanged() {
if (!this._window) {
@@ -454,33 +465,35 @@ class CyclerHighlight {
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
}
},
_onDestroy() {
this.window = null;
}
};
});
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
var CyclerList = GObject.registerClass({
var CyclerList = new Lang.Class({
Name: 'CyclerList',
Extends: St.Widget,
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
'item-entered': { param_types: [GObject.TYPE_INT] },
'item-removed': { param_types: [GObject.TYPE_INT] },
'item-highlighted': { param_types: [GObject.TYPE_INT] } },
}, class CyclerList extends St.Widget {
highlight(index, justOutline) {
this.emit('item-highlighted', index);
}
});
var CyclerPopup = GObject.registerClass(
class CyclerPopup extends SwitcherPopup.SwitcherPopup {
_init() {
if (this.constructor.name === CyclerPopup.prototype.constructor.name)
throw new TypeError(`Cannot instantiate abstract class ${this.constructor.name}`);
var CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
Abstract: true,
super._init();
_init() {
this.parent();
this._items = this._getWindows();
@@ -494,12 +507,12 @@ class CyclerPopup extends SwitcherPopup.SwitcherPopup {
this._switcherList.connect('item-highlighted', (list, index) => {
this._highlightItem(index);
});
}
},
_highlightItem(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
}
},
_finish() {
let window = this._items[this._selectedIndex];
@@ -524,23 +537,25 @@ class CyclerPopup extends SwitcherPopup.SwitcherPopup {
Main.wm.actionMoveWindow(window, ws);
}
super._finish();
}
this.parent();
},
_onDestroy() {
this._highlight.actor.destroy();
super._onDestroy();
this.parent();
}
});
var GroupCyclerPopup = GObject.registerClass(
class GroupCyclerPopup extends CyclerPopup {
var GroupCyclerPopup = new Lang.Class({
Name: 'GroupCyclerPopup',
Extends: CyclerPopup,
_getWindows() {
let app = Shell.WindowTracker.get_default().focus_app;
return app ? app.get_windows() : [];
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
@@ -554,10 +569,12 @@ class GroupCyclerPopup extends CyclerPopup {
}
});
var WindowSwitcherPopup = GObject.registerClass(
class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
var WindowSwitcherPopup = new Lang.Class({
Name: 'WindowSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init() {
super._init();
this.parent();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
let windows = this._getWindowList();
@@ -568,7 +585,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
let mode = this._settings.get_enum('app-icon-mode');
this._switcherList = new WindowList(windows, mode);
this._items = this._switcherList.icons;
}
},
_getWindowList() {
let workspace = null;
@@ -580,7 +597,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
return getWindows(workspace);
}
},
_closeWindow(windowIndex) {
let windowIcon = this._items[windowIndex];
@@ -588,7 +605,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
return;
windowIcon.window.delete(global.get_current_time());
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
@@ -607,21 +624,23 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
return Clutter.EVENT_STOP;
}
},
_finish() {
Main.activateWindow(this._items[this._selectedIndex].window);
super._finish();
this.parent();
}
});
var WindowCyclerPopup = GObject.registerClass(
class WindowCyclerPopup extends CyclerPopup {
var WindowCyclerPopup = new Lang.Class({
Name: 'WindowCyclerPopup',
Extends: CyclerPopup,
_init() {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
super._init();
}
this.parent();
},
_getWindows() {
let workspace = null;
@@ -633,7 +652,7 @@ class WindowCyclerPopup extends CyclerPopup {
}
return getWindows(workspace);
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
@@ -647,10 +666,12 @@ class WindowCyclerPopup extends CyclerPopup {
}
});
var AppIcon = GObject.registerClass(
class AppIcon extends St.BoxLayout {
var AppIcon = new Lang.Class({
Name: 'AppIcon',
Extends: St.BoxLayout,
_init(app) {
super._init({ style_class: 'alt-tab-app',
this.parent({ style_class: 'alt-tab-app',
vertical: true });
this.app = app;
@@ -660,26 +681,28 @@ class AppIcon extends St.BoxLayout {
this.add(this._iconBin, { x_fill: false, y_fill: false } );
this.label = new St.Label({ text: this.app.get_name() });
this.add(this.label, { x_fill: false });
}
},
set_size(size) {
this.icon = this.app.create_icon_texture(size);
this._iconBin.child = this.icon;
this._iconBin.set_size(size, size);
}
},
vfunc_get_preferred_width(forHeight) {
let [minWidth, ] = super.vfunc_get_preferred_width(forHeight);
let [minWidth, ] = this.parent(forHeight);
minWidth = Math.max(minWidth, forHeight);
return [minWidth, minWidth];
}
});
var AppSwitcher = GObject.registerClass(
class AppSwitcher extends SwitcherPopup.SwitcherList {
var AppSwitcher = new Lang.Class({
Name: 'AppSwitcher',
Extends: SwitcherPopup.SwitcherList,
_init(apps, altTabPopup) {
super._init(true);
this.parent(true);
this.icons = [];
this._arrows = [];
@@ -713,7 +736,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this._mouseTimeOutId = 0;
this.connect('destroy', this._onDestroy.bind(this));
}
},
_onDestroy() {
if (this._mouseTimeOutId != 0)
@@ -722,7 +745,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this.icons.forEach(icon => {
icon.app.disconnect(icon._stateChangedId);
});
}
},
_setIconSize() {
let j = 0;
@@ -763,16 +786,16 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
break;
this.icons[i].set_size(iconSize);
}
}
},
vfunc_get_preferred_height(forWidth) {
this._setIconSize();
return super.vfunc_get_preferred_height(forWidth);
}
return this.parent(forWidth);
},
vfunc_allocate(box, flags) {
// Allocate the main list items
super.vfunc_allocate(box, flags);
this.parent(box, flags);
let contentBox = this.get_theme_node().get_content_box(box);
@@ -789,7 +812,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
childBox.y2 = childBox.y1 + arrowHeight;
this._arrows[i].allocate(childBox, flags);
}
}
},
// We override SwitcherList's _onItemEnter method to delay
// activation when the thumbnail list is open
@@ -806,14 +829,14 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
} else
this._itemEntered(index);
}
},
_enterItem(index) {
let [x, y, mask] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
if (this._items[index].contains(pickedActor))
this._itemEntered(index);
}
},
// We override SwitcherList's highlight() method to also deal with
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
@@ -830,7 +853,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
}
super.highlight(n, justOutline);
this.parent(n, justOutline);
this._curApp = n;
if (this._curApp != -1) {
@@ -839,7 +862,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
else
this._arrows[this._curApp].add_style_pseudo_class('highlighted');
}
}
},
_addIcon(appIcon) {
this.icons.push(appIcon);
@@ -860,7 +883,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
arrow.hide();
else
item.add_accessible_state (Atk.StateType.EXPANDABLE);
}
},
_removeIcon(app) {
let index = this.icons.findIndex(icon => {
@@ -871,13 +894,15 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this.icons.splice(index, 1);
this.removeItem(index);
}
},
});
var ThumbnailList = GObject.registerClass(
class ThumbnailList extends SwitcherPopup.SwitcherList {
var ThumbnailList = new Lang.Class({
Name: 'ThumbnailList',
Extends: SwitcherPopup.SwitcherList,
_init(windows) {
super._init(false);
this.parent(false);
this._labels = new Array();
this._thumbnailBins = new Array();
@@ -910,7 +935,7 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
}
this.connect('destroy', this._onDestroy.bind(this));
}
},
addClones(availHeight) {
if (!this._thumbnailBins.length)
@@ -943,7 +968,7 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
// Make sure we only do this once
this._thumbnailBins = new Array();
}
},
_removeThumbnail(source, clone) {
let index = this._clones.indexOf(clone);
@@ -959,20 +984,23 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
this.highlight(SwitcherPopup.mod(index, this._clones.length));
else
this.destroy();
}
},
_onDestroy() {
this._clones.forEach(clone => {
if (clone.source)
clone.source.disconnect(clone._destroyId);
});
}
},
});
var WindowIcon = GObject.registerClass(
class WindowIcon extends St.BoxLayout {
var WindowIcon = new Lang.Class({
Name: 'WindowIcon',
Extends: St.BoxLayout,
_init(window, mode) {
super._init({ style_class: 'alt-tab-app',
this.parent({ style_class: 'alt-tab-app',
vertical: true });
this.window = window;
@@ -1013,7 +1041,7 @@ class WindowIcon extends St.BoxLayout {
}
this._icon.set_size(size * scaleFactor, size * scaleFactor);
}
},
_createAppIcon(app, size) {
let appIcon = app ? app.create_icon_texture(size)
@@ -1026,10 +1054,12 @@ class WindowIcon extends St.BoxLayout {
}
});
var WindowList = GObject.registerClass(
class WindowList extends SwitcherPopup.SwitcherList {
var WindowList = new Lang.Class({
Name: 'WindowList',
Extends: SwitcherPopup.SwitcherList,
_init(windows, mode) {
super._init(true);
this.parent(true);
this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
@@ -1051,16 +1081,16 @@ class WindowList extends SwitcherPopup.SwitcherList {
}
this.connect('destroy', this._onDestroy.bind(this));
}
},
_onDestroy() {
this.icons.forEach(icon => {
icon.window.disconnect(icon._unmanagedSignalId);
});
}
},
vfunc_get_preferred_height(forWidth) {
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [minHeight, natHeight] = this.parent(forWidth);
let spacing = this.get_theme_node().get_padding(St.Side.BOTTOM);
let [labelMin, labelNat] = this._label.get_preferred_height(-1);
@@ -1069,7 +1099,7 @@ class WindowList extends SwitcherPopup.SwitcherList {
natHeight += labelNat + spacing;
return [minHeight, natHeight];
}
},
vfunc_allocate(box, flags) {
let themeNode = this.get_theme_node();
@@ -1087,19 +1117,19 @@ class WindowList extends SwitcherPopup.SwitcherList {
childBox.x2 = box.x2;
childBox.y1 = box.y1;
childBox.y2 = box.y2 - totalLabelHeight;
super.vfunc_allocate(childBox, flags);
this.parent(childBox, flags);
// Hooking up the parent vfunc will call this.set_allocation() with
// the height without the label height, so call it again with the
// correct size here.
this.set_allocation(box, flags);
}
},
highlight(index, justOutline) {
super.highlight(index, justOutline);
this.parent(index, justOutline);
this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
}
},
_removeWindow(window) {
let index = this.icons.findIndex(icon => {

View File

@@ -1,27 +1,20 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { GLib, Gio, St } = imports.gi;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Tweener = imports.ui.tweener;
const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
var SPINNER_ANIMATION_TIME = 0.3;
var SPINNER_ANIMATION_DELAY = 1.0;
var Animation = class {
constructor(file, width, height, speed) {
var Animation = new Lang.Class({
Name: 'Animation',
_init(file, width, height, speed) {
this.actor = new St.Bin();
this.actor.set_size(width, height);
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor.connect('notify::size', this._syncAnimationSize.bind(this));
this.actor.connect('resource-scale-changed',
this._loadFile.bind(this, file, width, height));
let themeContext = St.ThemeContext.get_for_stage(global.stage);
this._scaleChangedId = themeContext.connect('notify::scale-factor',
this._loadFile.bind(this, file, width, height));
this._speed = speed;
this._isLoaded = false;
@@ -29,8 +22,11 @@ var Animation = class {
this._timeoutId = 0;
this._frame = 0;
this._loadFile(file, width, height);
}
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
this._animationsLoaded.bind(this));
this.actor.set_child(this._animations);
},
play() {
if (this._isLoaded && this._timeoutId == 0) {
@@ -42,7 +38,7 @@ var Animation = class {
}
this._isPlaying = true;
}
},
stop() {
if (this._timeoutId > 0) {
@@ -51,24 +47,7 @@ var Animation = class {
}
this._isPlaying = false;
}
_loadFile(file, width, height) {
let [validResourceScale, resourceScale] = this.actor.get_resource_scale();
this._isLoaded = false;
this.actor.destroy_all_children();
if (!validResourceScale)
return;
let texture_cache = St.TextureCache.get_default();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = texture_cache.load_sliced_image(file, width, height,
scaleFactor, resourceScale,
this._animationsLoaded.bind(this));
this.actor.set_child(this._animations);
}
},
_showFrame(frame) {
let oldFrameActor = this._animations.get_child_at_index(this._frame);
@@ -80,94 +59,30 @@ var Animation = class {
let newFrameActor = this._animations.get_child_at_index(this._frame);
if (newFrameActor)
newFrameActor.show();
}
},
_update() {
this._showFrame(this._frame + 1);
return GLib.SOURCE_CONTINUE;
}
_syncAnimationSize() {
if (!this._isLoaded)
return;
let [width, height] = this.actor.get_size();
for (let i = 0; i < this._animations.get_n_children(); ++i)
this._animations.get_child_at_index(i).set_size(width, height);
}
},
_animationsLoaded() {
this._isLoaded = this._animations.get_n_children() > 0;
this._syncAnimationSize();
if (this._isPlaying)
this.play();
}
},
_onDestroy() {
this.stop();
let themeContext = St.ThemeContext.get_for_stage(global.stage);
if (this._scaleChangedId)
themeContext.disconnect(this._scaleChangedId);
this._scaleChangedId = 0;
}
};
});
var AnimatedIcon = class extends Animation {
constructor(file, size) {
super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
var AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init(file, size) {
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
};
var Spinner = class extends AnimatedIcon {
constructor(size, animate=false) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
super(file, size);
this.actor.opacity = 0;
this._animate = animate;
}
_onDestroy() {
this._animate = false;
super._onDestroy();
}
play() {
Tweener.removeTweens(this.actor);
if (this._animate) {
super.play();
Tweener.addTween(this.actor, {
opacity: 255,
delay: SPINNER_ANIMATION_DELAY,
time: SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
this.actor.opacity = 255;
super.play();
}
}
stop() {
Tweener.removeTweens(this.actor);
if (this._animate) {
Tweener.addTween(this.actor, {
opacity: 0,
time: SPINNER_ANIMATION_TIME,
transition: 'linear',
onComplete: () => {
this.stop(false);
}
});
} else {
this.actor.opacity = 0;
super.stop();
}
}
};
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Signals = imports.signals;
const Main = imports.ui.main;
@@ -14,63 +15,53 @@ const RENAMED_DESKTOP_IDS = {
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
'evolution.desktop': 'org.gnome.Evolution.desktop',
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
'five-or-more.desktop': 'org.gnome.five-or-more.desktop',
'four-in-a-row.desktop': 'org.gnome.Four-in-a-row.desktop',
'gcalctool.desktop': 'org.gnome.Calculator.desktop',
'geary.desktop': 'org.gnome.Geary.desktop',
'gedit.desktop': 'org.gnome.gedit.desktop',
'glchess.desktop': 'org.gnome.Chess.desktop',
'glines.desktop': 'org.gnome.five-or-more.desktop',
'gnect.desktop': 'org.gnome.Four-in-a-row.desktop',
'glchess.desktop': 'gnome-chess.desktop',
'glines.desktop': 'five-or-more.desktop',
'gnect.desktop': 'four-in-a-row.desktop',
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnobots2.desktop': 'org.gnome.Robots.desktop',
'gnobots2.desktop': 'gnome-robots.desktop',
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
'gnome-calculator.desktop': 'org.gnome.Calculator.desktop',
'gnome-chess.desktop': 'org.gnome.Chess.desktop',
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
'gnome-klotski.desktop': 'org.gnome.Klotski.desktop',
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnome-mahjongg.desktop': 'org.gnome.Mahjongg.desktop',
'gnome-mines.desktop': 'org.gnome.Mines.desktop',
'gnome-music.desktop': 'org.gnome.Music.desktop',
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
'gnome-robots.desktop': 'org.gnome.Robots.desktop',
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
'gnome-software.desktop': 'org.gnome.Software.desktop',
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
'gnome-tetravex.desktop': 'org.gnome.Tetravex.desktop',
'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.desktop',
'gnomine.desktop': 'org.gnome.Mines.desktop',
'gnotravex.desktop': 'org.gnome.Tetravex.desktop',
'gnotski.desktop': 'org.gnome.Klotski.desktop',
'gtali.desktop': 'org.gnome.Tali.desktop',
'iagno.desktop': 'org.gnome.Reversi.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
'gnomine.desktop': 'gnome-mines.desktop',
'gnotravex.desktop': 'gnome-tetravex.desktop',
'gnotski.desktop': 'gnome-klotski.desktop',
'gtali.desktop': 'tali.desktop',
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
'org.gnome.gnome-2048.desktop': 'org.gnome.TwentyFortyEight.desktop',
'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop',
'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
'polari.desktop': 'org.gnome.Polari.desktop',
'tali.desktop': 'org.gnome.Tali.desktop',
'totem.desktop': 'org.gnome.Totem.desktop',
'evince.desktop': 'org.gnome.Evince.desktop',
};
class AppFavorites {
constructor() {
this.FAVORITE_APPS_KEY = 'favorite-apps';
var AppFavorites = new Lang.Class({
Name: 'AppFavorites',
FAVORITE_APPS_KEY: 'favorite-apps',
_init() {
this._favorites = {};
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, this._onFavsChanged.bind(this));
this.reload();
}
},
_onFavsChanged() {
this.reload();
this.emit('changed');
}
},
reload() {
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
@@ -98,29 +89,29 @@ class AppFavorites {
let app = apps[i];
this._favorites[app.get_id()] = app;
}
}
},
_getIds() {
let ret = [];
for (let id in this._favorites)
ret.push(id);
return ret;
}
},
getFavoriteMap() {
return this._favorites;
}
},
getFavorites() {
let ret = [];
for (let id in this._favorites)
ret.push(this._favorites[id]);
return ret;
}
},
isFavorite(appId) {
return appId in this._favorites;
}
},
_addFavorite(appId, pos) {
if (appId in this._favorites)
@@ -138,7 +129,7 @@ class AppFavorites {
ids.splice(pos, 0, appId);
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
return true;
}
},
addFavoriteAtPos(appId, pos) {
if (!this._addFavorite(appId, pos))
@@ -152,25 +143,25 @@ class AppFavorites {
this._removeFavorite(appId);
}
});
}
},
addFavorite(appId) {
this.addFavoriteAtPos(appId, -1);
}
},
moveFavoriteToPos(appId, pos) {
this._removeFavorite(appId);
this._addFavorite(appId, pos);
}
},
_removeFavorite(appId) {
if (!(appId in this._favorites))
if (!appId in this._favorites)
return false;
let ids = this._getIds().filter(id => id != appId);
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
return true;
}
},
removeFavorite(appId) {
let ids = this._getIds();
@@ -187,7 +178,7 @@ class AppFavorites {
}
});
}
};
});
Signals.addSignalMethods(AppFavorites.prototype);
var appFavoritesInstance = null;

View File

@@ -1,4 +1,10 @@
const { Clutter, Gio, GLib, Meta, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
@@ -13,10 +19,12 @@ var AudioDevice = {
const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection');
var AudioDeviceSelectionDialog =
class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
constructor(devices) {
super({ styleClass: 'audio-device-selection-dialog' });
var AudioDeviceSelectionDialog = new Lang.Class({
Name: 'AudioDeviceSelectionDialog',
Extends: ModalDialog.ModalDialog,
_init(devices) {
this.parent({ styleClass: 'audio-device-selection-dialog' });
this._deviceItems = {};
@@ -31,11 +39,11 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
if (this._selectionBox.get_n_children() < 2)
throw new Error('Too few devices for a selection');
}
},
destroy() {
super.destroy();
}
this.parent();
},
_buildLayout(devices) {
let title = new St.Label({ style_class: 'audio-selection-title',
@@ -48,13 +56,12 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
this.contentLayout.add(this._selectionBox, { expand: true });
if (Main.sessionMode.allowSettings)
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
this.addButton({ action: this.close.bind(this),
label: _("Cancel"),
key: Clutter.Escape });
}
},
_getDeviceLabel(device) {
switch(device) {
@@ -67,7 +74,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
default:
return null;
}
}
},
_getDeviceIcon(device) {
switch(device) {
@@ -80,7 +87,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
default:
return null;
}
}
},
_addDevice(device) {
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
@@ -110,7 +117,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
this.close();
Main.overview.hide();
});
}
},
_openSettings() {
let desktopFile = 'gnome-sound-panel.desktop'
@@ -125,21 +132,23 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
Main.overview.hide();
app.activate();
}
};
});
var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
constructor() {
var AudioDeviceSelectionDBus = new Lang.Class({
Name: 'AudioDeviceSelectionDBus',
_init() {
this._audioSelectionDialog = null;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
_onDialogClosed() {
this._audioSelectionDialog = null;
}
},
_onDeviceSelected(dialog, device) {
let connection = this._dbusImpl.get_connection();
@@ -152,7 +161,7 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
info ? info.name : null,
'DeviceSelected',
GLib.Variant.new('(s)', [deviceName]));
}
},
OpenAsync(params, invocation) {
if (this._audioSelectionDialog) {
@@ -180,7 +189,7 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
this._audioSelectionDialog = dialog;
invocation.return_value(null);
}
},
CloseAsync(params, invocation) {
if (this._audioSelectionDialog &&
@@ -189,4 +198,4 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
invocation.return_value(null);
}
};
});

View File

@@ -93,7 +93,13 @@
// MetaBackgroundImage MetaBackgroundImage
// MetaBackgroundImage MetaBackgroundImage
const { Clutter, GDesktopEnums, Gio, GLib, GnomeDesktop, Meta } = imports.gi;
const Clutter = imports.gi.Clutter;
const GDesktopEnums = imports.gi.GDesktopEnums;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const LoginManager = imports.misc.loginManager;
@@ -132,12 +138,14 @@ function _fileEqual0(file1, file2) {
return file1.equal(file2);
}
var BackgroundCache = class BackgroundCache {
constructor() {
var BackgroundCache = new Lang.Class({
Name: 'BackgroundCache',
_init() {
this._fileMonitors = {};
this._backgroundSources = {};
this._animations = {};
}
},
monitorFile(file) {
let key = file.hash();
@@ -155,7 +163,7 @@ var BackgroundCache = class BackgroundCache {
});
this._fileMonitors[key] = monitor;
}
},
getAnimation(params) {
params = Params.parse(params, { file: null,
@@ -187,7 +195,7 @@ var BackgroundCache = class BackgroundCache {
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
}
});
}
},
getBackgroundSource(layoutManager, settingsSchema) {
// The layoutManager is always the same one; we pass in it since
@@ -201,7 +209,7 @@ var BackgroundCache = class BackgroundCache {
}
return this._backgroundSources[settingsSchema];
}
},
releaseBackgroundSource(settingsSchema) {
if (settingsSchema in this._backgroundSources) {
@@ -213,7 +221,7 @@ var BackgroundCache = class BackgroundCache {
}
}
}
};
});
Signals.addSignalMethods(BackgroundCache.prototype);
function getBackgroundCache() {
@@ -222,8 +230,10 @@ function getBackgroundCache() {
return _backgroundCache;
}
var Background = class Background {
constructor(params) {
var Background = new Lang.Class({
Name: 'Background',
_init(params) {
params = Params.parse(params, { monitorIndex: 0,
layoutManager: Main.layoutManager,
settings: null,
@@ -262,7 +272,7 @@ var Background = class Background {
});
this._load();
}
},
destroy() {
this._cancellable.cancel();
@@ -288,12 +298,12 @@ var Background = class Background {
if (this._settingsChangedSignalId != 0)
this._settings.disconnect(this._settingsChangedSignalId);
this._settingsChangedSignalId = 0;
}
},
updateResolution() {
if (this._animation)
this._refreshAnimation();
}
},
_refreshAnimation() {
if (!this._animation)
@@ -301,7 +311,7 @@ var Background = class Background {
this._removeAnimationTimeout();
this._updateAnimation();
}
},
_setLoaded() {
if (this.isLoaded)
@@ -314,7 +324,7 @@ var Background = class Background {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
}
},
_loadPattern() {
let colorString, res, color, secondColor;
@@ -330,7 +340,7 @@ var Background = class Background {
this.background.set_color(color);
else
this.background.set_gradient(shadingType, color, secondColor);
}
},
_watchFile(file) {
let key = file.hash();
@@ -347,14 +357,14 @@ var Background = class Background {
}
});
this._fileWatches[key] = signalId;
}
},
_removeAnimationTimeout() {
if (this._updateAnimationTimeoutId) {
GLib.source_remove(this._updateAnimationTimeoutId);
this._updateAnimationTimeoutId = 0;
}
}
},
_updateAnimation() {
this._updateAnimationTimeoutId = 0;
@@ -394,7 +404,7 @@ var Background = class Background {
});
}
}
}
},
_queueUpdateAnimation() {
if (this._updateAnimationTimeoutId != 0)
@@ -423,7 +433,7 @@ var Background = class Background {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
}
},
_loadAnimation(file) {
this._cache.getAnimation({ file: file,
@@ -440,7 +450,7 @@ var Background = class Background {
this._watchFile(file);
}
});
}
},
_loadImage(file) {
this.background.set_file(file, this._style);
@@ -456,14 +466,14 @@ var Background = class Background {
image.disconnect(id);
});
}
}
},
_loadFile(file) {
if (file.get_basename().endsWith('.xml'))
this._loadAnimation(file);
else
this._loadImage(file);
}
},
_load() {
this._cache = getBackgroundCache();
@@ -476,14 +486,16 @@ var Background = class Background {
}
this._loadFile(this._file);
}
};
},
});
Signals.addSignalMethods(Background.prototype);
let _systemBackground;
var SystemBackground = class SystemBackground {
constructor() {
var SystemBackground = new Lang.Class({
Name: 'SystemBackground',
_init() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
@@ -512,12 +524,14 @@ var SystemBackground = class SystemBackground {
image = null;
});
}
}
};
},
});
Signals.addSignalMethods(SystemBackground.prototype);
var BackgroundSource = class BackgroundSource {
constructor(layoutManager, settingsSchema) {
var BackgroundSource = new Lang.Class({
Name: 'BackgroundSource',
_init(layoutManager, settingsSchema) {
// Allow override the background image setting for performance testing
this._layoutManager = layoutManager;
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
@@ -528,7 +542,7 @@ var BackgroundSource = class BackgroundSource {
this._monitorsChangedId =
monitorManager.connect('monitors-changed',
this._onMonitorsChanged.bind(this));
}
},
_onMonitorsChanged() {
for (let monitorIndex in this._backgrounds) {
@@ -542,7 +556,7 @@ var BackgroundSource = class BackgroundSource {
delete this._backgrounds[monitorIndex];
}
}
}
},
getBackground(monitorIndex) {
let file = null;
@@ -589,7 +603,7 @@ var BackgroundSource = class BackgroundSource {
}
return this._backgrounds[monitorIndex];
}
},
destroy() {
let monitorManager = Meta.MonitorManager.get();
@@ -603,10 +617,12 @@ var BackgroundSource = class BackgroundSource {
this._backgrounds = null;
}
};
});
var Animation = class Animation {
constructor(params) {
var Animation = new Lang.Class({
Name: 'Animation',
_init(params) {
params = Params.parse(params, { file: null });
this.file = params.file;
@@ -614,7 +630,7 @@ var Animation = class Animation {
this.transitionProgress = 0.0;
this.transitionDuration = 0.0;
this.loaded = false;
}
},
load(callback) {
this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
@@ -624,7 +640,7 @@ var Animation = class Animation {
if (callback)
callback();
});
}
},
update(monitor) {
this.keyFrameFiles = [];
@@ -645,12 +661,14 @@ var Animation = class Animation {
if (filename2)
this.keyFrameFiles.push(Gio.File.new_for_path(filename2));
}
};
},
});
Signals.addSignalMethods(Animation.prototype);
var BackgroundManager = class BackgroundManager {
constructor(params) {
var BackgroundManager = new Lang.Class({
Name: 'BackgroundManager',
_init(params) {
params = Params.parse(params, { container: null,
layoutManager: Main.layoutManager,
monitorIndex: null,
@@ -670,7 +688,7 @@ var BackgroundManager = class BackgroundManager {
this.backgroundActor = this._createBackgroundActor();
this._newBackgroundActor = null;
}
},
destroy() {
let cache = getBackgroundCache();
@@ -686,7 +704,7 @@ var BackgroundManager = class BackgroundManager {
this.backgroundActor.destroy();
this.backgroundActor = null;
}
}
},
_swapBackgroundActor() {
let oldBackgroundActor = this.backgroundActor;
@@ -703,7 +721,7 @@ var BackgroundManager = class BackgroundManager {
oldBackgroundActor.destroy();
}
});
}
},
_updateBackgroundActor() {
if (this._newBackgroundActor) {
@@ -732,7 +750,7 @@ var BackgroundManager = class BackgroundManager {
this._swapBackgroundActor();
});
}
}
},
_createBackgroundActor() {
let background = this._backgroundSource.getBackground(this._monitorIndex);
@@ -746,8 +764,10 @@ var BackgroundManager = class BackgroundManager {
this._container.add_child(backgroundActor);
let monitor = this._layoutManager.monitors[this._monitorIndex];
backgroundActor.set_size(monitor.width, monitor.height);
if (this._controlPosition) {
let monitor = this._layoutManager.monitors[this._monitorIndex];
backgroundActor.set_position(monitor.x, monitor.y);
backgroundActor.lower_bottom();
}
@@ -767,6 +787,6 @@ var BackgroundManager = class BackgroundManager {
});
return backgroundActor;
}
};
},
});
Signals.addSignalMethods(BackgroundManager.prototype);

View File

@@ -1,14 +1,20 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
constructor(layoutManager) {
super(layoutManager.dummyCursor, 0, St.Side.TOP);
var BackgroundMenu = new Lang.Class({
Name: 'BackgroundMenu',
Extends: PopupMenu.PopupMenu,
_init(layoutManager) {
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -20,12 +26,12 @@ var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
layoutManager.uiGroup.add_actor(this.actor);
this.actor.hide();
}
};
});
function addBackgroundMenu(actor, layoutManager) {
actor.reactive = true;
actor._backgroundMenu = new BackgroundMenu(layoutManager);
actor._backgroundManager = new PopupMenu.PopupMenuManager(actor);
actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor });
actor._backgroundManager.addMenu(actor._backgroundMenu);
function openMenu(x, y) {

View File

@@ -1,10 +1,16 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const { Atk, Clutter, St } = imports.gi;
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
var BarLevel = class {
constructor(value, params) {
var BarLevel = new Lang.Class({
Name: "BarLevel",
_init(value, params) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The bar level value must be a number');
@@ -34,7 +40,7 @@ var BarLevel = class {
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
}
},
setValue(value) {
if (isNaN(value))
@@ -42,7 +48,7 @@ var BarLevel = class {
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
}
},
setMaximumValue(value) {
if (isNaN(value))
@@ -51,7 +57,7 @@ var BarLevel = class {
this._maxValue = Math.max(value, 1);
this._overdriveStart = Math.min(this._overdriveStart, this._maxValue);
this.actor.queue_repaint();
}
},
setOverdriveStart(value) {
if (isNaN(value))
@@ -63,7 +69,7 @@ var BarLevel = class {
this._overdriveStart = value;
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
}
},
_barLevelRepaint(area) {
let cr = area.get_context();
@@ -121,8 +127,7 @@ var BarLevel = class {
cr.lineTo(x, (height - barLevelHeight) / 2);
cr.lineTo(x, (height + barLevelHeight) / 2);
cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2);
if (this._value > 0)
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor);
cr.setLineWidth(barLevelBorderWidth);
@@ -144,19 +149,17 @@ var BarLevel = class {
}
/* end progress bar arc */
if (this._value > 0) {
if (this._value <= this._overdriveStart)
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
else
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.fillPreserve();
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
}
if (this._value <= this._overdriveStart)
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
else
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.fillPreserve();
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
/* draw overdrive separator */
if (overdriveActive) {
@@ -173,34 +176,35 @@ var BarLevel = class {
}
cr.$dispose();
}
},
_getCurrentValue(actor) {
return this._value;
}
},
_getOverdriveStart(actor) {
return this._overdriveStart;
}
},
_getMinimumValue(actor) {
return 0;
}
},
_getMaximumValue(actor) {
return this._maxValue;
}
},
_setCurrentValue(actor, value) {
this._value = value;
}
},
_valueChanged(barLevel, value, property) {
this._customAccessible.notify("accessible-value");
}
},
get value() {
return this._value;
}
};
});
Signals.addSignalMethods(BarLevel.prototype);

View File

@@ -1,6 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GObject, Meta, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
@@ -24,14 +29,18 @@ var POPUP_ANIMATION_TIME = 0.15;
* placed. The arrow position may be controlled via
* setArrowOrigin(). The arrow side might be temporarily flipped
* depending on the box size and source position to keep the box
* totally inside the monitor workarea if possible.
* totally inside the monitor if possible.
*
*/
var BoxPointer = GObject.registerClass({
var BoxPointer = new Lang.Class({
Name: 'BoxPointer',
Extends: St.Widget,
Signals: { 'arrow-side-changed': {} },
}, class BoxPointer extends St.Widget {
_init(arrowSide, binProperties) {
super._init();
this.parent();
this.actor = this;
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
@@ -45,27 +54,31 @@ var BoxPointer = GObject.registerClass({
this._border.connect('repaint', this._drawBorder.bind(this));
this.add_actor(this._border);
this.bin.raise(this._border);
this._xOffset = 0;
this._yOffset = 0;
this._xPosition = 0;
this._yPosition = 0;
this._sourceAlignment = 0.5;
this._capturedEventId = 0;
this._muteInput();
}
},
get arrowSide() {
return this._arrowSide;
}
},
_muteInput() {
if (this._capturedEventId == 0)
this._capturedEventId = this.connect('captured-event',
() => Clutter.EVENT_STOP);
}
},
_unmuteInput() {
if (this._capturedEventId != 0) {
this.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
}
},
// BoxPointer.show() and BoxPointer.hide() are here for only compatibility
// purposes, and will be removed in 3.32.
@@ -81,7 +94,7 @@ var BoxPointer = GObject.registerClass({
}
this.visible = true;
}
},
hide(animate, onComplete) {
if (animate !== undefined) {
@@ -95,7 +108,7 @@ var BoxPointer = GObject.registerClass({
}
this.visible = false;
}
},
open(animate, onComplete) {
let themeNode = this.get_theme_node();
@@ -112,23 +125,23 @@ var BoxPointer = GObject.registerClass({
if (animate & PopupAnimation.SLIDE) {
switch (this._arrowSide) {
case St.Side.TOP:
this.translation_y = -rise;
this.yOffset = -rise;
break;
case St.Side.BOTTOM:
this.translation_y = rise;
this.yOffset = rise;
break;
case St.Side.LEFT:
this.translation_x = -rise;
this.xOffset = -rise;
break;
case St.Side.RIGHT:
this.translation_x = rise;
this.xOffset = rise;
break;
}
}
Tweener.addTween(this, { opacity: 255,
translation_x: 0,
translation_y: 0,
xOffset: 0,
yOffset: 0,
transition: 'linear',
onComplete: () => {
this._unmuteInput();
@@ -136,14 +149,14 @@ var BoxPointer = GObject.registerClass({
onComplete();
},
time: animationTime });
}
},
close(animate, onComplete) {
if (!this.visible)
return;
let translationX = 0;
let translationY = 0;
let xOffset = 0;
let yOffset = 0;
let themeNode = this.get_theme_node();
let rise = themeNode.get_length('-arrow-rise');
let fade = (animate & PopupAnimation.FADE);
@@ -152,16 +165,16 @@ var BoxPointer = GObject.registerClass({
if (animate & PopupAnimation.SLIDE) {
switch (this._arrowSide) {
case St.Side.TOP:
translationY = rise;
yOffset = rise;
break;
case St.Side.BOTTOM:
translationY = -rise;
yOffset = -rise;
break;
case St.Side.LEFT:
translationX = rise;
xOffset = rise;
break;
case St.Side.RIGHT:
translationX = -rise;
xOffset = -rise;
break;
}
}
@@ -170,20 +183,20 @@ var BoxPointer = GObject.registerClass({
Tweener.removeTweens(this);
Tweener.addTween(this, { opacity: fade ? 0 : 255,
translation_x: translationX,
translation_y: translationY,
xOffset: xOffset,
yOffset: yOffset,
transition: 'linear',
time: animationTime,
onComplete: () => {
this.hide();
this.opacity = 0;
this.translation_x = 0;
this.translation_y = 0;
this.xOffset = 0;
this.yOffset = 0;
if (onComplete)
onComplete();
}
});
}
},
_adjustAllocationForArrow(isWidth, minSize, natSize) {
let themeNode = this.get_theme_node();
@@ -198,7 +211,7 @@ var BoxPointer = GObject.registerClass({
}
return [minSize, natSize];
}
},
vfunc_get_preferred_width(forHeight) {
let themeNode = this.get_theme_node();
@@ -208,7 +221,7 @@ var BoxPointer = GObject.registerClass({
width = this._adjustAllocationForArrow(true, ...width);
return themeNode.adjust_preferred_width(...width);
}
},
vfunc_get_preferred_height(forWidth) {
let themeNode = this.get_theme_node();
@@ -219,7 +232,7 @@ var BoxPointer = GObject.registerClass({
height = this._adjustAllocationForArrow(false, ...height);
return themeNode.adjust_preferred_height(...height);
}
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
@@ -263,7 +276,7 @@ var BoxPointer = GObject.registerClass({
this._reposition();
this._updateFlip();
}
}
},
_drawBorder(area) {
let themeNode = this.get_theme_node();
@@ -445,7 +458,7 @@ var BoxPointer = GObject.registerClass({
}
cr.$dispose();
}
},
setPosition(sourceActor, alignment) {
// We need to show it now to force an allocation,
@@ -457,7 +470,7 @@ var BoxPointer = GObject.registerClass({
this._reposition();
this._updateFlip();
}
},
setSourceAlignment(alignment) {
this._sourceAlignment = alignment;
@@ -466,20 +479,16 @@ var BoxPointer = GObject.registerClass({
return;
this.setPosition(this._sourceActor, this._arrowAlignment);
}
},
_reposition() {
let sourceActor = this._sourceActor;
let alignment = this._arrowAlignment;
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
// Position correctly relative to the sourceActor
let sourceNode = sourceActor.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
let sourceAllocation = this._sourceAllocation;
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let [minWidth, minHeight, natWidth, natHeight] = this.get_preferred_size();
@@ -487,7 +496,7 @@ var BoxPointer = GObject.registerClass({
// We also want to keep it onscreen, and separated from the
// edge by the same distance as the main part of the box is
// separated from its sourceActor
let workarea = this._workArea;
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
let themeNode = this.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let arrowBase = themeNode.get_length('-arrow-base');
@@ -537,8 +546,8 @@ var BoxPointer = GObject.registerClass({
case St.Side.BOTTOM:
resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment);
resX = Math.max(resX, workarea.x + padding);
resX = Math.min(resX, workarea.x + workarea.width - (padding + natWidth));
resX = Math.max(resX, monitor.x + padding);
resX = Math.min(resX, monitor.x + monitor.width - (padding + natWidth));
arrowOrigin = sourceCenterX - resX;
if (arrowOrigin <= (x1 + (borderRadius + halfBase))) {
@@ -556,8 +565,8 @@ var BoxPointer = GObject.registerClass({
case St.Side.RIGHT:
resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment);
resY = Math.max(resY, workarea.y + padding);
resY = Math.min(resY, workarea.y + workarea.height - (padding + natHeight));
resY = Math.max(resY, monitor.y + padding);
resY = Math.min(resY, monitor.y + monitor.height - (padding + natHeight));
arrowOrigin = sourceCenterY - resY;
if (arrowOrigin <= (y1 + (borderRadius + halfBase))) {
@@ -581,10 +590,10 @@ var BoxPointer = GObject.registerClass({
parent = parent.get_parent();
}
// Actually set the position
this.x = Math.floor(x);
this.y = Math.floor(y);
}
this._xPosition = Math.floor(x);
this._yPosition = Math.floor(y);
this._shiftActor();
},
// @origin: Coordinate specifying middle of the arrow, along
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
@@ -594,7 +603,7 @@ var BoxPointer = GObject.registerClass({
this._arrowOrigin = origin;
this._border.queue_repaint();
}
}
},
// @actor: an actor relative to which the arrow is positioned.
// Differently from setPosition, this will not move the boxpointer itself,
@@ -604,38 +613,52 @@ var BoxPointer = GObject.registerClass({
this._arrowActor = actor;
this._border.queue_repaint();
}
}
},
_shiftActor() {
// Since the position of the BoxPointer depends on the allocated size
// of the BoxPointer and the position of the source actor, trying
// to position the BoxPointer via the x/y properties will result in
// allocation loops and warnings. Instead we do the positioning via
// the anchor point, which is independent of allocation, and leave
// x == y == 0.
this.set_anchor_point(-(this._xPosition + this._xOffset),
-(this._yPosition + this._yOffset));
},
_calculateArrowSide(arrowSide) {
let sourceAllocation = this._sourceAllocation;
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
let [minWidth, minHeight, boxWidth, boxHeight] = this.get_preferred_size();
let workarea = this._workArea;
let monitorActor = this.sourceActor;
if (!monitorActor)
monitorActor = this;
let monitor = Main.layoutManager.findMonitorForActor(monitorActor);
switch (arrowSide) {
case St.Side.TOP:
if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height &&
boxHeight < sourceAllocation.y1 - workarea.y)
if (sourceAllocation.y2 + boxHeight > monitor.y + monitor.height &&
boxHeight < sourceAllocation.y1 - monitor.y)
return St.Side.BOTTOM;
break;
case St.Side.BOTTOM:
if (sourceAllocation.y1 - boxHeight < workarea.y &&
boxHeight < workarea.y + workarea.height - sourceAllocation.y2)
if (sourceAllocation.y1 - boxHeight < monitor.y &&
boxHeight < monitor.y + monitor.height - sourceAllocation.y2)
return St.Side.TOP;
break;
case St.Side.LEFT:
if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width &&
boxWidth < sourceAllocation.x1 - workarea.x)
if (sourceAllocation.x2 + boxWidth > monitor.x + monitor.width &&
boxWidth < sourceAllocation.x1 - monitor.x)
return St.Side.RIGHT;
break;
case St.Side.RIGHT:
if (sourceAllocation.x1 - boxWidth < workarea.x &&
boxWidth < workarea.x + workarea.width - sourceAllocation.x2)
if (sourceAllocation.x1 - boxWidth < monitor.x &&
boxWidth < monitor.x + monitor.width - sourceAllocation.x2)
return St.Side.LEFT;
break;
}
return arrowSide;
}
},
_updateFlip() {
let arrowSide = this._calculateArrowSide(this._userArrowSide);
@@ -649,18 +672,36 @@ var BoxPointer = GObject.registerClass({
this.emit('arrow-side-changed');
}
}
},
set xOffset(offset) {
this._xOffset = offset;
this._shiftActor();
},
get xOffset() {
return this._xOffset;
},
set yOffset(offset) {
this._yOffset = offset;
this._shiftActor();
},
get yOffset() {
return this._yOffset;
},
updateArrowSide(side) {
this._arrowSide = side;
this._border.queue_repaint();
this.emit('arrow-side-changed');
}
},
getPadding(side) {
return this.bin.get_theme_node().get_padding(side);
}
},
getArrowHeight() {
return this.get_theme_node().get_length('-arrow-rise');

View File

@@ -1,7 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const MessageList = imports.ui.messageList;
@@ -9,8 +15,6 @@ const MessageTray = imports.ui.messageTray;
const Mpris = imports.ui.mpris;
const Util = imports.misc.util;
const { loadInterfaceXML } = imports.misc.fileUtils;
var MSECS_IN_DAY = 24 * 60 * 60 * 1000;
var SHOW_WEEKDATE_KEY = 'show-weekdate';
var ELLIPSIS_CHAR = '\u2026';
@@ -85,45 +89,64 @@ function _getCalendarDayAbbreviation(dayNumber) {
// Abstraction for an appointment/event in a calendar
var CalendarEvent = class CalendarEvent {
constructor(id, date, end, summary, allDay) {
var CalendarEvent = new Lang.Class({
Name: 'CalendarEvent',
_init(id, date, end, summary, allDay) {
this.id = id;
this.date = date;
this.end = end;
this.summary = summary;
this.allDay = allDay;
}
};
});
// Interface for appointments/events - e.g. the contents of a calendar
//
// First, an implementation with no events
var EmptyEventSource = class EmptyEventSource {
constructor() {
var EmptyEventSource = new Lang.Class({
Name: 'EmptyEventSource',
_init() {
this.isLoading = false;
this.isDummy = true;
this.hasCalendars = false;
}
},
destroy() {
}
},
ignoreEvent(event) {
},
requestRange(begin, end) {
}
},
getEvents(begin, end) {
let result = [];
return result;
}
},
hasEvents(day) {
return false;
}
};
});
Signals.addSignalMethods(EmptyEventSource.prototype);
const CalendarServerIface = loadInterfaceXML('org.gnome.Shell.CalendarServer');
const CalendarServerIface = `
<node>
<interface name="org.gnome.Shell.CalendarServer">
<method name="GetEvents">
<arg type="x" direction="in" />
<arg type="x" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sssbxxa{sv})" direction="out" />
</method>
<property name="HasCalendars" type="b" access="read" />
<signal name="Changed" />
</interface>
</node>`;
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface);
@@ -154,12 +177,22 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
}
// an implementation that reads data from a session bus service
var DBusEventSource = class DBusEventSource {
constructor() {
var DBusEventSource = new Lang.Class({
Name: 'DBusEventSource',
_init() {
this._resetCache();
this.isLoading = false;
this.isDummy = false;
this._ignoredEvents = new Map();
let savedState = global.get_persistent_state('as', 'ignored_events');
if (savedState)
savedState.deep_unpack().forEach(eventId => {
this._ignoredEvents.set(eventId, true);
});
this._initialized = false;
this._dbusProxy = new CalendarServer();
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => {
@@ -202,39 +235,39 @@ var DBusEventSource = class DBusEventSource {
this._onNameAppeared();
}
});
}
},
destroy() {
this._dbusProxy.run_dispose();
}
},
get hasCalendars() {
if (this._initialized)
return this._dbusProxy.HasCalendars;
else
return false;
}
},
_resetCache() {
this._events = [];
this._lastRequestBegin = null;
this._lastRequestEnd = null;
}
},
_onNameAppeared(owner) {
this._initialized = true;
this._resetCache();
this._loadEvents(true);
}
},
_onNameVanished(oldOwner) {
this._resetCache();
this.emit('changed');
}
},
_onChanged() {
this._loadEvents(false);
}
},
_onEventsReceived(results, error) {
let newEvents = [];
@@ -256,7 +289,7 @@ var DBusEventSource = class DBusEventSource {
this._events = newEvents;
this.isLoading = false;
this.emit('changed');
}
},
_loadEvents(forceReload) {
// Ignore while loading
@@ -270,7 +303,17 @@ var DBusEventSource = class DBusEventSource {
this._onEventsReceived.bind(this),
Gio.DBusCallFlags.NONE);
}
}
},
ignoreEvent(event) {
if (this._ignoredEvents.get(event.id))
return;
this._ignoredEvents.set(event.id, true);
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
global.set_persistent_state('ignored_events', savedState);
this.emit('changed');
},
requestRange(begin, end) {
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
@@ -281,13 +324,16 @@ var DBusEventSource = class DBusEventSource {
this._curRequestEnd = end;
this._loadEvents(false);
}
}
},
getEvents(begin, end) {
let result = [];
for(let n = 0; n < this._events.length; n++) {
let event = this._events[n];
if (this._ignoredEvents.has(event.id))
continue;
if (_dateIntervalsOverlap (event.date, event.end, begin, end)) {
result.push(event);
}
@@ -299,7 +345,7 @@ var DBusEventSource = class DBusEventSource {
return d1.getTime() - d2.getTime();
});
return result;
}
},
hasEvents(day) {
let dayBegin = _getBeginningOfDay(day);
@@ -312,11 +358,13 @@ var DBusEventSource = class DBusEventSource {
return true;
}
};
});
Signals.addSignalMethods(DBusEventSource.prototype);
var Calendar = class Calendar {
constructor() {
var Calendar = new Lang.Class({
Name: 'Calendar',
_init() {
this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
@@ -354,7 +402,7 @@ var Calendar = class Calendar {
this._onScroll.bind(this));
this._buildHeader ();
}
},
// @eventSource: is an object implementing the EventSource API, e.g. the
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
@@ -366,7 +414,7 @@ var Calendar = class Calendar {
});
this._rebuildCalendar();
this._update();
}
},
// Sets the calendar to show a specific date
setDate(date) {
@@ -376,14 +424,14 @@ var Calendar = class Calendar {
this._selectedDate = date;
this._update();
this.emit('selected-date-changed', new Date(this._selectedDate));
}
},
updateTimeZone() {
// The calendar need to be rebuilt after a time zone update because
// the date might have changed.
this._rebuildCalendar();
this._update();
}
},
_buildHeader() {
let layout = this.actor.layout_manager;
@@ -440,7 +488,7 @@ var Calendar = class Calendar {
// All the children after this are days, and get removed when we update the calendar
this._firstDayIndex = this.actor.get_n_children();
}
},
_onScroll(actor, event) {
switch (event.get_scroll_direction()) {
@@ -454,7 +502,7 @@ var Calendar = class Calendar {
break;
}
return Clutter.EVENT_PROPAGATE;
}
},
_onPrevMonthButtonClicked() {
let newDate = new Date(this._selectedDate);
@@ -478,7 +526,7 @@ var Calendar = class Calendar {
this._backButton.grab_key_focus();
this.setDate(newDate);
}
},
_onNextMonthButtonClicked() {
let newDate = new Date(this._selectedDate);
@@ -502,14 +550,14 @@ var Calendar = class Calendar {
this._forwardButton.grab_key_focus();
this.setDate(newDate);
}
},
_onSettingsChange() {
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
this._buildHeader();
this._rebuildCalendar();
this._update();
}
},
_rebuildCalendar() {
let now = new Date();
@@ -630,7 +678,7 @@ var Calendar = class Calendar {
// Signal to the event source that we are interested in events
// only from this date range
this._eventSource.requestRange(beginDate, iter);
}
},
_update() {
let now = new Date();
@@ -653,17 +701,18 @@ var Calendar = class Calendar {
button.remove_style_pseudo_class('selected');
});
}
};
});
Signals.addSignalMethods(Calendar.prototype);
var EventMessage = class EventMessage extends MessageList.Message {
constructor(event, date) {
super('', event.summary);
var EventMessage = new Lang.Class({
Name: 'EventMessage',
Extends: MessageList.Message,
_init(event, date) {
this._event = event;
this._date = date;
this.setTitle(this._formatEventTime());
this.parent(this._formatEventTime(), event.summary);
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
this.setIcon(this._icon);
@@ -672,7 +721,7 @@ var EventMessage = class EventMessage extends MessageList.Message {
let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
this._icon.opacity = (iconVisible ? 255 : 0);
});
}
},
_formatEventTime() {
let periodBegin = _getBeginningOfDay(this._date);
@@ -705,17 +754,23 @@ var EventMessage = class EventMessage extends MessageList.Message {
title = title + ELLIPSIS_CHAR;
}
return title;
},
canClose() {
return isToday(this._date);
}
};
});
var NotificationMessage =
class NotificationMessage extends MessageList.Message {
constructor(notification) {
super(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup);
var NotificationMessage = new Lang.Class({
Name: 'NotificationMessage',
Extends: MessageList.Message,
_init(notification) {
this.notification = notification;
this.parent(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup);
this.setIcon(this._getIcon());
this.connect('close', () => {
@@ -724,14 +779,13 @@ class NotificationMessage extends MessageList.Message {
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
});
this._destroyId = notification.connect('destroy', () => {
this._disconnectNotificationSignals();
this.notification = null;
if (!this._closed)
this.close();
});
this._updatedId = notification.connect('updated',
this._onUpdated.bind(this));
}
},
_getIcon() {
if (this.notification.gicon)
@@ -739,25 +793,22 @@ class NotificationMessage extends MessageList.Message {
icon_size: MESSAGE_ICON_SIZE });
else
return this.notification.source.createIcon(MESSAGE_ICON_SIZE);
}
},
_onUpdated(n, clear) {
this.setIcon(this._getIcon());
this.setTitle(n.title);
this.setBody(n.bannerBodyText);
this.setUseBodyMarkup(n.bannerBodyMarkup);
}
},
_onClicked() {
this.notification.activate();
}
},
_onDestroy() {
super._onDestroy();
this._disconnectNotificationSignals();
}
this.parent();
_disconnectNotificationSignals() {
if (this._updatedId)
this.notification.disconnect(this._updatedId);
this._updatedId = 0;
@@ -766,22 +817,21 @@ class NotificationMessage extends MessageList.Message {
this.notification.disconnect(this._destroyId);
this._destroyId = 0;
}
});
canClose() {
return true;
}
};
var EventsSection = class EventsSection extends MessageList.MessageListSection {
constructor() {
super();
var EventsSection = new Lang.Class({
Name: 'EventsSection',
Extends: MessageList.MessageListSection,
_init() {
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new EmptyEventSource();
this._messageById = new Map();
this.parent();
this._title = new St.Button({ style_class: 'events-section-title',
label: '',
x_align: St.Align.START,
@@ -794,16 +844,20 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
Shell.AppSystem.get_default().connect('installed-changed',
this._appInstalledChanged.bind(this));
this._appInstalledChanged();
}
},
_ignoreEvent(event) {
this._eventSource.ignoreEvent(event);
},
setEventSource(eventSource) {
this._eventSource = eventSource;
this._eventSource.connect('changed', this._reloadEvents.bind(this));
}
},
get allowed() {
return Main.sessionMode.showCalendarEvents;
}
},
_updateTitle() {
this._title.visible = !isToday(this._date);
@@ -822,7 +876,7 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
"%A, %B %-d, %Y"));
this._title.label = this._date.toLocaleFormat(dayFormat);
}
},
_reloadEvents() {
if (this._eventSource.isLoading)
@@ -848,6 +902,9 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
let message = this._messageById.get(event.id);
if (!message) {
message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this._messageById.set(event.id, message);
this.addMessage(message, false);
} else {
@@ -857,12 +914,12 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
this._reloading = false;
this._sync();
}
},
_appInstalledChanged() {
this._calendarApp = undefined;
this._title.reactive = (this._getCalendarApp() != null);
}
},
_getCalendarApp() {
if (this._calendarApp !== undefined)
@@ -877,7 +934,7 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
this._calendarApp = null;
}
return this._calendarApp;
}
},
_onTitleClicked() {
Main.overview.hide();
@@ -887,30 +944,32 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
if (app.get_id() == 'evolution.desktop')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
app.launch([], global.create_app_launch_context(0, -1));
}
},
setDate(date) {
super.setDate(date);
this.parent(date);
this._updateTitle();
this._reloadEvents();
}
},
_shouldShow() {
return !this.empty || !isToday(this._date);
}
},
_sync() {
if (this._reloading)
return;
super._sync();
this.parent();
}
};
});
var NotificationSection =
class NotificationSection extends MessageList.MessageListSection {
constructor() {
super();
var NotificationSection = new Lang.Class({
Name: 'NotificationSection',
Extends: MessageList.MessageListSection,
_init() {
this.parent();
this._sources = new Map();
this._nUrgent = 0;
@@ -921,12 +980,12 @@ class NotificationSection extends MessageList.MessageListSection {
});
this.actor.connect('notify::mapped', this._onMapped.bind(this));
}
},
get allowed() {
return Main.sessionMode.hasNotifications &&
!Main.sessionMode.isGreeter;
}
},
_createTimeLabel(datetime) {
let label = new St.Label({ style_class: 'event-time',
@@ -937,7 +996,7 @@ class NotificationSection extends MessageList.MessageListSection {
label.text = Util.formatTimeSpan(datetime);
});
return label;
}
},
_sourceAdded(tray, source) {
let obj = {
@@ -952,7 +1011,7 @@ class NotificationSection extends MessageList.MessageListSection {
this._onNotificationAdded.bind(this));
this._sources.set(source, obj);
}
},
_onNotificationAdded(source, notification) {
let message = new NotificationMessage(notification);
@@ -983,14 +1042,14 @@ class NotificationSection extends MessageList.MessageListSection {
let index = isUrgent ? 0 : this._nUrgent;
this.addMessageAtIndex(message, index, this.actor.mapped);
}
},
_onSourceDestroy(source, obj) {
source.disconnect(obj.destroyId);
source.disconnect(obj.notificationAddedId);
this._sources.delete(source);
}
},
_onMapped() {
if (!this.actor.mapped)
@@ -999,15 +1058,17 @@ class NotificationSection extends MessageList.MessageListSection {
for (let message of this._messages.keys())
if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
message.notification.acknowledged = true;
}
},
_shouldShow() {
return !this.empty && isToday(this._date);
}
};
});
var Placeholder = class Placeholder {
constructor() {
var Placeholder = new Lang.Class({
Name: 'Placeholder',
_init() {
this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
vertical: true });
@@ -1025,14 +1086,14 @@ var Placeholder = class Placeholder {
this.actor.add_actor(this._label);
this._sync();
}
},
setDate(date) {
if (sameDay(this._date, date))
return;
this._date = date;
this._sync();
}
},
_sync() {
let today = isToday(this._date);
@@ -1049,10 +1110,12 @@ var Placeholder = class Placeholder {
this._label.text = _("No Events");
}
}
};
});
var CalendarMessageList = class CalendarMessageList {
constructor() {
var CalendarMessageList = new Lang.Class({
Name: 'CalendarMessageList',
_init() {
this.actor = new St.Widget({ style_class: 'message-list',
layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true });
@@ -1068,11 +1131,11 @@ var CalendarMessageList = class CalendarMessageList {
overlay_scrollbars: true,
x_expand: true, y_expand: true,
x_fill: true, y_fill: true });
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
box.add_actor(this._scrollView);
this._clearButton = new St.Button({ style_class: 'message-list-clear-button button',
label: _("Clear"),
label: _("Clear All"),
can_focus: true });
this._clearButton.set_x_align(Clutter.ActorAlign.END);
this._clearButton.connect('clicked', () => {
@@ -1098,7 +1161,7 @@ var CalendarMessageList = class CalendarMessageList {
this._addSection(this._eventsSection);
Main.sessionMode.connect('updated', this._sync.bind(this));
}
},
_addSection(section) {
let obj = {
@@ -1123,7 +1186,7 @@ var CalendarMessageList = class CalendarMessageList {
this._sections.set(section, obj);
this._sectionList.add_actor(section.actor);
this._sync();
}
},
_removeSection(section) {
let obj = this._sections.get(section);
@@ -1136,11 +1199,11 @@ var CalendarMessageList = class CalendarMessageList {
this._sections.delete(section);
this._sectionList.remove_actor(section.actor);
this._sync();
}
},
_onKeyFocusIn(section, actor) {
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
}
},
_sync() {
let sections = [...this._sections.keys()];
@@ -1155,15 +1218,15 @@ var CalendarMessageList = class CalendarMessageList {
let canClear = sections.some(s => s.canClear && s.actor.visible);
this._clearButton.reactive = canClear;
}
},
setEventSource(eventSource) {
this._eventsSection.setEventSource(eventSource);
}
},
setDate(date) {
for (let section of this._sections.keys())
section.setDate(date);
this._placeholder.setDate(date);
}
};
});

View File

@@ -1,7 +1,13 @@
const { Clutter, Pango, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
var CheckBox = class CheckBox {
constructor(label) {
const Lang = imports.lang;
var CheckBox = new Lang.Class({
Name: 'CheckBox',
_init(label) {
let container = new St.BoxLayout();
this.actor = new St.Button({ style_class: 'check-box',
child: container,
@@ -22,13 +28,13 @@ var CheckBox = class CheckBox {
if (label)
this.setLabel(label);
}
},
setLabel(label) {
this._label.set_text(label);
}
},
getLabelActor() {
return this._label;
}
};
});

View File

@@ -1,6 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, GObject, Meta, Shell } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Dialog = imports.ui.dialog;
const Main = imports.ui.main;
@@ -10,29 +16,31 @@ var FROZEN_WINDOW_BRIGHTNESS = -0.3
var DIALOG_TRANSITION_TIME = 0.15
var ALIVE_TIMEOUT = 5000;
var CloseDialog = GObject.registerClass({
var CloseDialog = new Lang.Class({
Name: 'CloseDialog',
Extends: GObject.Object,
Implements: [ Meta.CloseDialog ],
Properties: {
'window': GObject.ParamSpec.override('window', Meta.CloseDialog)
},
}, class CloseDialog extends GObject.Object {
_init(window) {
super._init();
this.parent();
this._window = window;
this._dialog = null;
this._tracked = undefined;
this._timeoutId = 0;
this._windowFocusChangedId = 0;
this._keyFocusChangedId = 0;
}
},
get window() {
return this._window;
}
},
set window(window) {
this._window = window;
}
},
_createDialogContent() {
let tracker = Shell.WindowTracker.get_default();
@@ -44,7 +52,7 @@ var CloseDialog = GObject.registerClass({
"continue or force the application to quit entirely.");
let icon = new Gio.ThemedIcon({ name: 'dialog-warning-symbolic' });
return new Dialog.MessageDialogContent({ icon, title, subtitle });
}
},
_initDialog() {
if (this._dialog)
@@ -64,7 +72,7 @@ var CloseDialog = GObject.registerClass({
key: Clutter.Escape });
global.focus_manager.add_group(this._dialog);
}
},
_addWindowEffect() {
// We set the effect on the surface actor, so the dialog itself
@@ -75,21 +83,21 @@ var CloseDialog = GObject.registerClass({
let effect = new Clutter.BrightnessContrastEffect();
effect.set_brightness(FROZEN_WINDOW_BRIGHTNESS);
surfaceActor.add_effect_with_name("gnome-shell-frozen-window", effect);
}
},
_removeWindowEffect() {
let windowActor = this._window.get_compositor_private();
let surfaceActor = windowActor.get_first_child();
surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
}
},
_onWait() {
this.response(Meta.CloseDialogResponse.WAIT);
}
},
_onClose() {
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
}
},
_onFocusChanged() {
if (Meta.is_wayland_compositor())
@@ -120,7 +128,7 @@ var CloseDialog = GObject.registerClass({
});
this._tracked = shouldTrack;
}
},
vfunc_show() {
if (this._dialog != null)
@@ -154,7 +162,7 @@ var CloseDialog = GObject.registerClass({
time: DIALOG_TRANSITION_TIME,
onComplete: this._onFocusChanged.bind(this)
});
}
},
vfunc_hide() {
if (this._dialog == null)
@@ -183,7 +191,7 @@ var CloseDialog = GObject.registerClass({
dialog.destroy();
}
});
}
},
vfunc_focus() {
if (this._dialog)

View File

@@ -1,13 +1,17 @@
const Lang = imports.lang;
const Main = imports.ui.main;
var ComponentManager = class {
constructor() {
var ComponentManager = new Lang.Class({
Name: 'ComponentManager',
_init() {
this._allComponents = {};
this._enabledComponents = [];
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
}
},
_sessionUpdated() {
let newEnabledComponents = Main.sessionMode.components;
@@ -25,12 +29,12 @@ var ComponentManager = class {
});
this._enabledComponents = newEnabledComponents;
}
},
_importComponent(name) {
let module = imports.ui.components[name];
return module.Component;
}
},
_ensureComponent(name) {
let component = this._allComponents[name];
@@ -44,13 +48,13 @@ var ComponentManager = class {
component = new constructor();
this._allComponents[name] = component;
return component;
}
},
_enableComponent(name) {
let component = this._ensureComponent(name);
if (component)
component.enable();
}
},
_disableComponent(name) {
let component = this._allComponents[name];
@@ -58,4 +62,4 @@ var ComponentManager = class {
return;
component.disable();
}
};
});

View File

@@ -1,10 +1,14 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib } = imports.gi;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Params = imports.misc.params;
const Shell = imports.gi.Shell;
const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation;
var GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
@@ -15,8 +19,10 @@ const SETTING_ENABLE_AUTOMOUNT = 'automount';
var AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
var AutomountManager = class {
constructor() {
var AutomountManager = new Lang.Class({
Name: 'AutomountManager',
_init() {
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
this._volumeQueue = [];
this._activeOperations = new Map();
@@ -28,7 +34,7 @@ var AutomountManager = class {
this._inhibited = false;
this._volumeMonitor = Gio.VolumeMonitor.get();
}
},
enable() {
this._volumeAddedId = this._volumeMonitor.connect('volume-added', this._onVolumeAdded.bind(this));
@@ -39,7 +45,7 @@ var AutomountManager = class {
this._mountAllId = Mainloop.idle_add(this._startupMountAll.bind(this));
GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
}
},
disable() {
this._volumeMonitor.disconnect(this._volumeAddedId);
@@ -52,7 +58,7 @@ var AutomountManager = class {
Mainloop.source_remove(this._mountAllId);
this._mountAllId = 0;
}
}
},
_InhibitorsChanged(object, senderName, [inhibtor]) {
this._session.IsInhibitedRemote(GNOME_SESSION_AUTOMOUNT_INHIBIT,
@@ -61,7 +67,7 @@ var AutomountManager = class {
this._inhibited = result[0];
}
});
}
},
_startupMountAll() {
let volumes = this._volumeMonitor.get_volumes();
@@ -73,7 +79,7 @@ var AutomountManager = class {
this._mountAllId = 0;
return GLib.SOURCE_REMOVE;
}
},
_onDriveConnected() {
// if we're not in the current ConsoleKit session,
@@ -81,11 +87,10 @@ var AutomountManager = class {
if (!this._session.SessionIsActive)
return;
let player = global.display.get_sound_player();
player.play_from_theme('device-added-media',
_("External drive connected"),
null);
}
global.play_theme_sound(0, 'device-added-media',
_("External drive connected"),
null);
},
_onDriveDisconnected() {
// if we're not in the current ConsoleKit session,
@@ -93,11 +98,10 @@ var AutomountManager = class {
if (!this._session.SessionIsActive)
return;
let player = global.display.get_sound_player();
player.play_from_theme('device-removed-media',
_("External drive disconnected"),
null);
}
global.play_theme_sound(0, 'device-removed-media',
_("External drive disconnected"),
null);
},
_onDriveEjectButton(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor
@@ -128,11 +132,11 @@ var AutomountManager = class {
}
});
}
}
},
_onVolumeAdded(monitor, volume) {
this._checkAndMountVolume(volume);
}
},
_checkAndMountVolume(volume, params) {
params = Params.parse(params, { checkSession: true,
@@ -172,7 +176,7 @@ var AutomountManager = class {
} else {
this._mountVolume(volume, null, params.allowAutorun);
}
}
},
_mountVolume(volume, operation, allowAutorun) {
if (allowAutorun)
@@ -183,7 +187,7 @@ var AutomountManager = class {
volume.mount(0, mountOp, null,
this._onVolumeMounted.bind(this));
}
},
_onVolumeMounted(volume, res) {
this._allowAutorunExpire(volume);
@@ -208,7 +212,7 @@ var AutomountManager = class {
this._closeOperation(volume);
}
}
}
},
_onVolumeRemoved(monitor, volume) {
if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
@@ -217,7 +221,7 @@ var AutomountManager = class {
}
this._volumeQueue =
this._volumeQueue.filter(element => (element != volume));
}
},
_reaskPassword(volume) {
let prevOperation = this._activeOperations.get(volume);
@@ -226,7 +230,7 @@ var AutomountManager = class {
new ShellMountOperation.ShellMountOperation(volume,
{ existingDialog: existingDialog });
this._mountVolume(volume, operation);
}
},
_closeOperation(volume) {
let operation = this._activeOperations.get(volume);
@@ -234,11 +238,11 @@ var AutomountManager = class {
return;
operation.close();
this._activeOperations.delete(volume);
}
},
_allowAutorun(volume) {
volume.allowAutorun = true;
}
},
_allowAutorunExpire(volume) {
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
@@ -249,5 +253,5 @@ var AutomountManager = class {
volume._allowAutorunExpireId = id;
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
}
};
});
var Component = AutomountManager;

View File

@@ -1,6 +1,8 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, St } = imports.gi;
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const St = imports.gi.St;
const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main;
@@ -82,11 +84,13 @@ function HotplugSniffer() {
'/org/gnome/Shell/HotplugSniffer');
}
var ContentTypeDiscoverer = class {
constructor(callback) {
var ContentTypeDiscoverer = new Lang.Class({
Name: 'ContentTypeDiscoverer',
_init(callback) {
this._callback = callback;
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
}
},
guessContentTypes(mount) {
let autorunEnabled = !this._settings.get_boolean(SETTING_DISABLE_AUTORUN);
@@ -99,7 +103,7 @@ var ContentTypeDiscoverer = class {
} else {
this._emitCallback(mount, []);
}
}
},
_onContentTypeGuessed(mount, res) {
let contentTypes = [];
@@ -122,7 +126,7 @@ var ContentTypeDiscoverer = class {
this._emitCallback(mount, contentTypes);
});
}
}
},
_emitCallback(mount, contentTypes) {
if (!contentTypes)
@@ -146,25 +150,27 @@ var ContentTypeDiscoverer = class {
this._callback(mount, apps, contentTypes);
}
};
});
var AutorunManager = class {
constructor() {
var AutorunManager = new Lang.Class({
Name: 'AutorunManager',
_init() {
this._session = new GnomeSession.SessionManager();
this._volumeMonitor = Gio.VolumeMonitor.get();
this._dispatcher = new AutorunDispatcher(this);
}
},
enable() {
this._mountAddedId = this._volumeMonitor.connect('mount-added', this._onMountAdded.bind(this));
this._mountRemovedId = this._volumeMonitor.connect('mount-removed', this._onMountRemoved.bind(this));
}
},
disable() {
this._volumeMonitor.disconnect(this._mountAddedId);
this._volumeMonitor.disconnect(this._mountRemovedId);
}
},
_onMountAdded(monitor, mount) {
// don't do anything if our session is not the currently
@@ -176,19 +182,21 @@ var AutorunManager = class {
this._dispatcher.addMount(mount, apps, contentTypes);
});
discoverer.guessContentTypes(mount);
}
},
_onMountRemoved(monitor, mount) {
this._dispatcher.removeMount(mount);
}
};
});
var AutorunDispatcher = class {
constructor(manager) {
var AutorunDispatcher = new Lang.Class({
Name: 'AutorunDispatcher',
_init(manager) {
this._manager = manager;
this._sources = [];
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
}
},
_getAutorunSettingForType(contentType) {
let runApp = this._settings.get_strv(SETTING_START_APP);
@@ -204,7 +212,7 @@ var AutorunDispatcher = class {
return AutorunSetting.FILES;
return AutorunSetting.ASK;
}
},
_getSourceForMount(mount) {
let filtered = this._sources.filter(source => (source.mount == mount));
@@ -216,7 +224,7 @@ var AutorunDispatcher = class {
return filtered[0];
return null;
}
},
_addSource(mount, apps) {
// if we already have a source showing for this
@@ -226,7 +234,7 @@ var AutorunDispatcher = class {
// add a new source
this._sources.push(new AutorunSource(this._manager, mount, apps));
}
},
addMount(mount, apps, contentTypes) {
// if autorun is disabled globally, return
@@ -264,7 +272,7 @@ var AutorunDispatcher = class {
// but we failed launching the default app or the default file manager
if (!success)
this._addSource(mount, apps);
}
},
removeMount(mount) {
let source = this._getSourceForMount(mount);
@@ -276,39 +284,45 @@ var AutorunDispatcher = class {
// destroy the notification source
source.destroy();
}
};
});
var AutorunSource = class extends MessageTray.Source {
constructor(manager, mount, apps) {
super(mount.get_name());
var AutorunSource = new Lang.Class({
Name: 'AutorunSource',
Extends: MessageTray.Source,
_init(manager, mount, apps) {
this._manager = manager;
this.mount = mount;
this.apps = apps;
this.parent(mount.get_name());
this._notification = new AutorunNotification(this._manager, this);
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
this.notify(this._notification);
}
},
getIcon() {
return this.mount.get_icon();
}
},
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
}
};
});
var AutorunNotification = class extends MessageTray.Notification {
constructor(manager, source) {
super(source, source.title);
var AutorunNotification = new Lang.Class({
Name: 'AutorunNotification',
Extends: MessageTray.Notification,
_init(manager, source) {
this.parent(source, source.title);
this._manager = manager;
this._mount = source.mount;
}
},
createBanner() {
let banner = new MessageTray.NotificationBanner(this);
@@ -321,7 +335,7 @@ var AutorunNotification = class extends MessageTray.Notification {
});
return banner;
}
},
_buttonForApp(app) {
let box = new St.BoxLayout();
@@ -348,14 +362,14 @@ var AutorunNotification = class extends MessageTray.Notification {
});
return button;
}
},
activate() {
super.activate();
this.parent();
let app = Gio.app_info_get_default_for_type('inode/directory', false);
startAppForMount(app, this._mount);
}
};
});
var Component = AutorunManager;

View File

@@ -1,18 +1,31 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Pango = imports.gi.Pango;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gcr = imports.gi.Gcr;
const Animation = imports.ui.animation;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const CheckBox = imports.ui.checkBox;
const Tweener = imports.ui.tweener;
var WORK_SPINNER_ICON_SIZE = 16;
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
var WORK_SPINNER_ANIMATION_TIME = 0.3;
var KeyringDialog = class extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'prompt-dialog' });
var KeyringDialog = new Lang.Class({
Name: 'KeyringDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'prompt-dialog' });
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', this._onShowPassword.bind(this));
@@ -50,17 +63,34 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
}
},
_setWorking(working) {
if (!this._workSpinner)
return;
if (working)
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
else
this._workSpinner.stop();
}
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
_buildControlTable() {
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
@@ -84,7 +114,9 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
if (rtl) {
layout.attach(this._workSpinner.actor, 0, row, 1, 1);
@@ -151,7 +183,7 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
this._controlTable = table;
this._content.messageBox.add(table, { x_fill: true, y_fill: true });
}
},
_updateSensitivity(sensitive) {
if (this._passwordEntry) {
@@ -167,7 +199,7 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
}
},
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
@@ -185,61 +217,65 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
' Dismissing prompt request');
this.prompt.cancel()
return false;
}
},
_onShowPassword(prompt) {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._passwordEntry.grab_key_focus();
}
},
_onShowConfirm(prompt) {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._continueButton.grab_key_focus();
}
},
_onHidePrompt(prompt) {
this.close();
}
},
_onPasswordActivate() {
if (this.prompt.confirm_visible)
this._confirmEntry.grab_key_focus();
else
this._onContinueButton();
}
},
_onConfirmActivate() {
this._onContinueButton();
}
},
_onContinueButton() {
this._updateSensitivity(false);
this.prompt.complete();
}
},
_onCancelButton() {
this.prompt.cancel();
}
};
},
});
var KeyringDummyDialog = class {
constructor() {
var KeyringDummyDialog = new Lang.Class({
Name: 'KeyringDummyDialog',
_init() {
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', this._cancelPrompt.bind(this));
this.prompt.connect('show-confirm', this._cancelPrompt.bind(this));
}
},
_cancelPrompt() {
this.prompt.cancel();
}
};
});
var KeyringPrompter = class {
constructor() {
var KeyringPrompter = new Lang.Class({
Name: 'KeyringPrompter',
_init() {
this._prompter = new Gcr.SystemPrompter();
this._prompter.connect('new-prompt', () => {
let dialog = this._enabled ? new KeyringDialog()
@@ -251,7 +287,7 @@ var KeyringPrompter = class {
this._registered = false;
this._enabled = false;
this._currentPrompt = null;
}
},
enable() {
if (!this._registered) {
@@ -261,7 +297,7 @@ var KeyringPrompter = class {
this._registered = true;
}
this._enabled = true;
}
},
disable() {
this._enabled = false;
@@ -270,6 +306,6 @@ var KeyringPrompter = class {
this._currentPrompt.cancel();
this._currentPrompt = null;
}
};
});
var Component = KeyringPrompter;

View File

@@ -1,20 +1,32 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, NM, Pango, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const NM = imports.gi.NM;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Config = imports.misc.config;
const Dialog = imports.ui.dialog;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog;
const PopupMenu = imports.ui.popupMenu;
const ShellEntry = imports.ui.shellEntry;
const VPN_UI_GROUP = 'VPN Plugin UI';
var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
constructor(agent, requestId, connection, settingName, hints, flags, contentOverride) {
super({ styleClass: 'prompt-dialog' });
var NetworkSecretDialog = new Lang.Class({
Name: 'NetworkSecretDialog',
Extends: ModalDialog.ModalDialog,
_init(agent, requestId, connection, settingName, hints, contentOverride) {
this.parent({ styleClass: 'prompt-dialog' });
this._agent = agent;
this._requestId = requestId;
@@ -97,18 +109,6 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
contentBox.messageBox.add(secretTable);
if (flags & NM.SecretAgentGetSecretsFlags.WPS_PBC_ACTIVE) {
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: _("Alternatively you can connect by pushing the “WPS” button on your router.") });
descriptionLabel.clutter_text.line_wrap = true;
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
contentBox.messageBox.add(descriptionLabel,
{ y_fill: true,
y_align: St.Align.START,
expand: true });
}
this._okButton = { label: _("Connect"),
action: this._onOk.bind(this),
default: true
@@ -121,7 +121,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
this._okButton]);
this._updateOkButton();
}
},
_updateOkButton() {
let valid = true;
@@ -132,7 +132,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
this._okButton.button.reactive = valid;
this._okButton.button.can_focus = valid;
}
},
_onOk() {
let valid = true;
@@ -148,12 +148,12 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
this.close(global.get_current_time());
}
// do nothing if not valid
}
},
cancel() {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
this.close(global.get_current_time());
}
},
_validateWpaPsk(secret) {
let value = secret.value;
@@ -169,7 +169,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
}
return (value.length >= 8 && value.length <= 63);
}
},
_validateStaticWep(secret) {
let value = secret.value;
@@ -194,7 +194,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
return false;
}
return true;
}
},
_getWirelessSecrets(secrets, wirelessSetting) {
let wirelessSecuritySetting = this._connection.get_setting_wireless_security();
@@ -231,7 +231,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
default:
log('Invalid wireless key management: ' + wirelessSecuritySetting.key_mgmt);
}
}
},
_get8021xSecrets(secrets) {
let ieee8021xSetting = this._connection.get_setting_802_1x();
@@ -274,7 +274,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
default:
log('Invalid EAP/IEEE802.1x method: ' + ieee8021xSetting.get_eap_method(0));
}
}
},
_getPPPoESecrets(secrets) {
let pppoeSetting = this._connection.get_setting_pppoe();
@@ -284,7 +284,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
value: pppoeSetting.service || '', password: false });
secrets.push({ label: _("Password: "), key: 'password',
value: pppoeSetting.password || '', password: true });
}
},
_getMobileSecrets(secrets, connectionType) {
let setting;
@@ -294,7 +294,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
setting = this._connection.get_setting_by_name(connectionType);
secrets.push({ label: _("Password: "), key: 'password',
value: setting.value || '', password: true });
}
},
_getContent() {
let connectionSetting = this._connection.get_setting_connection();
@@ -347,14 +347,15 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
return content;
}
};
});
var VPNRequestHandler = class {
constructor(agent, requestId, authHelper, serviceType, connection, hints, flags) {
var VPNRequestHandler = new Lang.Class({
Name: 'VPNRequestHandler',
_init(agent, requestId, authHelper, serviceType, connection, hints, flags) {
this._agent = agent;
this._requestId = requestId;
this._connection = connection;
this._flags = flags;
this._pluginOutBuffer = [];
this._title = null;
this._description = null;
@@ -411,7 +412,7 @@ var VPNRequestHandler = class {
this._agent.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
}
}
},
cancel(respond) {
if (respond)
@@ -427,7 +428,7 @@ var VPNRequestHandler = class {
}
this.destroy();
}
},
destroy() {
if (this._destroyed)
@@ -441,7 +442,7 @@ var VPNRequestHandler = class {
// Stdout is closed when we finish reading from it
this._destroyed = true;
}
},
_vpnChildFinished(pid, status, requestObj) {
this._childWatch = 0;
@@ -462,7 +463,7 @@ var VPNRequestHandler = class {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
}
},
_vpnChildProcessLineOldStyle(line) {
if (this._previousLine != undefined) {
@@ -480,7 +481,7 @@ var VPNRequestHandler = class {
} else {
this._previousLine = line;
}
}
},
_readStdoutOldStyle() {
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
@@ -497,7 +498,7 @@ var VPNRequestHandler = class {
// try to read more!
this._readStdoutOldStyle();
});
}
},
_readStdoutNewStyle() {
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
@@ -515,7 +516,7 @@ var VPNRequestHandler = class {
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
this._readStdoutNewStyle();
});
}
},
_showNewStyleDialog() {
let keyfile = new GLib.KeyFile();
@@ -573,13 +574,13 @@ var VPNRequestHandler = class {
if (contentOverride && contentOverride.secrets.length) {
// Only show the dialog if we actually have something to ask
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], this._flags, contentOverride);
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], contentOverride);
this._shellDialog.open(global.get_current_time());
} else {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.CONFIRMED);
this.destroy();
}
}
},
_writeConnection() {
let vpnSetting = this._connection.get_setting_vpn();
@@ -600,12 +601,14 @@ var VPNRequestHandler = class {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
}
}
};
},
});
Signals.addSignalMethods(VPNRequestHandler.prototype);
var NetworkAgent = class {
constructor() {
var NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
_init() {
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
auto_register: false
@@ -636,7 +639,7 @@ var NetworkAgent = class {
logError(e, 'error initializing the NetworkManager Agent');
}
});
}
},
enable() {
if (!this._native)
@@ -645,7 +648,7 @@ var NetworkAgent = class {
this._native.auto_register = true;
if (this._initialized && !this._native.registered)
this._native.register_async(null, null);
}
},
disable() {
let requestId;
@@ -668,7 +671,7 @@ var NetworkAgent = class {
this._native.auto_register = false;
if (this._initialized && this._native.registered)
this._native.unregister_async(null, null);
}
},
_showNotification(requestId, connection, settingName, hints, flags) {
let source = new MessageTray.Source(_("Network Manager"), 'network-transmit-receive');
@@ -697,14 +700,14 @@ var NetworkAgent = class {
if (hints.indexOf('pin') != -1) {
let gsmSetting = connection.get_setting_gsm();
title = _("PIN code required");
body = _("PIN code is needed for the mobile broadband device");
message = _("PIN code is needed for the mobile broadband device");
break;
}
// fall through
case 'cdma':
case 'bluetooth':
title = _("Mobile broadband network password");
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
default:
log('Invalid connection type: ' + connectionType);
@@ -728,14 +731,14 @@ var NetworkAgent = class {
Main.messageTray.add(source);
source.notify(notification);
}
},
_newRequest(agent, requestId, connection, settingName, hints, flags) {
if (!(flags & NM.SecretAgentGetSecretsFlags.USER_REQUESTED))
this._showNotification(requestId, connection, settingName, hints, flags);
else
this._handleRequest(requestId, connection, settingName, hints, flags);
}
},
_handleRequest(requestId, connection, settingName, hints, flags) {
if (settingName == 'vpn') {
@@ -743,13 +746,13 @@ var NetworkAgent = class {
return;
}
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints, flags);
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints);
dialog.connect('destroy', () => {
delete this._dialogs[requestId];
});
this._dialogs[requestId] = dialog;
dialog.open(global.get_current_time());
}
},
_cancelRequest(agent, requestId) {
if (this._dialogs[requestId]) {
@@ -760,7 +763,7 @@ var NetworkAgent = class {
this._vpnRequests[requestId].cancel(false);
delete this._vpnRequests[requestId];
}
}
},
_vpnRequest(requestId, connection, hints, flags) {
let vpnSetting = connection.get_setting_vpn();
@@ -782,7 +785,7 @@ var NetworkAgent = class {
delete this._vpnRequests[requestId];
});
this._vpnRequests[requestId] = vpnRequest;
}
},
_buildVPNServiceCache() {
if (this._vpnCacheBuilt)
@@ -815,5 +818,5 @@ var NetworkAgent = class {
}
});
}
};
});
var Component = NetworkAgent;

View File

@@ -1,23 +1,39 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { AccountsService, Clutter, Gio, GLib,
Pango, PolkitAgent, Polkit, Shell, St } = imports.gi;
const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const AccountsService = imports.gi.AccountsService;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Pango = imports.gi.Pango;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Mainloop = imports.mainloop;
const Polkit = imports.gi.Polkit;
const PolkitAgent = imports.gi.PolkitAgent;
const Animation = imports.ui.animation;
const Components = imports.ui.components;
const Dialog = imports.ui.dialog;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget;
const Tweener = imports.ui.tweener;
var DIALOG_ICON_SIZE = 48;
var WORK_SPINNER_ICON_SIZE = 16;
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
var WORK_SPINNER_ANIMATION_TIME = 0.3;
var AuthenticationDialog = class extends ModalDialog.ModalDialog {
constructor(actionId, body, cookie, userNames) {
super({ styleClass: 'prompt-dialog' });
var AuthenticationDialog = new Lang.Class({
Name: 'AuthenticationDialog',
Extends: ModalDialog.ModalDialog,
_init(actionId, body, cookie, userNames) {
this.parent({ styleClass: 'prompt-dialog' });
this.actionId = actionId;
this.message = body;
@@ -28,8 +44,6 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._group.visible = !Main.sessionMode.isLocked;
});
this.connect('closed', this._onDialogClosed.bind(this));
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
let title = _("Authentication Required");
@@ -103,7 +117,10 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._passwordBox.add(this._passwordEntry,
{ expand: true });
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._passwordBox.add(this._workSpinner.actor);
this.setInitialKeyFocus(this._passwordEntry);
@@ -144,25 +161,50 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
this._cookie = cookie;
}
},
_setWorking(working) {
if (working)
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
else
this._workSpinner.stop();
}
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
performAuthentication() {
this._destroySession();
this.destroySession();
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
cookie: this._cookie });
this._sessionCompletedId = this._session.connect('completed', this._onSessionCompleted.bind(this));
this._sessionRequestId = this._session.connect('request', this._onSessionRequest.bind(this));
this._sessionShowErrorId = this._session.connect('show-error', this._onSessionShowError.bind(this));
this._sessionShowInfoId = this._session.connect('show-info', this._onSessionShowInfo.bind(this));
this._session.connect('completed', this._onSessionCompleted.bind(this));
this._session.connect('request', this._onSessionRequest.bind(this));
this._session.connect('show-error', this._onSessionShowError.bind(this));
this._session.connect('show-info', this._onSessionShowInfo.bind(this));
this._session.initiate();
}
},
close(timestamp) {
this.parent(timestamp);
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
},
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
@@ -184,14 +226,14 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
' cookie ' + this._cookie);
this._emitDone(true);
}
}
},
_emitDone(dismissed) {
if (!this._doneEmitted) {
this._doneEmitted = true;
this.emit('done', dismissed);
}
}
},
_updateSensitivity(sensitive) {
this._passwordEntry.reactive = sensitive;
@@ -200,7 +242,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._okButton.can_focus = sensitive;
this._okButton.reactive = sensitive;
this._setWorking(!sensitive);
}
},
_onEntryActivate() {
let response = this._passwordEntry.get_text();
@@ -211,11 +253,11 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._errorMessageLabel.hide();
this._infoMessageLabel.hide();
this._nullMessageLabel.show();
}
},
_onAuthenticateButtonPressed() {
this._onEntryActivate();
}
},
_onSessionCompleted(session, gainedAuthorization) {
if (this._completed || this._doneEmitted)
@@ -247,7 +289,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
/* Try and authenticate again */
this.performAuthentication();
}
}
},
_onSessionRequest(session, request, echo_on) {
// Cheap localization trick
@@ -266,7 +308,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._passwordEntry.grab_key_focus();
this._updateSensitivity(true);
this._ensureOpen();
}
},
_onSessionShowError(session, text) {
this._passwordEntry.set_text('');
@@ -275,7 +317,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
}
},
_onSessionShowInfo(session, text) {
this._passwordEntry.set_text('');
@@ -284,60 +326,43 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._errorMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
}
},
_destroySession() {
destroySession() {
if (this._session) {
if (!this._completed)
this._session.cancel();
this._completed = false;
this._session.disconnect(this._sessionCompletedId);
this._session.disconnect(this._sessionRequestId);
this._session.disconnect(this._sessionShowErrorId);
this._session.disconnect(this._sessionShowInfoId);
this._session = null;
}
}
},
_onUserChanged() {
if (this._user.is_loaded && this._userAvatar) {
this._userAvatar.update();
this._userAvatar.actor.show();
}
}
},
cancel() {
this._wasDismissed = true;
this.close(global.get_current_time());
this._emitDone(true);
}
_onDialogClosed() {
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
if (this._user) {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
this._user = null;
}
this._destroySession();
}
};
},
});
Signals.addSignalMethods(AuthenticationDialog.prototype);
var AuthenticationAgent = class {
constructor() {
var AuthenticationAgent = new Lang.Class({
Name: 'AuthenticationAgent',
_init() {
this._currentDialog = null;
this._handle = null;
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', this._onInitiate.bind(this));
this._native.connect('cancel', this._onCancel.bind(this));
this._sessionUpdatedId = 0;
}
},
enable() {
try {
@@ -345,7 +370,7 @@ var AuthenticationAgent = class {
} catch(e) {
log('Failed to register AuthenticationAgent');
}
}
},
disable() {
try {
@@ -353,7 +378,7 @@ var AuthenticationAgent = class {
} catch(e) {
log('Failed to unregister AuthenticationAgent');
}
}
},
_onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames) {
// Don't pop up a dialog while locked
@@ -381,18 +406,19 @@ var AuthenticationAgent = class {
this._currentDialog.connect('done', this._onDialogDone.bind(this));
this._currentDialog.performAuthentication();
}
},
_onCancel(nativeAgent) {
this._completeRequest(false);
}
},
_onDialogDone(dialog, dismissed) {
this._completeRequest(dismissed);
}
},
_completeRequest(dismissed) {
this._currentDialog.close();
this._currentDialog.destroySession();
this._currentDialog = null;
if (this._sessionUpdatedId)
@@ -400,7 +426,7 @@ var AuthenticationAgent = class {
this._sessionUpdatedId = 0;
this._native.complete(dismissed);
}
};
},
});
var Component = AuthenticationAgent;

View File

@@ -1,13 +1,19 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, GObject, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
var Tpl = null;
var Tp = null;
try {
({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi);
Tpl = imports.gi.TelepathyLogger;
Tp = imports.gi.TelepathyGLib;
} catch(e) {
log('Telepathy is not available, chat integration will be disabled.');
}
@@ -17,6 +23,7 @@ const Main = imports.ui.main;
const MessageList = imports.ui.messageList;
const MessageTray = imports.ui.messageTray;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
const Util = imports.misc.util;
const HAVE_TP = (Tp != null && Tpl != null);
@@ -72,15 +79,17 @@ function makeMessageFromTplEvent(event) {
};
}
var TelepathyComponent = class {
constructor() {
var TelepathyComponent = new Lang.Class({
Name: 'TelepathyComponent',
_init() {
this._client = null;
if (!HAVE_TP)
return; // Telepathy isn't available
this._client = new TelepathyClient();
}
},
enable() {
if (!this._client)
@@ -94,7 +103,7 @@ var TelepathyComponent = class {
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
this._client.account_manager.prepare_async(null, null);
}
},
disable() {
if (!this._client)
@@ -102,10 +111,12 @@ var TelepathyComponent = class {
this._client.unregister();
}
};
});
var TelepathyClient = HAVE_TP ? new Lang.Class({
Name: 'TelepathyClient',
Extends: Tp.BaseClient,
var TelepathyClient = HAVE_TP ? GObject.registerClass(
class TelepathyClient extends Tp.BaseClient {
_init() {
// channel path -> ChatSource
this._chatSources = {};
@@ -129,7 +140,7 @@ class TelepathyClient extends Tp.BaseClient {
// channel matching its filters is detected.
// The second argument, recover, means _observeChannels will be run
// for any existing channel as well.
super._init({ name: 'GnomeShell',
this.parent({ name: 'GnomeShell',
account_manager: this._accountManager,
uniquify_name: true });
@@ -147,7 +158,7 @@ class TelepathyClient extends Tp.BaseClient {
// needed
this.set_delegated_channels_callback(
this._delegatedChannelsCb.bind(this));
}
},
vfunc_observe_channels(account, conn, channels,
dispatchOp, requests, context) {
@@ -168,7 +179,7 @@ class TelepathyClient extends Tp.BaseClient {
}
context.accept();
}
},
_createChatSource(account, conn, channel, contact) {
if (this._chatSources[channel.get_object_path()])
@@ -180,13 +191,13 @@ class TelepathyClient extends Tp.BaseClient {
source.connect('destroy', () => {
delete this._chatSources[channel.get_object_path()];
});
}
},
vfunc_handle_channels(account, conn, channels, requests,
user_action_time, context) {
this._handlingChannels(account, conn, channels, true);
context.accept();
}
},
_handlingChannels(account, conn, channels, notify) {
let len = channels.length;
@@ -220,7 +231,7 @@ class TelepathyClient extends Tp.BaseClient {
source.notify();
}
}
}
},
vfunc_add_dispatch_operation(account, conn, channels,
dispatchOp, context) {
@@ -238,7 +249,7 @@ class TelepathyClient extends Tp.BaseClient {
else
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Unsupported channel type' }));
}
},
_approveTextChannel(account, conn, channel, dispatchOp, context) {
let [targetHandle, targetHandleType] = channel.get_handle();
@@ -260,22 +271,25 @@ class TelepathyClient extends Tp.BaseClient {
});
context.accept();
}
},
_delegatedChannelsCb(client, channels) {
// Nothing to do as we don't make a distinction between observed and
// handled channels.
}
},
}) : null;
var ChatSource = class extends MessageTray.Source {
constructor(account, conn, channel, contact, client) {
super(contact.get_alias());
var ChatSource = new Lang.Class({
Name: 'ChatSource',
Extends: MessageTray.Source,
_init(account, conn, channel, contact, client) {
this._account = account;
this._contact = contact;
this._client = client;
this.parent(contact.get_alias());
this.isChat = true;
this._pendingMessages = [];
@@ -299,7 +313,7 @@ var ChatSource = class extends MessageTray.Source {
Main.messageTray.add(this);
this._getLogMessages();
}
},
_ensureNotification() {
if (this._notification)
@@ -315,13 +329,13 @@ var ChatSource = class extends MessageTray.Source {
this._notification = null;
});
this.pushNotification(this._notification);
}
},
_createPolicy() {
if (this._account.protocol_name == 'irc')
return new MessageTray.NotificationApplicationPolicy('org.gnome.Polari');
return new MessageTray.NotificationApplicationPolicy('empathy');
}
},
createBanner() {
this._banner = new ChatNotificationBanner(this._notification);
@@ -334,7 +348,7 @@ var ChatSource = class extends MessageTray.Source {
});
return this._banner;
}
},
_updateAlias() {
let oldAlias = this.title;
@@ -346,7 +360,7 @@ var ChatSource = class extends MessageTray.Source {
this.setTitle(newAlias);
if (this._notification)
this._notification.appendAliasChange(oldAlias, newAlias);
}
},
getIcon() {
let file = this._contact.get_avatar_file();
@@ -355,7 +369,7 @@ var ChatSource = class extends MessageTray.Source {
} else {
return new Gio.ThemedIcon({ name: 'avatar-default' });
}
}
},
getSecondaryIcon() {
let iconName;
@@ -384,7 +398,7 @@ var ChatSource = class extends MessageTray.Source {
iconName = 'user-offline';
}
return new Gio.ThemedIcon({ name: iconName });
}
},
_updateAvatarIcon() {
this.iconUpdated();
@@ -392,7 +406,7 @@ var ChatSource = class extends MessageTray.Source {
this._notification.update(this._notification.title,
this._notification.bannerBodyText,
{ gicon: this.getIcon() });
}
},
open() {
Main.overview.hide();
@@ -417,7 +431,7 @@ var ChatSource = class extends MessageTray.Source {
cd.present_channel_async(this._channel, global.get_current_time(), null);
}
}
},
_getLogMessages() {
let logManager = Tpl.LogManager.dup_singleton();
@@ -426,7 +440,7 @@ var ChatSource = class extends MessageTray.Source {
logManager.get_filtered_events_async(this._account, entity,
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
null, this._displayPendingMessages.bind(this));
}
},
_displayPendingMessages(logManager, result) {
let [success, events] = logManager.get_filtered_events_finish(result);
@@ -479,7 +493,7 @@ var ChatSource = class extends MessageTray.Source {
if (pendingMessages.length > 0)
this.notify();
}
},
destroy(reason) {
if (this._client.is_handling_channel(this._channel)) {
@@ -513,25 +527,25 @@ var ChatSource = class extends MessageTray.Source {
this._contact.disconnect(this._notifyAvatarId);
this._contact.disconnect(this._presenceChangedId);
super.destroy(reason);
}
this.parent(reason);
},
_channelClosed() {
this.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
}
},
/* All messages are new messages for Telepathy sources */
get count() {
return this._pendingMessages.length;
}
},
get unseenCount() {
return this.count;
}
},
get countVisible() {
return this.count > 0;
}
},
_messageReceived(channel, message) {
if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT)
@@ -551,7 +565,7 @@ var ChatSource = class extends MessageTray.Source {
this._notifyTimeoutId = Mainloop.timeout_add(500,
this._notifyTimeout.bind(this));
GLib.Source.set_name_by_id(this._notifyTimeoutId, '[gnome-shell] this._notifyTimeout');
}
},
_notifyTimeout() {
if (this._pendingMessages.length != 0)
@@ -560,7 +574,7 @@ var ChatSource = class extends MessageTray.Source {
this._notifyTimeoutId = 0;
return GLib.SOURCE_REMOVE;
}
},
// This is called for both messages we send from
// our client and other clients as well.
@@ -568,11 +582,11 @@ var ChatSource = class extends MessageTray.Source {
this._ensureNotification();
message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
this._notification.appendMessage(message);
}
},
notify() {
super.notify(this._notification);
}
this.parent(this._notification);
},
respond(text) {
let type;
@@ -587,7 +601,7 @@ var ChatSource = class extends MessageTray.Source {
this._channel.send_message_async(msg, 0, (src, result) => {
this._channel.send_message_finish(result);
});
}
},
setChatState(state) {
// We don't want to send COMPOSING every time a letter is typed into
@@ -600,14 +614,14 @@ var ChatSource = class extends MessageTray.Source {
this._chatState = state;
this._channel.set_chat_state_async(state, null);
}
}
},
_presenceChanged(contact, presence, status, message) {
if (this._notification)
this._notification.update(this._notification.title,
this._notification.bannerBodyText,
{ secondaryGIcon: this.getSecondaryIcon() });
}
},
_pendingRemoved(channel, message) {
let idx = this._pendingMessages.indexOf(message);
@@ -620,32 +634,35 @@ var ChatSource = class extends MessageTray.Source {
if (this._pendingMessages.length == 0 &&
this._banner && !this._banner.expanded)
this._banner.hide();
}
},
_ackMessages() {
// Don't clear our messages here, tp-glib will send a
// 'pending-message-removed' for each one.
this._channel.ack_all_pending_messages_async(null);
}
};
});
var ChatNotification = class extends MessageTray.Notification {
constructor(source) {
super(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
var ChatNotification = new Lang.Class({
Name: 'ChatNotification',
Extends: MessageTray.Notification,
_init(source) {
this.parent(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
this.setUrgency(MessageTray.Urgency.HIGH);
this.setResident(true);
this.messages = [];
this._timestampTimeoutId = 0;
}
},
destroy(reason) {
if (this._timestampTimeoutId)
Mainloop.source_remove(this._timestampTimeoutId);
this._timestampTimeoutId = 0;
super.destroy(reason);
}
this.parent(reason);
},
/**
* appendMessage:
@@ -683,7 +700,7 @@ var ChatNotification = class extends MessageTray.Notification {
styles: styles,
timestamp: message.timestamp,
noTimestamp: noTimestamp });
}
},
_filterMessages() {
if (this.messages.length < 1)
@@ -708,7 +725,7 @@ var ChatNotification = class extends MessageTray.Notification {
for (let i = 0; i < expired.length; i++)
this.emit('message-removed', expired[i]);
}
}
},
/**
* _append:
@@ -756,7 +773,7 @@ var ChatNotification = class extends MessageTray.Notification {
}
this._filterMessages();
}
},
appendTimestamp() {
this._timestampTimeoutId = 0;
@@ -767,7 +784,7 @@ var ChatNotification = class extends MessageTray.Notification {
this._filterMessages();
return GLib.SOURCE_REMOVE;
}
},
appendAliasChange(oldAlias, newAlias) {
oldAlias = GLib.markup_escape_text(oldAlias, -1);
@@ -783,19 +800,24 @@ var ChatNotification = class extends MessageTray.Notification {
this._filterMessages();
}
};
});
var ChatLineBox = new Lang.Class({
Name: 'ChatLineBox',
Extends: St.BoxLayout,
var ChatLineBox = GObject.registerClass(
class ChatLineBox extends St.BoxLayout {
vfunc_get_preferred_height(forWidth) {
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [, natHeight] = this.parent(forWidth);
return [natHeight, natHeight];
}
});
var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
constructor(notification) {
super(notification);
var ChatNotificationBanner = new Lang.Class({
Name: 'ChatNotificationBanner',
Extends: MessageTray.NotificationBanner,
_init(notification) {
this.parent(notification);
this._responseEntry = new St.Entry({ style_class: 'chat-response',
x_expand: true,
@@ -813,8 +835,8 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
});
this._scrollArea = new St.ScrollView({ style_class: 'chat-scrollview vfade',
vscrollbar_policy: St.PolicyType.AUTOMATIC,
hscrollbar_policy: St.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER,
visible: this.expanded });
this._contentArea = new St.BoxLayout({ style_class: 'chat-body',
vertical: true });
@@ -858,14 +880,14 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
for (let i = this.notification.messages.length - 1; i >= 0; i--)
this._addMessage(this.notification.messages[i]);
}
},
_onDestroy() {
super._onDestroy();
this.parent();
this.notification.disconnect(this._messageAddedId);
this.notification.disconnect(this._messageRemovedId);
this.notification.disconnect(this._timestampChangedId);
}
},
scrollTo(side) {
let adjustment = this._scrollArea.vscroll.adjustment;
@@ -873,11 +895,11 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
adjustment.value = adjustment.lower;
else if (side == St.Side.BOTTOM)
adjustment.value = adjustment.upper;
}
},
hide() {
this.emit('done-displaying');
}
},
_addMessage(message) {
let highlighter = new MessageList.URLHighlighter(message.body, true, true);
@@ -899,7 +921,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
this._messageActors.set(message, lineBox);
this._updateTimestamp(message);
}
},
_updateTimestamp(message) {
let actor = this._messageActors.get(message);
@@ -920,7 +942,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
actor.add_actor(timeLabel);
}
}
},
_onEntryActivated() {
let text = this._responseEntry.get_text();
@@ -933,7 +955,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
// see Source._messageSent
this._responseEntry.set_text('');
this.notification.source.respond(text);
}
},
_composingStopTimeout() {
this._composingTimeoutId = 0;
@@ -941,7 +963,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
this.notification.source.setChatState(Tp.ChannelChatState.PAUSED);
return GLib.SOURCE_REMOVE;
}
},
_onEntryChanged() {
let text = this._responseEntry.get_text();
@@ -968,6 +990,6 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
}
}
};
});
var Component = TelepathyComponent;

View File

@@ -1,10 +1,16 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GObject, Meta, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const SwitcherPopup = imports.ui.switcherPopup;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
var POPUP_APPICON_SIZE = 96;
var POPUP_FADE_TIME = 0.1; // seconds
@@ -15,13 +21,15 @@ var SortGroup = {
BOTTOM: 2
};
var CtrlAltTabManager = class CtrlAltTabManager {
constructor() {
var CtrlAltTabManager = new Lang.Class({
Name: 'CtrlAltTabManager',
_init() {
this._items = [];
this.addGroup(global.window_group, _("Windows"),
'focus-windows-symbolic', { sortGroup: SortGroup.TOP,
focusCallback: this._focusWindows.bind(this) });
}
},
addGroup(root, name, icon, params) {
let item = Params.parse(params, { sortGroup: SortGroup.MIDDLE,
@@ -36,7 +44,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
root.connect('destroy', () => { this.removeGroup(root); });
if (root instanceof St.Widget)
global.focus_manager.add_group(root);
}
},
removeGroup(root) {
if (root instanceof St.Widget)
@@ -47,14 +55,14 @@ var CtrlAltTabManager = class CtrlAltTabManager {
return;
}
}
}
},
focusGroup(item, timestamp) {
if (item.focusCallback)
item.focusCallback(timestamp);
else
item.root.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
}
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
},
// Sort the items into a consistent order; panel first, tray last,
// and everything else in between, sorted by X coordinate, so that
@@ -69,7 +77,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
[bx, y] = b.proxy.get_transformed_position();
return ax - bx;
}
},
popup(backward, binding, mask) {
// Start with the set of focus groups that are currently mapped
@@ -94,9 +102,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
if (app)
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
else
icon = textureCache.bind_cairo_surface_property(windows[i],
'icon',
POPUP_APPICON_SIZE);
icon = textureCache.bind_cairo_surface_property(windows[i], 'icon');
}
items.push({ name: windows[i].title,
@@ -124,20 +130,22 @@ var CtrlAltTabManager = class CtrlAltTabManager {
this._popup = null;
});
}
}
},
_focusWindows(timestamp) {
global.display.focus_default_window(timestamp);
}
};
});
var CtrlAltTabPopup = new Lang.Class({
Name: 'CtrlAltTabPopup',
Extends: SwitcherPopup.SwitcherPopup,
var CtrlAltTabPopup = GObject.registerClass(
class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
_init(items) {
super._init(items);
this.parent(items);
this._switcherList = new CtrlAltTabSwitcher(this._items);
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_PANELS)
@@ -152,22 +160,24 @@ class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
},
_finish(time) {
super._finish(time);
this.parent(time);
Main.ctrlAltTabManager.focusGroup(this._items[this._selectedIndex], time);
}
},
});
var CtrlAltTabSwitcher = GObject.registerClass(
class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList {
var CtrlAltTabSwitcher = new Lang.Class({
Name: 'CtrlAltTabSwitcher',
Extends: SwitcherPopup.SwitcherList,
_init(items) {
super._init(true);
this.parent(true);
for (let i = 0; i < items.length; i++)
this._addIcon(items[i]);
}
},
_addIcon(item) {
let box = new St.BoxLayout({ style_class: 'alt-tab-app',

View File

@@ -1,8 +1,14 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
const Mainloop = imports.mainloop;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Signals = imports.signals;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Mainloop = imports.mainloop;
const AppDisplay = imports.ui.appDisplay;
const AppFavorites = imports.ui.appFavorites;
@@ -10,6 +16,7 @@ const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const Workspace = imports.ui.workspace;
var DASH_ANIMATION_TIME = 0.2;
var DASH_ITEM_LABEL_SHOW_TIME = 0.15;
@@ -26,10 +33,12 @@ function getAppFromSource(source) {
// A container like StBin, but taking the child's scale into account
// when requesting a size
var DashItemContainer = GObject.registerClass(
class DashItemContainer extends St.Widget {
var DashItemContainer = new Lang.Class({
Name: 'DashItemContainer',
Extends: St.Widget,
_init() {
super._init({ style_class: 'dash-item-container',
this.parent({ style_class: 'dash-item-container',
pivot_point: new Clutter.Point({ x: .5, y: .5 }),
x_expand: true,
x_align: Clutter.ActorAlign.CENTER });
@@ -50,23 +59,23 @@ class DashItemContainer extends St.Widget {
this.child.destroy();
this.label.destroy();
});
}
},
vfunc_get_preferred_height(forWidth) {
let themeNode = this.get_theme_node();
forWidth = themeNode.adjust_for_width(forWidth);
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [minHeight, natHeight] = this.parent(forWidth);
return themeNode.adjust_preferred_height(minHeight * this.scale_y,
natHeight * this.scale_y);
}
},
vfunc_get_preferred_width(forHeight) {
let themeNode = this.get_theme_node();
forHeight = themeNode.adjust_for_height(forHeight);
let [minWidth, natWidth] = super.vfunc_get_preferred_width(forHeight);
let [minWidth, natWidth] = this.parent(forHeight);
return themeNode.adjust_preferred_width(minWidth * this.scale_x,
natWidth * this.scale_x);
}
},
showLabel() {
if (!this._labelText)
@@ -100,12 +109,12 @@ class DashItemContainer extends St.Widget {
time: DASH_ITEM_LABEL_SHOW_TIME,
transition: 'easeOutQuad',
});
}
},
setLabelText(text) {
this._labelText = text;
this.child.accessible_name = text;
}
},
hideLabel() {
Tweener.addTween(this.label,
@@ -116,7 +125,7 @@ class DashItemContainer extends St.Widget {
this.label.hide();
}
});
}
},
setChild(actor) {
if (this.child == actor)
@@ -129,7 +138,7 @@ class DashItemContainer extends St.Widget {
this.set_scale(this._childScale, this._childScale);
this.set_opacity(this._childOpacity);
}
},
show(animate) {
if (this.child == null)
@@ -142,7 +151,7 @@ class DashItemContainer extends St.Widget {
time: time,
transition: 'easeOutQuad'
});
}
},
animateOutAndDestroy() {
this.label.hide();
@@ -162,35 +171,37 @@ class DashItemContainer extends St.Widget {
this.destroy();
}
});
}
},
set childScale(scale) {
this._childScale = scale;
this.set_scale(scale, scale);
this.queue_relayout();
}
},
get childScale() {
return this._childScale;
}
},
set childOpacity(opacity) {
this._childOpacity = opacity;
this.set_opacity(opacity);
this.queue_redraw();
}
},
get childOpacity() {
return this._childOpacity;
}
});
var ShowAppsIcon = GObject.registerClass(
class ShowAppsIcon extends DashItemContainer {
var ShowAppsIcon = new Lang.Class({
Name: 'ShowAppsIcon',
Extends: DashItemContainer,
_init() {
super._init();
this.parent();
this.toggleButton = new St.Button({ style_class: 'show-apps',
track_hover: true,
@@ -206,7 +217,7 @@ class ShowAppsIcon extends DashItemContainer {
this.setChild(this.toggleButton);
this.setDragApp(null);
}
},
_createIcon(size) {
this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
@@ -214,7 +225,7 @@ class ShowAppsIcon extends DashItemContainer {
style_class: 'show-apps-icon',
track_hover: true });
return this._iconActor;
}
},
_canRemoveApp(app) {
if (app == null)
@@ -226,7 +237,7 @@ class ShowAppsIcon extends DashItemContainer {
let id = app.get_id();
let isFavorite = AppFavorites.getAppFavorites().isFavorite(id);
return isFavorite;
}
},
setDragApp(app) {
let canRemove = this._canRemoveApp(app);
@@ -239,14 +250,14 @@ class ShowAppsIcon extends DashItemContainer {
this.setLabelText(_("Remove from Favorites"));
else
this.setLabelText(_("Show Applications"));
}
},
handleDragOver(source, actor, x, y, time) {
if (!this._canRemoveApp(getAppFromSource(source)))
return DND.DragMotionResult.NO_DROP;
return DND.DragMotionResult.MOVE_DROP;
}
},
acceptDrop(source, actor, x, y, time) {
let app = getAppFromSource(source);
@@ -264,30 +275,36 @@ class ShowAppsIcon extends DashItemContainer {
}
});
var DragPlaceholderItem = GObject.registerClass(
class DragPlaceholderItem extends DashItemContainer {
var DragPlaceholderItem = new Lang.Class({
Name: 'DragPlaceholderItem',
Extends: DashItemContainer,
_init() {
super._init();
this.parent();
this.setChild(new St.Bin({ style_class: 'placeholder' }));
}
});
var EmptyDropTargetItem = GObject.registerClass(
class EmptyDropTargetItem extends DashItemContainer {
var EmptyDropTargetItem = new Lang.Class({
Name: 'EmptyDropTargetItem',
Extends: DashItemContainer,
_init() {
super._init();
this.parent();
this.setChild(new St.Bin({ style_class: 'empty-dash-drop-target' }));
}
});
var DashActor = GObject.registerClass(
class DashActor extends St.Widget {
var DashActor = new Lang.Class({
Name: 'DashActor',
Extends: St.Widget,
_init() {
let layout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.VERTICAL });
super._init({ name: 'dash',
this.parent({ name: 'dash',
layout_manager: layout,
clip_to_allocation: true });
}
},
vfunc_allocate(box, flags) {
let contentBox = this.get_theme_node().get_content_box(box);
@@ -308,7 +325,7 @@ class DashActor extends St.Widget {
childBox.y1 = contentBox.y2 - showAppsNatHeight;
childBox.y2 = contentBox.y2;
showAppsButton.allocate(childBox, flags);
}
},
vfunc_get_preferred_height(forWidth) {
// We want to request the natural height of all our children
@@ -316,7 +333,7 @@ class DashActor extends St.Widget {
// then calls BoxLayout), but we only request the showApps
// button as the minimum size
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [, natHeight] = this.parent(forWidth);
let themeNode = this.get_theme_node();
let adjustedForWidth = themeNode.adjust_for_width(forWidth);
@@ -330,8 +347,10 @@ class DashActor extends St.Widget {
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
var Dash = class Dash {
constructor() {
var Dash = new Lang.Class({
Name: 'Dash',
_init() {
this._maxHeight = -1;
this.iconSize = 64;
this._shownInitially = false;
@@ -388,7 +407,7 @@ var Dash = class Dash {
// Translators: this is the name of the dock/favorites area on
// the left of the overview
Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
}
},
_onDragBegin() {
this._dragCancelled = false;
@@ -402,26 +421,26 @@ var Dash = class Dash {
this._box.insert_child_at_index(this._emptyDropTarget, 0);
this._emptyDropTarget.show(true);
}
}
},
_onDragCancelled() {
this._dragCancelled = true;
this._endDrag();
}
},
_onDragEnd() {
if (this._dragCancelled)
return;
this._endDrag();
}
},
_endDrag() {
this._clearDragPlaceholder();
this._clearEmptyDropTarget();
this._showAppsIcon.setDragApp(null);
DND.removeDragMonitor(this._dragMonitor);
}
},
_onDragMotion(dragEvent) {
let app = getAppFromSource(dragEvent.source);
@@ -440,18 +459,18 @@ var Dash = class Dash {
this._showAppsIcon.setDragApp(null);
return DND.DragMotionResult.CONTINUE;
}
},
_appIdListToHash(apps) {
let ids = {};
for (let i = 0; i < apps.length; i++)
ids[apps[i].get_id()] = apps[i];
return ids;
}
},
_queueRedisplay() {
Main.queueDeferredWork(this._workId);
}
},
_hookUpLabel(item, appIcon) {
item.child.connect('notify::hover', () => {
@@ -471,7 +490,7 @@ var Dash = class Dash {
this._syncLabel(item, appIcon);
});
}
}
},
_createAppItem(app) {
let appIcon = new AppDisplay.AppIcon(app,
@@ -505,7 +524,7 @@ var Dash = class Dash {
this._hookUpLabel(item, appIcon);
return item;
}
},
_itemMenuStateChanged(item, opened) {
// When the menu closes, it calls sync_hover, which means
@@ -518,7 +537,7 @@ var Dash = class Dash {
item.hideLabel();
}
}
},
_syncLabel(item, appIcon) {
let shouldShow = appIcon ? appIcon.shouldShowTooltip() : item.child.get_hover();
@@ -554,7 +573,7 @@ var Dash = class Dash {
GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing');
}
}
}
},
_adjustIconSize() {
// For the icon size, we only consider children which are "proper"
@@ -584,18 +603,22 @@ var Dash = class Dash {
let firstButton = iconChildren[0].child;
let firstIcon = firstButton._delegate.icon;
// Enforce valid spacings during the size request
let minHeight, natHeight;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
// Enforce the current icon size during the size request
firstIcon.icon.ensure_style();
let [, iconHeight] = firstIcon.icon.get_preferred_height(-1);
let [, buttonHeight] = firstButton.get_preferred_height(-1);
let [, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_height(this.iconSize * scaleFactor);
[minHeight, natHeight] = firstButton.get_preferred_height(-1);
firstIcon.icon.set_height(currentHeight);
// Subtract icon padding and box spacing from the available height
availHeight -= iconChildren.length * (buttonHeight - iconHeight) +
availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) +
(iconChildren.length - 1) * spacing;
let availSize = availHeight / iconChildren.length;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let iconSizes = baseIconSizes.map(s => s * scaleFactor);
let newIconSize = baseIconSizes[0];
@@ -640,7 +663,7 @@ var Dash = class Dash {
transition: 'easeOutQuad',
});
}
}
},
_redisplay() {
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
@@ -769,7 +792,7 @@ var Dash = class Dash {
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
// Without it, StBoxLayout may use a stale size cache
this._box.queue_relayout();
}
},
_clearDragPlaceholder() {
if (this._dragPlaceholder) {
@@ -781,14 +804,14 @@ var Dash = class Dash {
this._dragPlaceholder = null;
}
this._dragPlaceholderPos = -1;
}
},
_clearEmptyDropTarget() {
if (this._emptyDropTarget) {
this._emptyDropTarget.animateOutAndDestroy();
this._emptyDropTarget = null;
}
}
},
handleDragOver(source, actor, x, y, time) {
let app = getAppFromSource(source);
@@ -865,7 +888,7 @@ var Dash = class Dash {
return DND.DragMotionResult.MOVE_DROP;
return DND.DragMotionResult.COPY_DROP;
}
},
// Draggable target interface
acceptDrop(source, actor, x, y, time) {
@@ -915,5 +938,6 @@ var Dash = class Dash {
return true;
}
};
});
Signals.addSignalMethods(Dash.prototype);

View File

@@ -1,17 +1,29 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GLib, GnomeDesktop,
GObject, GWeather, Shell, St } = imports.gi;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Atk = imports.gi.Atk;
const Params = imports.misc.params;
const Util = imports.misc.util;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Calendar = imports.ui.calendar;
const Weather = imports.misc.weather;
const System = imports.system;
const MAX_FORECASTS = 5;
function _isToday(date) {
let now = new Date();
return now.getYear() == date.getYear() &&
@@ -19,8 +31,10 @@ function _isToday(date) {
now.getDate() == date.getDate();
}
var TodayButton = class TodayButton {
constructor(calendar) {
var TodayButton = new Lang.Class({
Name: 'TodayButton',
_init(calendar) {
// Having the ability to go to the current date if the user is already
// on the current date can be confusing. So don't make the button reactive
// until the selected date changes.
@@ -49,7 +63,7 @@ var TodayButton = class TodayButton {
// current date.
this.actor.reactive = !_isToday(date)
});
}
},
setDate(date) {
this._dayLabel.set_text(date.toLocaleFormat('%A'));
@@ -69,10 +83,12 @@ var TodayButton = class TodayButton {
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
}
};
});
var WorldClocksSection = class WorldClocksSection {
constructor() {
var WorldClocksSection = new Lang.Class({
Name: 'WorldClocksSection',
_init() {
this._clock = new GnomeDesktop.WallClock();
this._clockNotifyId = 0;
@@ -102,11 +118,11 @@ var WorldClocksSection = class WorldClocksSection {
this._clockAppMon.watchSetting('world-clocks',
this._clocksChanged.bind(this));
this._sync();
}
},
_sync() {
this.actor.visible = this._clockAppMon.available;
}
},
_clocksChanged(settings) {
this._grid.destroy_all_children();
@@ -118,7 +134,7 @@ var WorldClocksSection = class WorldClocksSection {
if (!clocks[i].location)
continue;
let l = world.deserialize(clocks[i].location);
if (l && l.get_timezone() != null)
if (l)
this._locations.push({ location: l });
}
@@ -136,37 +152,26 @@ var WorldClocksSection = class WorldClocksSection {
layout.attach(header, 0, 0, 2, 1);
this.actor.label_actor = header;
let localOffset = GLib.DateTime.new_now_local().get_utc_offset();
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i].location;
let name = l.get_city_name() || l.get_name();
let name = l.get_level() == GWeather.LocationLevel.NAMED_TIMEZONE ? l.get_name()
: l.get_city_name();
let label = new St.Label({ style_class: 'world-clocks-city',
text: name,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true });
let time = new St.Label({ style_class: 'world-clocks-time' });
let otherOffset = this._getTimeAtLocation(l).get_utc_offset();
let offset = (otherOffset - localOffset) / GLib.TIME_SPAN_HOUR;
let fmt = (Math.trunc(offset) == offset) ? '%s%.0f' : '%s%.1f';
let prefix = (offset >= 0) ? '+' : '-';
let tz = new St.Label({ style_class: 'world-clocks-timezone',
text: fmt.format(prefix, Math.abs(offset)),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER });
let time = new St.Label({ style_class: 'world-clocks-time',
x_align: Clutter.ActorAlign.END,
x_expand: true });
if (this._grid.text_direction == Clutter.TextDirection.RTL) {
layout.attach(tz, 0, i + 1, 1, 1);
layout.attach(time, 1, i + 1, 1, 1);
layout.attach(label, 2, i + 1, 1, 1);
layout.attach(time, 0, i + 1, 1, 1);
layout.attach(label, 1, i + 1, 1, 1);
} else {
layout.attach(label, 0, i + 1, 1, 1);
layout.attach(time, 1, i + 1, 1, 1);
layout.attach(tz, 2, i + 1, 1, 1);
}
this._locations[i].actor = time;
@@ -182,24 +187,22 @@ var WorldClocksSection = class WorldClocksSection {
this._clock.disconnect(this._clockNotifyId);
this._clockNotifyId = 0;
}
}
_getTimeAtLocation(location) {
let tz = GLib.TimeZone.new(location.get_timezone().get_tzid());
return GLib.DateTime.new_now(tz);
}
},
_updateLabels() {
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i];
let now = this._getTimeAtLocation(l.location);
let tz = GLib.TimeZone.new(l.location.get_timezone().get_tzid());
let now = GLib.DateTime.new_now(tz);
l.actor.text = Util.formatTime(now, { timeOnly: true });
}
}
};
});
var WeatherSection = class WeatherSection {
constructor() {
var WeatherSection = new Lang.Class({
Name: 'WeatherSection',
_init() {
this._weatherClient = new Weather.WeatherClient();
this.actor = new St.Button({ style_class: 'weather-button',
@@ -221,115 +224,111 @@ var WeatherSection = class WeatherSection {
this.actor.child = box;
let titleBox = new St.BoxLayout();
titleBox.add_child(new St.Label({ style_class: 'weather-header',
x_align: Clutter.ActorAlign.START,
x_expand: true,
text: _("Weather") }));
box.add_child(titleBox);
box.add_child(new St.Label({ style_class: 'weather-header',
x_align: Clutter.ActorAlign.START,
text: _("Weather") }));
this._titleLocation = new St.Label({ style_class: 'weather-header location',
x_align: Clutter.ActorAlign.END });
titleBox.add_child(this._titleLocation);
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
this._forecastGrid = new St.Widget({ style_class: 'weather-grid',
layout_manager: layout });
layout.hookup_style(this._forecastGrid);
box.add_child(this._forecastGrid);
this._conditionsLabel = new St.Label({ style_class: 'weather-conditions',
x_align: Clutter.ActorAlign.START });
this._conditionsLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._conditionsLabel.clutter_text.line_wrap = true;
box.add_child(this._conditionsLabel);
this._weatherClient.connect('changed', this._sync.bind(this));
this._sync();
}
},
_getInfos() {
_getSummary(info, capitalize=false) {
let options = capitalize ? GWeather.FormatOptions.SENTENCE_CAPITALIZATION
: GWeather.FormatOptions.NO_CAPITALIZATION;
let [ok, phenomenon, qualifier] = info.get_value_conditions();
if (ok)
return new GWeather.Conditions({ significant: true,
phenomenon,
qualifier }).to_string_full(options);
let [, sky] = info.get_value_sky();
return GWeather.Sky.to_string_full(sky, options);
},
_sameSummary(info1, info2) {
let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
let [ok2, phenom2, qualifier2] = info2.get_value_conditions();
if (ok1 || ok2)
return ok1 == ok2 && phenom1 == phenom2 && qualifier1 == qualifier2;
let [, sky1] = info1.get_value_sky();
let [, sky2] = info2.get_value_sky();
return sky1 == sky2;
},
_getSummaryText() {
let info = this._weatherClient.info;
let forecasts = info.get_forecast_list();
if (forecasts.length == 0) // No forecasts, just current conditions
return '%s.'.format(this._getSummary(info, true));
let current = info;
let infos = [info];
for (let i = 0; i < forecasts.length; i++) {
let [ok, timestamp] = forecasts[i].get_value_update();
let datetime = new Date(timestamp * 1000);
if (!_isToday(datetime))
if (!_isToday(new Date(timestamp * 1000)))
continue; // Ignore forecasts from other days
[ok, timestamp] = current.get_value_update();
let currenttime = new Date(timestamp * 1000);
if (currenttime.getHours() == datetime.getHours())
continue; // Enforce a minimum interval of 1h
if (this._sameSummary(current, forecasts[i]))
continue; // Ignore consecutive runs of equal summaries
current = forecasts[i];
if (infos.push(current) == MAX_FORECASTS)
break; // Use a maximum of five forecasts
if (infos.push(current) == 3)
break; // Use a maximum of three summaries
}
return infos;
}
_addForecasts() {
let layout = this._forecastGrid.layout_manager;
let fmt;
switch(infos.length) {
/* Translators: %s is a weather condition like "Clear sky"; see
libgweather for the possible condition strings. If at all
possible, the sentence should match the grammatical case etc. of
the inserted conditions. */
case 1: fmt = _("%s all day."); break;
let infos = this._getInfos();
if (this._forecastGrid.text_direction == Clutter.TextDirection.RTL)
infos.reverse();
/* Translators: %s is a weather condition like "Clear sky"; see
libgweather for the possible condition strings. If at all
possible, the sentence should match the grammatical case etc. of
the inserted conditions. */
case 2: fmt = _("%s, then %s later."); break;
let col = 0;
infos.forEach(fc => {
let [ok, timestamp] = fc.get_value_update();
let timeStr = Util.formatTime(new Date(timestamp * 1000), {
timeOnly: true
});
let icon = new St.Icon({ style_class: 'weather-forecast-icon',
icon_name: fc.get_symbolic_icon_name(),
x_align: Clutter.ActorAlign.CENTER,
x_expand: true });
let temp = new St.Label({ style_class: 'weather-forecast-temp',
text: fc.get_temp_summary(),
x_align: Clutter.ActorAlign.CENTER });
let time = new St.Label({ style_class: 'weather-forecast-time',
text: timeStr,
x_align: Clutter.ActorAlign.CENTER });
layout.attach(icon, col, 0, 1, 1);
layout.attach(temp, col, 1, 1, 1);
layout.attach(time, col, 2, 1, 1);
col++;
/* Translators: %s is a weather condition like "Clear sky"; see
libgweather for the possible condition strings. If at all
possible, the sentence should match the grammatical case etc. of
the inserted conditions. */
case 3: fmt = _("%s, then %s, followed by %s later."); break;
}
let summaries = infos.map((info, i) => {
let capitalize = i == 0 && fmt.startsWith('%s');
return this._getSummary(info, capitalize);
});
}
return String.prototype.format.apply(fmt, summaries);
},
_setStatusLabel(text) {
let layout = this._forecastGrid.layout_manager;
let label = new St.Label({ text });
layout.attach(label, 0, 0, 1, 1);
}
_getLabelText() {
if (!this._weatherClient.hasLocation)
return _("Select a location…");
_updateForecasts() {
this._forecastGrid.destroy_all_children();
if (!this._weatherClient.hasLocation) {
this._setStatusLabel(_("Select a location…"));
return;
}
if (this._weatherClient.loading)
return _("Loading…");
let info = this._weatherClient.info;
this._titleLocation.text = info.get_location().get_name();
if (this._weatherClient.loading) {
this._setStatusLabel(_("Loading…"));
return;
}
if (info.is_valid()) {
this._addForecasts();
return;
}
if (info.is_valid())
return this._getSummaryText() + ' ' +
/* Translators: %s is a temperature with unit, e.g. "23℃" */
_("Feels like %s.").format(info.get_apparent());
if (info.network_error())
this._setStatusLabel(_("Go online for weather information"));
else
this._setStatusLabel(_("Weather information is currently unavailable"));
}
return _("Go online for weather information");
return _("Weather information is currently unavailable");
},
_sync() {
this.actor.visible = this._weatherClient.available;
@@ -337,14 +336,14 @@ var WeatherSection = class WeatherSection {
if (!this.actor.visible)
return;
this._titleLocation.visible = this._weatherClient.hasLocation;
this._updateForecasts();
this._conditionsLabel.text = this._getLabelText();
}
};
});
var MessagesIndicator = class MessagesIndicator {
constructor() {
var MessagesIndicator = new Lang.Class({
Name: 'MessagesIndicator',
_init() {
this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
icon_size: 16,
visible: false, y_expand: true,
@@ -358,18 +357,18 @@ var MessagesIndicator = class MessagesIndicator {
let sources = Main.messageTray.getSources();
sources.forEach(source => { this._onSourceAdded(null, source); });
}
},
_onSourceAdded(tray, source) {
source.connect('count-updated', this._updateCount.bind(this));
this._sources.push(source);
this._updateCount();
}
},
_onSourceRemoved(tray, source) {
this._sources.splice(this._sources.indexOf(source), 1);
this._updateCount();
}
},
_updateCount() {
let count = 0;
@@ -378,39 +377,42 @@ var MessagesIndicator = class MessagesIndicator {
this.actor.visible = (count > 0);
}
};
});
var IndicatorPad = new Lang.Class({
Name: 'IndicatorPad',
Extends: St.Widget,
var IndicatorPad = GObject.registerClass(
class IndicatorPad extends St.Widget {
_init(actor) {
this._source = actor;
this._source.connect('notify::visible', () => { this.queue_relayout(); });
this._source.connect('notify::size', () => { this.queue_relayout(); });
super._init();
}
this.parent();
},
vfunc_get_preferred_width(forHeight) {
vfunc_get_preferred_width(container, forHeight) {
if (this._source.visible)
return this._source.get_preferred_width(forHeight);
return [0, 0];
}
},
vfunc_get_preferred_height(forWidth) {
vfunc_get_preferred_height(container, forWidth) {
if (this._source.visible)
return this._source.get_preferred_height(forWidth);
return [0, 0];
}
});
var FreezableBinLayout = GObject.registerClass(
class FreezableBinLayout extends Clutter.BinLayout {
var FreezableBinLayout = new Lang.Class({
Name: 'FreezableBinLayout',
Extends: Clutter.BinLayout,
_init() {
super._init();
this.parent();
this._frozen = false;
this._savedWidth = [NaN, NaN];
this._savedHeight = [NaN, NaN];
}
},
set frozen(v) {
if (this._frozen == v)
@@ -419,22 +421,22 @@ class FreezableBinLayout extends Clutter.BinLayout {
this._frozen = v;
if (!this._frozen)
this.layout_changed();
}
},
vfunc_get_preferred_width(container, forHeight) {
if (!this._frozen || this._savedWidth.some(isNaN))
return super.vfunc_get_preferred_width(container, forHeight);
return this.parent(container, forHeight);
return this._savedWidth;
}
},
vfunc_get_preferred_height(container, forWidth) {
if (!this._frozen || this._savedHeight.some(isNaN))
return super.vfunc_get_preferred_height(container, forWidth);
return this.parent(container, forWidth);
return this._savedHeight;
}
},
vfunc_allocate(container, allocation, flags) {
super.vfunc_allocate(container, allocation, flags);
this.parent(container, allocation, flags);
let [width, height] = allocation.get_size();
this._savedWidth = [width, width];
@@ -442,22 +444,26 @@ class FreezableBinLayout extends Clutter.BinLayout {
}
});
var CalendarColumnLayout = GObject.registerClass(
class CalendarColumnLayout extends Clutter.BoxLayout {
var CalendarColumnLayout = new Lang.Class({
Name: 'CalendarColumnLayout',
Extends: Clutter.BoxLayout,
_init(actor) {
super._init({ orientation: Clutter.Orientation.VERTICAL });
this.parent({ orientation: Clutter.Orientation.VERTICAL });
this._calActor = actor;
}
},
vfunc_get_preferred_width(container, forHeight) {
if (!this._calActor || this._calActor.get_parent() != container)
return super.vfunc_get_preferred_width(container, forHeight);
return this.parent(container, forHeight);
return this._calActor.get_preferred_width(forHeight);
}
});
var DateMenuButton = GObject.registerClass(
class DateMenuButton extends PanelMenu.Button {
var DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
Extends: PanelMenu.Button,
_init() {
let item;
let hbox;
@@ -466,7 +472,7 @@ class DateMenuButton extends PanelMenu.Button {
let menuAlignment = 0.5;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
super._init(menuAlignment);
this.parent(menuAlignment);
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator();
@@ -476,9 +482,10 @@ class DateMenuButton extends PanelMenu.Button {
box.add_actor(this._clockDisplay);
box.add_actor(this._indicator.actor);
this.label_actor = this._clockDisplay;
this.add_actor(box);
this.add_style_class_name ('clock-display');
this.actor.label_actor = this._clockDisplay;
this.actor.add_actor(box);
this.actor.add_style_class_name ('clock-display');
let layout = new FreezableBinLayout();
let bin = new St.Widget({ layout_manager: layout });
@@ -525,7 +532,7 @@ class DateMenuButton extends PanelMenu.Button {
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true, x_fill: true,
overlay_scrollbars: true });
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._displaysSection.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
vbox.add_actor(this._displaysSection);
let displaysBox = new St.BoxLayout({ vertical: true,
@@ -546,11 +553,11 @@ class DateMenuButton extends PanelMenu.Button {
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
}
},
_getEventSource() {
return new Calendar.DBusEventSource();
}
},
_setEventSource(eventSource) {
if (this._eventSource)
@@ -560,7 +567,7 @@ class DateMenuButton extends PanelMenu.Button {
this._messageList.setEventSource(eventSource);
this._eventSource = eventSource;
}
},
_updateTimeZone() {
// SpiderMonkey caches the time zone so we must explicitly clear it
@@ -569,7 +576,7 @@ class DateMenuButton extends PanelMenu.Button {
System.clearDateCaches();
this._calendar.updateTimeZone();
}
},
_sessionUpdated() {
let eventSource;

View File

@@ -1,11 +1,18 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GObject, Pango, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Lang = imports.lang;
var Dialog = new Lang.Class({
Name: 'Dialog',
Extends: St.Widget,
var Dialog = GObject.registerClass(
class Dialog extends St.Widget {
_init(parentActor, styleClass) {
super._init({ layout_manager: new Clutter.BinLayout() });
this.parent({ layout_manager: new Clutter.BinLayout() });
this.connect('destroy', this._onDestroy.bind(this));
this._initialKeyFocus = null;
@@ -21,7 +28,7 @@ class Dialog extends St.Widget {
this._parentActor = parentActor;
this._eventId = this._parentActor.connect('event', this._modalEventHandler.bind(this));
this._parentActor.add_child(this);
}
},
_createDialog() {
this._dialog = new St.BoxLayout({ style_class: 'modal-dialog',
@@ -48,13 +55,13 @@ class Dialog extends St.Widget {
this._dialog.add(this.buttonLayout,
{ x_align: St.Align.MIDDLE,
y_align: St.Align.START });
}
},
_onDestroy() {
if (this._eventId != 0)
this._parentActor.disconnect(this._eventId);
this._eventId = 0;
}
},
_modalEventHandler(actor, event) {
if (event.type() == Clutter.EventType.KEY_PRESS) {
@@ -80,7 +87,7 @@ class Dialog extends St.Widget {
}
return Clutter.EVENT_PROPAGATE;
}
},
_setInitialKeyFocus(actor) {
if (this._initialKeyFocus)
@@ -92,15 +99,15 @@ class Dialog extends St.Widget {
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
});
}
},
get initialKeyFocus() {
return this._initialKeyFocus || this;
}
},
addContent(actor) {
this.contentLayout.add (actor, { expand: true });
}
},
addButton(buttonInfo) {
let { label, action, key } = buttonInfo;
@@ -137,15 +144,17 @@ class Dialog extends St.Widget {
this.buttonLayout.add_actor(button);
return button;
}
},
clearButtons() {
this.buttonLayout.destroy_all_children();
this._buttonKeys = {};
}
},
});
var MessageDialogContent = GObject.registerClass({
var MessageDialogContent = new Lang.Class({
Name: 'MessageDialogContent',
Extends: St.BoxLayout,
Properties: {
'icon': GObject.ParamSpec.object('icon', 'icon', 'icon',
GObject.ParamFlags.READWRITE |
@@ -163,8 +172,8 @@ var MessageDialogContent = GObject.registerClass({
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT,
null)
}
}, class MessageDialogContent extends St.BoxLayout {
},
_init(params) {
this._icon = new St.Icon({ y_align: Clutter.ActorAlign.START });
this._title = new St.Label({ style_class: 'headline' });
@@ -175,15 +184,15 @@ var MessageDialogContent = GObject.registerClass({
this[`_${prop}`].add_style_class_name(`message-dialog-${prop}`);
});
let textProps = { ellipsize: Pango.EllipsizeMode.NONE,
let textProps = { ellipsize_mode: Pango.EllipsizeMode.NONE,
line_wrap: true };
this._subtitle.clutter_text.set(textProps);
this._body.clutter_text.set(textProps);
Object.assign(this._subtitle.clutter_text, textProps);
Object.assign(this._body.clutter_text, textProps);
if (!params.hasOwnProperty('style_class'))
params.style_class = 'message-dialog-main-layout';
super._init(params);
this.parent(params);
this.messageBox = new St.BoxLayout({ style_class: 'message-dialog-content',
x_expand: true,
@@ -195,45 +204,45 @@ var MessageDialogContent = GObject.registerClass({
this.add_actor(this._icon);
this.add_actor(this.messageBox);
}
},
get icon() {
return this._icon.gicon;
}
},
get title() {
return this._title.text;
}
},
get subtitle() {
return this._subtitle.text;
}
},
get body() {
return this._body.text;
}
},
set icon(icon) {
Object.assign(this._icon, { gicon: icon, visible: icon != null });
this.notify('icon');
}
},
set title(title) {
this._setLabel(this._title, 'title', title);
}
},
set subtitle(subtitle) {
this._setLabel(this._subtitle, 'subtitle', subtitle);
}
},
set body(body) {
this._setLabel(this._body, 'body', body);
}
},
_setLabel(label, prop, value) {
Object.assign(label, { text: value || '', visible: value != null });
this.notify(prop);
}
},
insertBeforeBody(actor) {
this.messageBox.insert_child_below(actor, this._body);

View File

@@ -1,11 +1,17 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GLib, Meta, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const St = imports.gi.St;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const Main = imports.ui.main;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
const Params = imports.misc.params;
// Time to scale down to maxDragActorSize
var SCALE_ANIMATION_TIME = 0.25;
@@ -68,8 +74,10 @@ function removeDragMonitor(monitor) {
}
}
var _Draggable = class _Draggable {
constructor(actor, params) {
var _Draggable = new Lang.Class({
Name: 'Draggable',
_init(actor, params) {
params = Params.parse(params, { manualMode: false,
restoreOnSuccess: false,
dragActorMaxSize: undefined,
@@ -104,8 +112,7 @@ var _Draggable = class _Draggable {
this._dragCancellable = true;
this._eventsGrabbed = false;
this._capturedEventId = 0;
}
},
_onButtonPress(actor, event) {
if (event.get_button() != 1)
@@ -115,26 +122,16 @@ var _Draggable = class _Draggable {
return Clutter.EVENT_PROPAGATE;
this._buttonDown = true;
this._grabActor(event.get_device());
this._grabActor();
let [stageX, stageY] = event.get_coords();
this._dragStartX = stageX;
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
}
},
_onTouchEvent(actor, event) {
// We only handle touch events here on wayland. On X11
// we do get emulated pointer events, which already works
// for single-touch cases. Besides, the X11 passive touch grab
// set up by Mutter will make us see first the touch events
// and later the pointer events, so it will look like two
// unrelated series of events, we want to avoid double handling
// in these cases.
if (!Meta.is_wayland_compositor())
return Clutter.EVENT_PROPAGATE;
if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE;
@@ -142,40 +139,31 @@ var _Draggable = class _Draggable {
if (Tweener.getTweenCount(actor))
return Clutter.EVENT_PROPAGATE;
this._touchSequence = event.get_event_sequence();
this._buttonDown = true;
this._grabActor(event.get_device(), event.get_event_sequence());
this._grabActor();
let [stageX, stageY] = event.get_coords();
this._dragStartX = stageX;
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
}
},
_grabDevice(actor, pointer, touchSequence) {
if (touchSequence)
pointer.sequence_grab(touchSequence, actor);
_grabDevice(actor) {
let manager = Clutter.DeviceManager.get_default();
let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
if (pointer && this._touchSequence)
pointer.sequence_grab(this._touchSequence, actor);
else if (pointer)
pointer.grab (actor);
this._grabbedDevice = pointer;
this._touchSequence = touchSequence;
this._capturedEventId = global.stage.connect('captured-event', (actor, event) => {
let device = event.get_device();
if (device != this._grabbedDevice &&
device.get_device_type() != Clutter.InputDeviceType.KEYBOARD_DEVICE)
return Clutter.EVENT_STOP;
return Clutter.EVENT_PROPAGATE;
});
}
},
_ungrabDevice() {
if (this._capturedEventId != 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
if (this._touchSequence)
this._grabbedDevice.sequence_ungrab (this._touchSequence);
else
@@ -183,13 +171,13 @@ var _Draggable = class _Draggable {
this._touchSequence = null;
this._grabbedDevice = null;
}
},
_grabActor(device, touchSequence) {
this._grabDevice(this.actor, device, touchSequence);
_grabActor() {
this._grabDevice(this.actor);
this._onEventId = this.actor.connect('event',
this._onEvent.bind(this));
}
},
_ungrabActor() {
if (!this._onEventId)
@@ -198,15 +186,15 @@ var _Draggable = class _Draggable {
this._ungrabDevice();
this.actor.disconnect(this._onEventId);
this._onEventId = null;
}
},
_grabEvents(device, touchSequence) {
_grabEvents() {
if (!this._eventsGrabbed) {
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
if (this._eventsGrabbed)
this._grabDevice(_getEventHandlerActor(), device, touchSequence);
this._grabDevice(_getEventHandlerActor());
}
}
},
_ungrabEvents() {
if (this._eventsGrabbed) {
@@ -214,38 +202,16 @@ var _Draggable = class _Draggable {
Main.popModal(_getEventHandlerActor());
this._eventsGrabbed = false;
}
}
_eventIsRelease(event) {
if (event.type() == Clutter.EventType.BUTTON_RELEASE) {
let buttonMask = (Clutter.ModifierType.BUTTON1_MASK |
Clutter.ModifierType.BUTTON2_MASK |
Clutter.ModifierType.BUTTON3_MASK);
/* We only obey the last button release from the device,
* other buttons may get pressed/released during the DnD op.
*/
return (event.get_state() & buttonMask) == 0;
} else if (event.type() == Clutter.EventType.TOUCH_END) {
/* For touch, we only obey the pointer emulating sequence */
return global.display.is_pointer_emulating_sequence(event.get_event_sequence());
}
return false;
}
},
_onEvent(actor, event) {
let device = event.get_device();
if (this._grabbedDevice &&
device != this._grabbedDevice &&
device.get_device_type() != Clutter.InputDeviceType.KEYBOARD_DEVICE)
return Clutter.EVENT_PROPAGATE;
// We intercept BUTTON_RELEASE event to know that the button was released in case we
// didn't start the drag, to drop the draggable in case the drag was in progress, and
// to complete the drag and ensure that whatever happens to be under the pointer does
// not get triggered if the drag was cancelled with Esc.
if (this._eventIsRelease(event)) {
if (event.type() == Clutter.EventType.BUTTON_RELEASE ||
(event.type() == Clutter.EventType.TOUCH_END &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
this._buttonDown = false;
if (this._dragState == DragState.DRAGGING) {
return this._dragActorDropped(event);
@@ -280,7 +246,7 @@ var _Draggable = class _Draggable {
}
return Clutter.EVENT_PROPAGATE;
}
},
/**
* fakeRelease:
@@ -293,7 +259,7 @@ var _Draggable = class _Draggable {
fakeRelease() {
this._buttonDown = false;
this._ungrabActor();
}
},
/**
* startDrag:
@@ -305,22 +271,7 @@ var _Draggable = class _Draggable {
* This function is useful to call if you've specified manualMode
* for the draggable.
*/
startDrag(stageX, stageY, time, sequence, device) {
if (currentDraggable)
return;
if (device == undefined) {
let event = Clutter.get_current_event();
if (event)
device = event.get_device();
if (device == undefined) {
let manager = Clutter.DeviceManager.get_default();
device = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
}
}
startDrag(stageX, stageY, time, sequence) {
currentDraggable = this;
this._dragState = DragState.DRAGGING;
@@ -335,7 +286,8 @@ var _Draggable = class _Draggable {
if (this._onEventId)
this._ungrabActor();
this._grabEvents(device, sequence);
this._touchSequence = sequence;
this._grabEvents();
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
this._dragX = this._dragStartX = stageX;
@@ -403,8 +355,7 @@ var _Draggable = class _Draggable {
this._finishAnimation();
this._dragActor = null;
if (this._dragState == DragState.DRAGGING)
this._dragState = DragState.CANCELLED;
this._dragState = DragState.CANCELLED;
});
this._dragOrigOpacity = this._dragActor.opacity;
if (this._dragActorOpacity != undefined)
@@ -444,33 +395,26 @@ var _Draggable = class _Draggable {
onUpdateScope: this });
}
}
}
},
_maybeStartDrag(event) {
let [stageX, stageY] = event.get_coords();
// See if the user has moved the mouse enough to trigger a drag
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let threshold = St.Settings.get().drag_threshold * scaleFactor;
if (!currentDraggable &&
(Math.abs(stageX - this._dragStartX) > threshold ||
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
if ((Math.abs(stageX - this._dragStartX) > threshold ||
Math.abs(stageY - this._dragStartY) > threshold)) {
this.startDrag(stageX, stageY, event.get_time(), this._touchSequence, event.get_device());
this.startDrag(stageX, stageY, event.get_time(), this._touchSequence);
this._updateDragPosition(event);
}
return true;
}
_pickTargetActor() {
return this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
}
},
_updateDragHover() {
this._updateHoverId = 0;
let target = this._pickTargetActor();
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
let dragEvent = {
x: this._dragX,
y: this._dragY,
@@ -478,18 +422,6 @@ var _Draggable = class _Draggable {
source: this.actor._delegate,
targetActor: target
};
let targetActorDestroyHandlerId;
let handleTargetActorDestroyClosure;
handleTargetActorDestroyClosure = () => {
target = this._pickTargetActor();
dragEvent.targetActor = target;
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
};
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
for (let i = 0; i < dragMonitors.length; i++) {
let motionFunc = dragMonitors[i].dragMotion;
if (motionFunc) {
@@ -500,7 +432,6 @@ var _Draggable = class _Draggable {
}
}
}
dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
while (target) {
if (target._delegate && target._delegate.handleDragOver) {
@@ -522,7 +453,7 @@ var _Draggable = class _Draggable {
}
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
return GLib.SOURCE_REMOVE;
}
},
_queueUpdateDragHover() {
if (this._updateHoverId)
@@ -531,7 +462,7 @@ var _Draggable = class _Draggable {
this._updateHoverId = GLib.idle_add(GLib.PRIORITY_DEFAULT,
this._updateDragHover.bind(this));
GLib.Source.set_name_by_id(this._updateHoverId, '[gnome-shell] this._updateDragHover');
}
},
_updateDragPosition(event) {
let [stageX, stageY] = event.get_coords();
@@ -542,7 +473,7 @@ var _Draggable = class _Draggable {
this._queueUpdateDragHover();
return true;
}
},
_dragActorDropped(event) {
let [dropX, dropY] = event.get_coords();
@@ -605,7 +536,7 @@ var _Draggable = class _Draggable {
this._cancelDrag(event.get_time());
return true;
}
},
_getRestoreLocation() {
let x, y, scale;
@@ -637,7 +568,7 @@ var _Draggable = class _Draggable {
}
return [x, y, scale];
}
},
_cancelDrag(eventTime) {
this.emit('drag-cancelled', eventTime);
@@ -664,7 +595,7 @@ var _Draggable = class _Draggable {
scale_y: snapBackScale,
time: SNAP_BACK_ANIMATION_TIME,
});
}
},
_restoreDragActor(eventTime) {
this._dragState = DragState.INIT;
@@ -677,7 +608,7 @@ var _Draggable = class _Draggable {
this._animateDragEnd(eventTime,
{ time: REVERT_ANIMATION_TIME });
}
},
_animateDragEnd(eventTime, params) {
this._animationInProgress = true;
@@ -690,7 +621,7 @@ var _Draggable = class _Draggable {
// start the animation
Tweener.addTween(this._dragActor, params)
}
},
_finishAnimation() {
if (!this._animationInProgress)
@@ -701,7 +632,7 @@ var _Draggable = class _Draggable {
this._dragComplete();
global.display.set_cursor(Meta.Cursor.DEFAULT);
}
},
_onAnimationComplete(dragActor, eventTime) {
if (this._dragOrigParent) {
@@ -715,7 +646,7 @@ var _Draggable = class _Draggable {
this.emit('drag-end', eventTime, false);
this._finishAnimation();
}
},
_dragComplete() {
if (!this._actorDestroyed && this._dragActor)
@@ -737,7 +668,8 @@ var _Draggable = class _Draggable {
this._dragState = DragState.INIT;
currentDraggable = null;
}
};
});
Signals.addSignalMethods(_Draggable.prototype);
/**

View File

@@ -1,32 +1,38 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GObject, Meta, St } = imports.gi;
const Lang = imports.lang;
const Signals = imports.signals;
const Meta = imports.gi.Meta;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Main = imports.ui.main;
var EDGE_THRESHOLD = 20;
var DRAG_DISTANCE = 80;
var EdgeDragAction = GObject.registerClass({
var EdgeDragAction = new Lang.Class({
Name: 'EdgeDragAction',
Extends: Clutter.GestureAction,
Signals: { 'activated': {} },
}, class EdgeDragAction extends Clutter.GestureAction {
_init(side, allowedModes) {
super._init();
this.parent();
this._side = side;
this._allowedModes = allowedModes;
this.set_n_touch_points(1);
global.display.connect('grab-op-begin', () => { this.cancel(); });
}
},
_getMonitorRect(x, y) {
let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
let monitorIndex = global.display.get_monitor_index_for_rect(rect);
return global.display.get_monitor_geometry(monitorIndex);
}
},
vfunc_gesture_prepare(actor) {
vfunc_gesture_prepare(action, actor) {
if (this.get_n_current_points() == 0)
return false;
@@ -40,9 +46,9 @@ var EdgeDragAction = GObject.registerClass({
(this._side == St.Side.RIGHT && x > monitorRect.x + monitorRect.width - EDGE_THRESHOLD) ||
(this._side == St.Side.TOP && y < monitorRect.y + EDGE_THRESHOLD) ||
(this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
}
},
vfunc_gesture_progress(actor) {
vfunc_gesture_progress(action, actor) {
let [startX, startY] = this.get_press_coords(0);
let [x, y] = this.get_motion_coords(0);
let offsetX = Math.abs (x - startX);
@@ -60,9 +66,9 @@ var EdgeDragAction = GObject.registerClass({
}
return true;
}
},
vfunc_gesture_end(actor) {
vfunc_gesture_end(action, actor) {
let [startX, startY] = this.get_press_coords(0);
let [x, y] = this.get_motion_coords(0);
let monitorRect = this._getMonitorRect(startX, startY);

View File

@@ -16,15 +16,24 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const { AccountsService, Clutter, Gio,
GLib, Pango, Polkit, Shell, St } = imports.gi;
const AccountsService = imports.gi.AccountsService;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const Polkit = imports.gi.Polkit;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const CheckBox = imports.ui.checkBox;
const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager;
const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
const { loadInterfaceXML } = imports.misc.fileUtils;
@@ -226,10 +235,13 @@ function init() {
_endSessionDialog = new EndSessionDialog();
}
var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'end-session-dialog',
destroyOnClose: false });
var EndSessionDialog = new Lang.Class({
Name: 'EndSessionDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'end-session-dialog',
destroyOnClose: false });
this._loginManager = LoginManager.getLoginManager();
this._userManager = AccountsService.UserManager.get_default();
@@ -312,7 +324,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
messageLayout.add(this._batteryWarning);
this._scrollView = new St.ScrollView({ style_class: 'end-session-dialog-list' });
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.contentLayout.add(this._scrollView,
{ x_fill: true,
y_fill: true });
@@ -344,12 +356,12 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
}
},
_onDestroy() {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
}
},
_sync() {
let open = (this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED);
@@ -422,7 +434,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
this._scrollView.visible = hasApplications || hasSessions;
this._applicationHeader.visible = hasApplications;
this._sessionHeader.visible = hasSessions;
}
},
_updateButtons() {
let dialogContent = DialogContent[this._type];
@@ -444,20 +456,20 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
this.setButtons(buttons);
}
},
close(skipSignal) {
super.close();
this.parent();
if (!skipSignal)
this._dbusImpl.emit_signal('Closed', null);
}
},
cancel() {
this._stopTimer();
this._dbusImpl.emit_signal('Canceled', null);
this.close();
}
},
_confirm(signal) {
let callback = () => {
@@ -492,11 +504,11 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
} else {
this._triggerOfflineUpdateCancel(callback);
}
}
},
_onOpened() {
this._sync();
}
},
_triggerOfflineUpdateReboot(callback) {
this._pkOfflineProxy.TriggerRemote('reboot', (result, error) => {
@@ -505,7 +517,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
callback();
});
}
},
_triggerOfflineUpdateShutdown(callback) {
this._pkOfflineProxy.TriggerRemote('power-off', (result, error) => {
@@ -514,7 +526,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
callback();
});
}
},
_triggerOfflineUpdateCancel(callback) {
this._pkOfflineProxy.CancelRemote((result, error) => {
@@ -523,7 +535,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
callback();
});
}
},
_startTimer() {
let startTime = GLib.get_monotonic_time();
@@ -547,7 +559,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timerId, '[gnome-shell] this._confirm');
}
},
_stopTimer() {
if (this._timerId > 0) {
@@ -556,7 +568,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
this._secondsLeft = 0;
}
},
_constructListItemForApp(inhibitor, app) {
let actor = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item',
@@ -581,7 +593,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
return actor;
}
},
_onInhibitorLoaded(inhibitor) {
if (this._applications.indexOf(inhibitor) < 0) {
@@ -600,7 +612,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
this._sync();
}
},
_constructListItemForSession(session) {
let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
@@ -630,7 +642,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
actor.label_actor = nameLabel;
return actor;
}
},
_loadSessions() {
this._loginManager.listSessions(result => {
@@ -672,7 +684,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
this._sync();
});
}
},
OpenAsync(parameters, invocation) {
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
@@ -742,9 +754,9 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
invocation.return_value(null);
this.disconnect(signalId);
});
}
},
Close(parameters, invocation) {
this.close();
}
};
});

View File

@@ -4,13 +4,19 @@ const Config = imports.misc.config;
imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION;
imports.gi.versions.Gio = '2.0';
imports.gi.versions.Gdk = '3.0';
imports.gi.versions.GdkPixbuf = '2.0';
imports.gi.versions.Gtk = '3.0';
imports.gi.versions.TelepathyGLib = '0.12';
imports.gi.versions.TelepathyLogger = '0.2';
const { Clutter, GLib, Shell, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
// We can't import shell JS modules yet, because they may have
// variable initializations, etc, that depend on init() already having
@@ -96,15 +102,6 @@ function init() {
Clutter.Actor.prototype.toString = function() {
return St.describe_actor(this);
};
// Deprecation warning for former JS classes turned into an actor subclass
Object.defineProperty(Clutter.Actor.prototype, 'actor', {
get() {
let klass = this.constructor.name;
let { stack } = new Error();
log(`Usage of object.actor is deprecated for ${klass}\n${stack}`);
return this;
}
});
let origToString = Object.prototype.toString;
Object.prototype.toString = function() {

View File

@@ -1,6 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, Gio, GLib, Soup, St } = imports.gi;
const Lang = imports.lang;
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Soup = imports.gi.Soup;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
@@ -176,10 +183,12 @@ function checkForUpdates() {
});
}
var InstallExtensionDialog =
class InstallExtensionDialog extends ModalDialog.ModalDialog {
constructor(uuid, info, invocation) {
super({ styleClass: 'extension-dialog' });
var InstallExtensionDialog = new Lang.Class({
Name: 'InstallExtensionDialog',
Extends: ModalDialog.ModalDialog,
_init(uuid, info, invocation) {
this.parent({ styleClass: 'extension-dialog' });
this._uuid = uuid;
this._info = info;
@@ -207,12 +216,12 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
let label = new St.Label({ style_class: 'message-dialog-title headline',
text: message });
box.add(label);
}
},
_onCancelButtonPressed(button, event) {
this.close();
this._invocation.return_value(GLib.Variant.new('(s)', ['cancelled']));
}
},
_onInstallButtonPressed(button, event) {
let params = { shell_version: Config.PACKAGE_VERSION };
@@ -255,7 +264,7 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
this.close();
}
};
});
function init() {
_httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });

View File

@@ -1,8 +1,12 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, St } = imports.gi;
const Lang = imports.lang;
const Signals = imports.signals;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const St = imports.gi.St;
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;

View File

@@ -22,26 +22,29 @@
*/
const Atspi = imports.gi.Atspi;
const Lang = imports.lang;
const Signals = imports.signals;
const CARETMOVED = 'object:text-caret-moved';
const STATECHANGED = 'object:state-changed';
var FocusCaretTracker = class FocusCaretTracker {
constructor() {
var FocusCaretTracker = new Lang.Class({
Name: 'FocusCaretTracker',
_init() {
this._atspiListener = Atspi.EventListener.new(this._onChanged.bind(this));
this._atspiInited = false;
this._focusListenerRegistered = false;
this._caretListenerRegistered = false;
}
},
_onChanged(event) {
if (event.type.indexOf(STATECHANGED) == 0)
this.emit('focus-changed', event);
else if (event.type == CARETMOVED)
this.emit('caret-moved', event);
}
},
_initAtspi() {
if (!this._atspiInited && Atspi.init() == 0) {
@@ -50,7 +53,7 @@ var FocusCaretTracker = class FocusCaretTracker {
}
return this._atspiInited;
}
},
registerFocusListener() {
if (!this._initAtspi() || this._focusListenerRegistered)
@@ -59,7 +62,7 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.register(STATECHANGED + ':focused');
this._atspiListener.register(STATECHANGED + ':selected');
this._focusListenerRegistered = true;
}
},
registerCaretListener() {
if (!this._initAtspi() || this._caretListenerRegistered)
@@ -67,7 +70,7 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.register(CARETMOVED);
this._caretListenerRegistered = true;
}
},
deregisterFocusListener() {
if (!this._focusListenerRegistered)
@@ -76,7 +79,7 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.deregister(STATECHANGED + ':focused');
this._atspiListener.deregister(STATECHANGED + ':selected');
this._focusListenerRegistered = false;
}
},
deregisterCaretListener() {
if (!this._caretListenerRegistered)
@@ -85,5 +88,5 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.deregister(CARETMOVED);
this._caretListenerRegistered = false;
}
};
});
Signals.addSignalMethods(FocusCaretTracker.prototype);

View File

@@ -1,6 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const Params = imports.misc.params;
@@ -41,8 +46,10 @@ function _popGrabHelper(grabHelper) {
// your code just needs to deal with it; you shouldn't adjust behavior directly
// after you call ungrab(), but instead pass an 'onUngrab' callback when you
// call grab().
var GrabHelper = class GrabHelper {
constructor(owner, params) {
var GrabHelper = new Lang.Class({
Name: 'GrabHelper',
_init(owner, params) {
this._owner = owner;
this._modalParams = params;
@@ -52,7 +59,7 @@ var GrabHelper = class GrabHelper {
this._ignoreUntilRelease = false;
this._modalCount = 0;
}
},
// addActor:
// @actor: an actor
@@ -64,7 +71,7 @@ var GrabHelper = class GrabHelper {
this.removeActor(actor);
});
this._actors.push(actor);
}
},
// removeActor:
// @actor: an actor
@@ -79,7 +86,7 @@ var GrabHelper = class GrabHelper {
actor.disconnect(actor.__grabHelperDestroyId);
delete actor.__grabHelperDestroyId;
}
}
},
_isWithinGrabbedActor(actor) {
let currentActor = this.currentGrab.actor;
@@ -91,19 +98,19 @@ var GrabHelper = class GrabHelper {
actor = actor.get_parent();
}
return false;
}
},
get currentGrab() {
return this._grabStack[this._grabStack.length - 1] || {};
}
},
get grabbed() {
return this._grabStack.length > 0;
}
},
get grabStack() {
return this._grabStack;
}
},
_findStackIndex(actor) {
if (!actor)
@@ -114,7 +121,7 @@ var GrabHelper = class GrabHelper {
return i;
}
return -1;
}
},
_actorInGrabStack(actor) {
while (actor) {
@@ -124,11 +131,11 @@ var GrabHelper = class GrabHelper {
actor = actor.get_parent();
}
return -1;
}
},
isActorGrabbed(actor) {
return this._findStackIndex(actor) >= 0;
}
},
// grab:
// @params: A bunch of parameters, see below
@@ -183,12 +190,12 @@ var GrabHelper = class GrabHelper {
if (params.focus) {
params.focus.grab_key_focus();
} else if (newFocus && hadFocus) {
if (!newFocus.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
newFocus.grab_key_focus();
}
return true;
}
},
_takeModalGrab() {
let firstGrab = (this._modalCount == 0);
@@ -201,7 +208,7 @@ var GrabHelper = class GrabHelper {
this._modalCount++;
return true;
}
},
_releaseModalGrab() {
this._modalCount--;
@@ -214,7 +221,7 @@ var GrabHelper = class GrabHelper {
Main.popModal(this._owner);
global.sync_pointer();
}
},
// ignoreRelease:
//
@@ -224,7 +231,7 @@ var GrabHelper = class GrabHelper {
// the next release event.
ignoreRelease() {
this._ignoreUntilRelease = true;
}
},
// ungrab:
// @params: The parameters for the grab; see below.
@@ -267,7 +274,7 @@ var GrabHelper = class GrabHelper {
if (poppedGrab.savedFocus)
poppedGrab.savedFocus.grab_key_focus();
}
}
},
onCapturedEvent(event) {
let type = event.type();
@@ -315,5 +322,5 @@ var GrabHelper = class GrabHelper {
}
return Clutter.EVENT_STOP;
}
};
},
});

View File

@@ -1,7 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, IBus, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const IBus = imports.gi.IBus;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
@@ -11,8 +14,10 @@ var MAX_CANDIDATES_PER_PAGE = 16;
var DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ];
var CandidateArea = class CandidateArea {
constructor() {
var CandidateArea = new Lang.Class({
Name: 'CandidateArea',
_init() {
this.actor = new St.BoxLayout({ vertical: true,
reactive: true,
visible: false });
@@ -69,7 +74,7 @@ var CandidateArea = class CandidateArea {
this._orientation = -1;
this._cursorPosition = 0;
}
},
setOrientation(orientation) {
if (this._orientation == orientation)
@@ -90,7 +95,7 @@ var CandidateArea = class CandidateArea {
this._previousButton.child.icon_name = 'go-up-symbolic';
this._nextButton.child.icon_name = 'go-down-symbolic';
}
}
},
setCandidates(indexes, candidates, cursorPosition, cursorVisible) {
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
@@ -109,7 +114,7 @@ var CandidateArea = class CandidateArea {
this._cursorPosition = cursorPosition;
if (cursorVisible)
this._candidateBoxes[cursorPosition].add_style_pseudo_class('selected');
}
},
updateButtons(wrapsAround, page, nPages) {
if (nPages < 2) {
@@ -119,12 +124,14 @@ var CandidateArea = class CandidateArea {
this._buttonBox.show();
this._previousButton.reactive = wrapsAround || page > 0;
this._nextButton.reactive = wrapsAround || page < nPages - 1;
}
};
},
});
Signals.addSignalMethods(CandidateArea.prototype);
var CandidatePopup = class CandidatePopup {
constructor() {
var CandidatePopup = new Lang.Class({
Name: 'CandidatePopup',
_init() {
this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
this._boxPointer.visible = false;
this._boxPointer.style_class = 'candidate-popup-boxpointer';
@@ -164,7 +171,7 @@ var CandidatePopup = class CandidatePopup {
});
this._panelService = null;
}
},
setPanelService(panelService) {
this._panelService = panelService;
@@ -234,7 +241,7 @@ var CandidatePopup = class CandidatePopup {
let indexes = [];
let indexLabel;
for (let i = 0; (indexLabel = lookupTable.get_label(i)); ++i)
for (let i = 0; indexLabel = lookupTable.get_label(i); ++i)
indexes.push(indexLabel.get_text());
Main.keyboard.resetSuggestions();
@@ -268,13 +275,13 @@ var CandidatePopup = class CandidatePopup {
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
Main.keyboard.resetSuggestions();
});
}
},
_setDummyCursorGeometry(x, y, w, h) {
Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
if (this._boxPointer.visible)
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
}
},
_updateVisibility() {
let isVisible = (!Main.keyboard.visible &&
@@ -285,16 +292,16 @@ var CandidatePopup = class CandidatePopup {
if (isVisible) {
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
this._boxPointer.open(BoxPointer.PopupAnimation.NONE);
this._boxPointer.raise_top();
this._boxPointer.actor.raise_top();
} else {
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
}
}
},
_setTextAttributes(clutterText, ibusAttrList) {
let attr;
for (let i = 0; (attr = ibusAttrList.get(i)); ++i)
for (let i = 0; attr = ibusAttrList.get(i); ++i)
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
}
};
});

View File

@@ -1,7 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Clutter, GObject, Meta, St } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Lang = imports.lang;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
@@ -28,8 +34,10 @@ var AnimationDirection = {
var APPICON_ANIMATION_OUT_SCALE = 3;
var APPICON_ANIMATION_OUT_TIME = 0.25;
var BaseIcon = GObject.registerClass(
class BaseIcon extends St.Bin {
var BaseIcon = new Lang.Class({
Name: 'BaseIcon',
Extends: St.Bin,
_init(label, params) {
params = Params.parse(params, { createIcon: null,
setSizeManually: false,
@@ -39,10 +47,12 @@ class BaseIcon extends St.Bin {
if (params.showLabel)
styleClass += ' overview-icon-with-label';
super._init({ style_class: styleClass,
this.parent({ style_class: styleClass,
x_fill: true,
y_fill: true });
this.actor = this;
this.connect('destroy', this._onDestroy.bind(this));
this._box = new St.BoxLayout({ vertical: true });
@@ -69,18 +79,18 @@ class BaseIcon extends St.Bin {
let cache = St.TextureCache.get_default();
this._iconThemeChangedId = cache.connect('icon-theme-changed', this._onIconThemeChanged.bind(this));
}
},
vfunc_get_preferred_width(forHeight) {
// Return the actual height to keep the squared aspect
return this.get_preferred_height(-1);
}
},
// This can be overridden by a subclass, or by the createIcon
// parameter to _init()
createIcon(size) {
throw new Error('no implementation of createIcon in ' + this);
}
},
setIconSize(size) {
if (!this._setSizeManually)
@@ -90,7 +100,7 @@ class BaseIcon extends St.Bin {
return;
this._createIconTexture(size);
}
},
_createIconTexture(size) {
if (this.icon)
@@ -99,10 +109,9 @@ class BaseIcon extends St.Bin {
this.icon = this.createIcon(this.iconSize);
this._iconBin.child = this.icon;
}
},
vfunc_style_changed() {
super.vfunc_style_changed();
let node = this.get_theme_node();
let size;
@@ -117,7 +126,7 @@ class BaseIcon extends St.Bin {
return;
this._createIconTexture(size);
}
},
_onDestroy() {
if (this._iconThemeChangedId > 0) {
@@ -125,11 +134,11 @@ class BaseIcon extends St.Bin {
cache.disconnect(this._iconThemeChangedId);
this._iconThemeChangedId = 0;
}
}
},
_onIconThemeChanged() {
this._createIconTexture(this.iconSize);
}
},
animateZoomOut() {
// Animate only the child instead of the entire actor, so the
@@ -178,14 +187,18 @@ function zoomOutActor(actor) {
});
}
var IconGrid = GObject.registerClass({
var IconGrid = new Lang.Class({
Name: 'IconGrid',
Extends: St.Widget,
Signals: {'animation-done': {},
'child-focused': { param_types: [Clutter.Actor.$gtype]} },
}, class IconGrid extends St.Widget {
_init(params) {
super._init({ style_class: 'icon-grid',
this.parent({ style_class: 'icon-grid',
y_align: Clutter.ActorAlign.START });
this.actor = this;
params = Params.parse(params, { rowLimit: null,
columnLimit: null,
minRows: 1,
@@ -223,19 +236,19 @@ var IconGrid = GObject.registerClass({
this.connect('actor-added', this._childAdded.bind(this));
this.connect('actor-removed', this._childRemoved.bind(this));
}
},
_keyFocusIn(actor) {
this.emit('child-focused', actor);
}
},
_childAdded(grid, child) {
child._iconGridKeyFocusInId = child.connect('key-focus-in', this._keyFocusIn.bind(this));
}
},
_childRemoved(grid, child) {
child.disconnect(child._iconGridKeyFocusInId);
}
},
vfunc_get_preferred_width(forHeight) {
if (this._fillParent)
@@ -255,11 +268,11 @@ var IconGrid = GObject.registerClass({
let natSize = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
return this.get_theme_node().adjust_preferred_width(minSize, natSize);
}
},
_getVisibleChildren() {
return this.get_children().filter(actor => actor.visible);
}
},
vfunc_get_preferred_height(forWidth) {
if (this._fillParent)
@@ -289,7 +302,7 @@ var IconGrid = GObject.registerClass({
let height = nRows * this._getVItemSize() + totalSpacing + this.topPadding + this.bottomPadding;
return themeNode.adjust_preferred_height(height, height);
}
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
@@ -350,7 +363,7 @@ var IconGrid = GObject.registerClass({
x += this._getHItemSize() + spacing;
}
}
}
},
vfunc_get_paint_volume(paintVolume) {
// Setting the paint volume does not make sense when we don't have
@@ -389,7 +402,7 @@ var IconGrid = GObject.registerClass({
}
return true;
}
},
/**
* Intended to be override by subclasses if they need a different
@@ -397,12 +410,12 @@ var IconGrid = GObject.registerClass({
*/
_getChildrenToAnimate() {
return this._getVisibleChildren();
}
},
_cancelAnimation() {
this._clonesAnimating.forEach(clone => { clone.destroy(); });
this._clonesAnimating = [];
}
},
_animationDone() {
this._clonesAnimating.forEach(clone => {
@@ -412,7 +425,7 @@ var IconGrid = GObject.registerClass({
});
this._clonesAnimating = [];
this.emit('animation-done');
}
},
animatePulse(animationDirection) {
if (animationDirection != AnimationDirection.IN)
@@ -461,7 +474,7 @@ var IconGrid = GObject.registerClass({
}
});
}
}
},
animateSpring(animationDirection, sourceActor) {
this._cancelAnimation();
@@ -561,7 +574,7 @@ var IconGrid = GObject.registerClass({
Tweener.addTween(actorClone, movementParams);
Tweener.addTween(actorClone, fadeParams);
}
}
},
_getAllocatedChildSizeAndSpacing(child) {
let [,, natWidth, natHeight] = child.get_preferred_size();
@@ -570,7 +583,7 @@ var IconGrid = GObject.registerClass({
let height = Math.min(this._getVItemSize(), natHeight);
let ySpacing = Math.max(0, height - natHeight) / 2;
return [width, height, xSpacing, ySpacing];
}
},
_calculateChildBox(child, x, y, box) {
/* Center the item in its allocation horizontally */
@@ -588,15 +601,15 @@ var IconGrid = GObject.registerClass({
childBox.x2 = childBox.x1 + width;
childBox.y2 = childBox.y1 + height;
return childBox;
}
},
columnsForWidth(rowWidth) {
return this._computeLayout(rowWidth)[0];
}
},
getRowLimit() {
return this._rowLimit;
}
},
_computeLayout(forWidth) {
let nColumns = 0;
@@ -613,7 +626,7 @@ var IconGrid = GObject.registerClass({
usedWidth -= spacing;
return [nColumns, usedWidth];
}
},
_onStyleChanged() {
let themeNode = this.get_theme_node();
@@ -621,7 +634,7 @@ var IconGrid = GObject.registerClass({
this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
this._vItemSize = themeNode.get_length('-shell-grid-vertical-item-size') || ICON_SIZE;
this.queue_relayout();
}
},
nRows(forWidth) {
let children = this._getVisibleChildren();
@@ -630,38 +643,38 @@ var IconGrid = GObject.registerClass({
if (this._rowLimit)
nRows = Math.min(nRows, this._rowLimit);
return nRows;
}
},
rowsForHeight(forHeight) {
return Math.floor((forHeight - (this.topPadding + this.bottomPadding) + this._getSpacing()) / (this._getVItemSize() + this._getSpacing()));
}
},
usedHeightForNRows(nRows) {
return (this._getVItemSize() + this._getSpacing()) * nRows - this._getSpacing() + this.topPadding + this.bottomPadding;
}
},
usedWidth(forWidth) {
return this.usedWidthForNColumns(this.columnsForWidth(forWidth));
}
},
usedWidthForNColumns(columns) {
let usedWidth = columns * (this._getHItemSize() + this._getSpacing());
usedWidth -= this._getSpacing();
return usedWidth + this.leftPadding + this.rightPadding;
}
},
removeAll() {
this._items = [];
this.remove_all_children();
}
},
destroyAll() {
this._items = [];
this.destroy_all_children();
}
},
addItem(item, index) {
if (!(item.icon instanceof BaseIcon))
if (!item.icon instanceof BaseIcon)
throw new Error('Only items with a BaseIcon icon property can be added to IconGrid');
this._items.push(item);
@@ -669,35 +682,35 @@ var IconGrid = GObject.registerClass({
this.insert_child_at_index(item.actor, index);
else
this.add_actor(item.actor);
}
},
removeItem(item) {
this.remove_child(item.actor);
}
},
getItemAtIndex(index) {
return this.get_child_at_index(index);
}
},
visibleItemsCount() {
return this.get_children().filter(c => c.is_visible()).length;
}
},
setSpacing(spacing) {
this._fixedSpacing = spacing;
}
},
_getSpacing() {
return this._fixedSpacing ? this._fixedSpacing : this._spacing;
}
},
_getHItemSize() {
return this._fixedHItemSize ? this._fixedHItemSize : this._hItemSize;
}
},
_getVItemSize() {
return this._fixedVItemSize ? this._fixedVItemSize : this._vItemSize;
}
},
_updateSpacingForSize(availWidth, availHeight) {
let maxEmptyVArea = availHeight - this._minRows * this._getVItemSize();
@@ -730,7 +743,7 @@ var IconGrid = GObject.registerClass({
this.setSpacing(spacing);
if (this._padWithSpacing)
this.topPadding = this.rightPadding = this.bottomPadding = this.leftPadding = spacing;
}
},
/**
* This function must to be called before iconGrid allocation,
@@ -755,7 +768,7 @@ var IconGrid = GObject.registerClass({
}
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
this._updateIconSizes.bind(this));
}
},
// Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
_updateIconSizes() {
@@ -767,23 +780,25 @@ var IconGrid = GObject.registerClass({
}
});
var PaginatedIconGrid = GObject.registerClass({
var PaginatedIconGrid = new Lang.Class({
Name: 'PaginatedIconGrid',
Extends: IconGrid,
Signals: {'space-opened': {},
'space-closed': {} },
}, class PaginatedIconGrid extends IconGrid {
_init(params) {
super._init(params);
this.parent(params);
this._nPages = 0;
this.currentPage = 0;
this._rowsPerPage = 0;
this._spaceBetweenPages = 0;
this._childrenPerPage = 0;
}
},
vfunc_get_preferred_height(forWidth) {
let height = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
return [height, height];
}
},
vfunc_allocate(box, flags) {
if (this._childrenPerPage == 0)
@@ -838,7 +853,7 @@ var PaginatedIconGrid = GObject.registerClass({
} else
x += this._getHItemSize() + spacing;
}
}
},
// Overriden from IconGrid
_getChildrenToAnimate() {
@@ -847,7 +862,7 @@ var PaginatedIconGrid = GObject.registerClass({
let lastIndex = firstIndex + this._childrenPerPage;
return children.slice(firstIndex, lastIndex);
}
},
_computePages(availWidthPerPage, availHeightPerPage) {
let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
@@ -866,24 +881,24 @@ var PaginatedIconGrid = GObject.registerClass({
this._nPages = Math.ceil(nRows / this._rowsPerPage);
this._spaceBetweenPages = availHeightPerPage - (this.topPadding + this.bottomPadding) - this._availableHeightPerPageForItems();
this._childrenPerPage = nColumns * this._rowsPerPage;
}
},
adaptToSize(availWidth, availHeight) {
super.adaptToSize(availWidth, availHeight);
this.parent(availWidth, availHeight);
this._computePages(availWidth, availHeight);
}
},
_availableHeightPerPageForItems() {
return this.usedHeightForNRows(this._rowsPerPage) - (this.topPadding + this.bottomPadding);
}
},
nPages() {
return this._nPages;
}
},
getPageHeight() {
return this._availableHeightPerPageForItems();
}
},
getPageY(pageNumber) {
if (!this._nPages)
@@ -892,15 +907,17 @@ var PaginatedIconGrid = GObject.registerClass({
let firstPageItem = pageNumber * this._childrenPerPage
let childBox = this._getVisibleChildren()[firstPageItem].get_allocation_box();
return childBox.y1 - this.topPadding;
}
},
getItemPage(item) {
let children = this._getVisibleChildren();
let index = children.indexOf(item);
if (index == -1)
if (index == -1) {
throw new Error('Item not found.');
return 0;
}
return Math.floor(index / this._childrenPerPage);
}
},
/**
* openExtraSpace:
@@ -913,9 +930,10 @@ var PaginatedIconGrid = GObject.registerClass({
openExtraSpace(sourceItem, side, nRows) {
let children = this._getVisibleChildren();
let index = children.indexOf(sourceItem.actor);
if (index == -1)
if (index == -1) {
throw new Error('Item not found.');
return;
}
let pageIndex = Math.floor(index / this._childrenPerPage);
let pageOffset = pageIndex * this._childrenPerPage;
@@ -947,18 +965,18 @@ var PaginatedIconGrid = GObject.registerClass({
this._translatedChildren = [];
this.emit('space-opened');
} else {
this._translateChildren(childrenUp, St.DirectionType.UP, nRowsUp);
this._translateChildren(childrenDown, St.DirectionType.DOWN, nRowsDown);
this._translateChildren(childrenUp, Gtk.DirectionType.UP, nRowsUp);
this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown);
this._translatedChildren = childrenUp.concat(childrenDown);
}
}
},
_translateChildren(children, direction, nRows) {
let translationY = nRows * (this._getVItemSize() + this._getSpacing());
if (translationY == 0)
return;
if (direction == St.DirectionType.UP)
if (direction == Gtk.DirectionType.UP)
translationY *= -1;
for (let i = 0; i < children.length; i++) {
@@ -971,7 +989,7 @@ var PaginatedIconGrid = GObject.registerClass({
params.onComplete = () => { this.emit('space-opened'); };
Tweener.addTween(children[i], params);
}
}
},
closeExtraSpace() {
if (!this._translatedChildren || !this._translatedChildren.length) {

View File

@@ -1,75 +1,56 @@
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
const PermissionStore = imports.misc.permissionStore;
const WAYLAND_KEYBINDINGS_SCHEMA = 'org.gnome.mutter.wayland.keybindings';
const APP_WHITELIST = ['gnome-control-center.desktop'];
const APP_PERMISSIONS_TABLE = 'gnome';
const APP_PERMISSIONS_ID = 'shortcuts-inhibitor';
const GRANTED = 'GRANTED';
const DENIED = 'DENIED';
var DialogResponse = Meta.InhibitShortcutsDialogResponse;
var InhibitShortcutsDialog = GObject.registerClass({
var InhibitShortcutsDialog = new Lang.Class({
Name: 'InhibitShortcutsDialog',
Extends: GObject.Object,
Implements: [Meta.InhibitShortcutsDialog],
Properties: {
'window': GObject.ParamSpec.override('window', Meta.InhibitShortcutsDialog)
}
}, class InhibitShortcutsDialog extends GObject.Object {
},
_init(window) {
super._init();
this.parent();
this._window = window;
this._dialog = new ModalDialog.ModalDialog();
this._buildLayout();
}
},
get window() {
return this._window;
}
},
set window(window) {
this._window = window;
}
},
get _app() {
let windowTracker = Shell.WindowTracker.get_default();
return windowTracker.get_window_app(this._window);
}
},
_getRestoreAccel() {
let settings = new Gio.Settings({ schema_id: WAYLAND_KEYBINDINGS_SCHEMA });
let accel = settings.get_strv('restore-shortcuts')[0] || '';
return Gtk.accelerator_get_label.apply(null,
Gtk.accelerator_parse(accel));
}
_shouldUsePermStore() {
return this._app && !this._app.is_window_backed();
}
_saveToPermissionStore(grant) {
if (!this._shouldUsePermStore() || this._permStore == null)
return;
let permissions = {};
permissions[this._app.get_id()] = [grant];
let data = GLib.Variant.new('av', {});
this._permStore.SetRemote(APP_PERMISSIONS_TABLE,
true,
APP_PERMISSIONS_ID,
permissions,
data,
(result, error) => {
if (error != null)
log(error.message);
});
}
},
_buildLayout() {
let name = this._app ? this._app.get_name() : this._window.title;
@@ -92,63 +73,28 @@ var InhibitShortcutsDialog = GObject.registerClass({
this._dialog.addButton({ label: _("Deny"),
action: () => {
this._saveToPermissionStore(DENIED);
this._emitResponse(DialogResponse.DENY);
},
key: Clutter.KEY_Escape });
this._dialog.addButton({ label: _("Allow"),
action: () => {
this._saveToPermissionStore(GRANTED);
this._emitResponse(DialogResponse.ALLOW);
},
default: true });
}
},
_emitResponse(response) {
this.emit('response', response);
this._dialog.close();
}
},
vfunc_show() {
if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1) {
if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1)
this._emitResponse(DialogResponse.ALLOW);
return;
}
if (!this._shouldUsePermStore()) {
else
this._dialog.open();
return;
}
/* Check with the permission store */
let appId = this._app.get_id();
this._permStore = new PermissionStore.PermissionStore((proxy, error) => {
if (error) {
log(error.message);
this._dialog.open();
return;
}
this._permStore.LookupRemote(APP_PERMISSIONS_TABLE,
APP_PERMISSIONS_ID,
(res, error) => {
if (error) {
this._dialog.open();
log(error.message);
return;
}
let [permissions, data] = res;
if (permissions[appId] === undefined) // Not found
this._dialog.open();
else if (permissions[appId] == GRANTED)
this._emitResponse(DialogResponse.ALLOW);
else
this._emitResponse(DialogResponse.DENY);
});
});
}
},
vfunc_hide() {
this._dialog.close();

View File

@@ -1,5 +1,7 @@
const { Clutter, Gio, GObject } = imports.gi;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
@@ -7,17 +9,17 @@ const KEYBOARD_A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable';
const KEY_SLOW_KEYS_ENABLED = 'slowkeys-enable';
var KbdA11yDialog = GObject.registerClass(
class KbdA11yDialog extends GObject.Object {
_init() {
super._init();
var KbdA11yDialog = new Lang.Class({
Name: 'KbdA11yDialog',
Extends: GObject.Object,
_init() {
this._a11ySettings = new Gio.Settings({ schema_id: KEYBOARD_A11Y_SCHEMA });
let deviceManager = Clutter.DeviceManager.get_default();
deviceManager.connect('kbd-a11y-flags-changed',
this._showKbdA11yDialog.bind(this));
}
},
_showKbdA11yDialog(deviceManager, newFlags, whatChanged) {
let dialog = new ModalDialog.ModalDialog();

File diff suppressed because it is too large Load Diff

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