Compare commits

..

36 Commits

Author SHA1 Message Date
Florian Müllner 5dfdb68c75 Bump version to 41.rc
Update NEWS.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/188>
2021-09-05 02:02:52 +02:00
Florian Müllner 443d1dc42b ci: Add dist job
So far, releases are done locally by invoking `meson dist`.

We can do better and leverage the existing CI infrastructure, to get
to the following release workflow:

 - bump version in meson.build, update NEWS etc.
 - open merge request for the release
 - merge when the pipeline (including dist check) succeeds
 - tag the release
 - wait for the tag pipeline to spit out the tarball artifact

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/186>
2021-09-04 05:10:23 +02:00
Florian Müllner 34f6c9514a ci: Add a fedora build job
We currently use a setup modelled after the flatpak CI workflow,
where we produce extension bundles and expose them as artifacts
for easy testing.

It still makes sense to test a regular build though, in particular
as that can include classic mode support.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/186>
2021-09-04 05:10:23 +02:00
Florian Müllner 2f2619403a ci: Build custom image
The gnome-shell image we are using is well-suited for the jobs we
are running, but the lack of sassc means that we don't cover classic
mode.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/186>
2021-09-04 05:10:23 +02:00
Florian Müllner d25cc847f3 ci: Reindent yaml configuration
The file currently uses a mix of 4 and 2 space indentation (with the
occasional 1 space thrown in). It looks like most GNOME projects have
settled on 2-space indentation, so use that.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/186>
2021-09-04 05:10:23 +02:00
Florian Müllner 769ad859e6 build: Check NEWS for version
I don't think this ever happened to me, but it can't hurt enforcing
that every release has a corresponding NEWS entry.

(The script has been copied from Polari, thus the metainfo support)

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/186>
2021-09-04 05:10:23 +02:00
Florian Müllner 7ba0e5b42c apps-menu: Stop using panel-main-menu shortcut
It's an old GNOME 2 shortcut that's no longer worth supporting in
the regular session. Instead, set up a new shortcut backed by our
own schema.

https://discourse.gnome.org/t/difference-between-show-the-overview-and-show-the-activities-overview-keyboard-shortcuts/6572

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/173>
2021-08-31 23:42:23 +02:00
Florian Müllner 201339345d window-list: Only show at the end of the overview transition
gnome-shell now considers the work area in the overview, so popping
up at the beginning of the overview transition is now more jarring
than at the end.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/185>
2021-08-26 23:36:53 +02:00
Florian Müllner 6ee4205f1e window-list: Fix initial visibility
Mutter uses an undefined initial in-fullscreen state, so it will
always emit the `in-fullscreen-changed` signal when it determines
the actual initial state.

This didn't use to be an issue when the shell started in the session,
but now results in the window list ending up visible in the overview
on startup.

Work around this by hiding ourselves again when the in-fullscreen
state changes in the overview.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/185>
2021-08-26 23:28:44 +02:00
Florian Müllner 2307e2cabe Bump version to 41.beta
Update NEWS.
2021-08-18 01:50:19 +02:00
Florian Müllner 4becaa28ce Update sass submodule 2021-08-18 01:50:19 +02:00
Florian Müllner cc45bd63ab cleanup: Use new gettext() convenience
gnome-shell now includes convenience helpers for gettext functions that
use an extension's text domain (as initialized by initTranslations()).

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/183>
2021-08-14 23:15:56 +02:00
Florian Müllner 757bcee4e2 build: Use backend-agnostic meson commands for export
There's no alternative backend in sight for us, but it's nice to
only deal with a single build tool.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/182>
2021-08-13 05:25:47 +02:00
Florian Müllner 1340b209f9 window-list: Simplify radio handling
Instead of handling the active state manually and updating settings
on changes, we can use GActions to leave the nitty-gritty to GTK.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/181>
2021-08-13 05:22:41 +02:00
Florian Müllner 8f362d57fe lint: Synchronize configuration with gjs
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/180>
2021-08-13 04:57:35 +02:00
Florian Müllner d0b9c9b54a cleanup: Document functions
gjs now enforces this in its eslint configuration. Adding type
information generally is a good idea, so add appropriate comments
to public functions before picking up that configuration change.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/180>
2021-08-13 04:48:22 +02:00
Florian Müllner 6284b0c489 window-list: Move functions into base class
The helper functions date back to a time when AppButton and WindowButton
were unconnected classes. But nowadays they share a common base class, so
we have a better place for them than external helper functions.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/180>
2021-08-13 04:39:00 +02:00
Florian Müllner 8a211f98fd build: Rewrite gettext domain when exporting zips
Now that every extension picks up its gettext domain from
its metadata, we can easily change it when exporting the
zips.

That ensures that every extension only binds its own domain
instead of messing up other extension's translations.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/335

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/179>
2021-08-11 19:05:45 +02:00
Florian Müllner d6633397b7 build: Remove unused variable
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/335

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/179>
2021-08-11 19:05:45 +02:00
Florian Müllner 0d06cc685e extensions: Pick up gettext domain from metadata
Since commit a6ee142f21, the extension archives that are uploaded
to extensions.gnome.org only contain strings that are relevant for
the extension, not all translations from all extensions.

Unfortunately all extensions still share a common gettext domain,
so the extension with the last bind_textdomain() call wins and
leaves the others without translations.

We'll address this by using distinct domains when not installed
system-wide. That becomes easier if there is a canonical place
for the text domain, with the existing metadata key being the
natural choice.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/335

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/179>
2021-08-11 18:42:43 +02:00
Marco Trevisan (Treviño) 8de89a44a4 README: Fix typo on instructions to move to main branch 2021-07-21 19:50:34 +02:00
Florian Müllner f3b1f10f6c ci: Set FDO_UPSTREAM_REPO
ci-fairy uses the variable to set the upstream remote that is used
to build the commit range to check.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/178>
2021-07-19 17:23:44 +02:00
Florian Müllner 2bced47762 classic: Remove padding from app menu
It is now inconsistent with other top bar items, so drop it.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/167>
2021-07-18 21:57:38 +00:00
Florian Müllner 7ba9b87064 docs: Add README section for default branch
We are about to change it, so briefly outline how to update local
checkouts.

(Copied from glib)

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/177>
2021-07-14 21:11:59 +02:00
Florian Müllner a642c439ce docs: Use HEAD in external URLs
That way the link will keep working when the other project changes
its default branch name.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/177>
2021-07-14 20:37:15 +02:00
Florian Müllner d421bbfa60 drive-menu: Hide items initially
Now that the check for network mounts is non-blocking, the initial
sync doesn't take effect immediately. We don't want hidden items
to briefly flash the indicator, so create them initially hidden.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/176>
2021-07-13 11:54:21 +02:00
Florian Müllner 3539ce1139 drive-menu: Fix indicator visibility
Commit 519269be9d made the check for network mounts non-blocking, and
we now update the indicator's visibility before a newly-added network
mount is hidden.

Address this by monitoring the item itself for visibility changes.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/176>
2021-07-13 11:46:16 +02:00
Florian Müllner 94b907f46d window-list: Init translations
Whoops, we are missing the bindtextdomain() call, which means translations
won't work when no other extension that shares the same domain is used
(like in GNOME Classic for instance).

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/340

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/174>
2021-07-12 16:04:50 +00:00
Alexander Shopov 1e04622eb4 Update Bulgarian translation 2021-07-11 08:21:24 +00:00
Florian Müllner 519269be9d drive-menu: Avoid blocking I/O when querying filesystem
The last commit improved the heuristics for detecting network mounts,
but at the price of potentially blocking the shell. Avoid that drawback
by making the code in question async.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/53

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/27>
2021-06-23 18:15:42 +02:00
Florian Müllner 7d6670ce3c drive-menu: Don't assume mounts without volume are local
The intention of the code is to only expose actually plugged in
devices rather than network mounts, but the existing heuristics are
based on GVolume and simply assume a local mount where there's no
associated volume. Fill that gap by querying the ::remote filesystem
attribute in that case.

https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/53

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/27>
2021-06-23 17:52:19 +02:00
Juliano de Souza Camargo 50bd597baa Update Portuguese translation
(cherry picked from commit 12eedcf6f7)
2021-06-07 10:22:07 +00:00
Hugo Carvalho 4403b54fbc Update Portuguese translation
(cherry picked from commit 08d382facc)
2021-06-02 16:10:00 +00:00
Adam Goode d6648b0b5c window-list: Don't use panel-button class for the workspace indicator
The panel-button introduces some horizontal padding which is insensitive
to scroll events. Without this change, there is a small dead zone in the
corner that cannot be used to switch workspaces with the mouse wheel.

For useMenu mode, this has the effect of removing all of the horizontal
space to the edge of the screen, so I add some back with the
status-label-bin margin.

This a is similar change to 8bad8a3b63.

Fixes #315.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/171>
2021-05-26 11:57:41 +00:00
Florian Müllner 861e5c0be6 build: Only use major version in shell-versions
The website changed its version handling again, and now takes "40.0"
to mean "40.0, and only 40.0".

Not complaining though, as "40" is more correct in my opinion anyway ...

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/172>
2021-05-25 15:45:21 +02:00
Florian Müllner bf86b84d6c Post-release version bump 2021-05-14 17:01:12 +02:00
34 changed files with 724 additions and 625 deletions
+128 -63
View File
@@ -1,83 +1,107 @@
include: include:
- remote: "https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/6f86b8bcb0cd5168c32779c4fea9a893c4a0c046/templates/ci-fairy.yml" - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/fedora.yml'
- remote: "https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/6f86b8bcb0cd5168c32779c4fea9a893c4a0c046/templates/ci-fairy.yml"
image: registry.gitlab.gnome.org/gnome/gnome-shell/fedora/33:2020-11-17.0 image: registry.gitlab.gnome.org/gnome/gnome-shell/fedora/34:2021-08-12.0
stages: stages:
- pre_review - pre_review
- review - prepare
- build - review
- build
- deploy
default: default:
# Cancel jobs if newer commits are pushed to the branch # Cancel jobs if newer commits are pushed to the branch
interruptible: true interruptible: true
# Auto-retry jobs in case of infra failures # Auto-retry jobs in case of infra failures
retry: retry:
max: 1 max: 1
when: when:
- 'runner_system_failure' - 'runner_system_failure'
- 'stuck_or_timeout_failure' - 'stuck_or_timeout_failure'
- 'scheduler_failure' - 'scheduler_failure'
- 'api_failure' - 'api_failure'
variables: variables:
LINT_LOG: "eslint-report.xml" FDO_UPSTREAM_REPO: GNOME/gnome-shell-extensions
JS_LOG: "js-report.txt" LINT_LOG: "eslint-report.xml"
JS_LOG: "js-report.txt"
workflow: workflow:
rules: rules:
- if: '$CI_MERGE_REQUEST_IID' - if: '$CI_MERGE_REQUEST_IID'
- if: '$CI_COMMIT_TAG' - if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH' - if: '$CI_COMMIT_BRANCH'
.pipeline_guard: &pipeline_guard .pipeline_guard: &pipeline_guard
rules: rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_TAG' - if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/' - if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
- when: 'manual' - when: 'manual'
.gnome-shell-extensions.fedora:34:
variables:
FDO_DISTRIBUTION_VERSION: 34
FDO_DISTRIBUTION_TAG: '2021-08-31.0'
FDO_DISTRIBUTION_PACKAGES: >
meson git gettext sassc
.prereview_req: &prereview_req
needs:
- check_commit_log
- check-merge-request
check_commit_log: check_commit_log:
extends: extends:
- .fdo.ci-fairy - .fdo.ci-fairy
stage: pre_review stage: pre_review
script: script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ; - if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then then
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ; ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ;
else else
echo "Not a merge request" ; echo "Not a merge request" ;
fi fi
<<: *pipeline_guard <<: *pipeline_guard
artifacts: artifacts:
expire_in: 1 week expire_in: 1 week
paths: paths:
- commit-message-junit-report.xml - commit-message-junit-report.xml
reports: reports:
junit: commit-message-junit-report.xml junit: commit-message-junit-report.xml
check-merge-request: check-merge-request:
extends: extends:
- .fdo.ci-fairy - .fdo.ci-fairy
stage: pre_review stage: pre_review
script: script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ; - if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then then
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ; ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ;
else else
echo "Not a merge request" ; echo "Not a merge request" ;
fi fi
<<: *pipeline_guard <<: *pipeline_guard
artifacts: artifacts:
expire_in: 1 week expire_in: 1 week
paths: paths:
- check-merge-request-report.xml - check-merge-request-report.xml
reports: reports:
junit: check-merge-request-report.xml junit: check-merge-request-report.xml
build-fedora-container:
extends:
- .fdo.container-build@fedora@x86_64
- .gnome-shell-extensions.fedora:34
stage: prepare
<<: *prereview_req
js_check: js_check:
stage: review stage: review
<<: *prereview_req
script: script:
- find extensions -name '*.js' -exec js78 -c '{}' ';' 2>&1 | tee $JS_LOG - find extensions -name '*.js' -exec js78 -c '{}' ';' 2>&1 | tee $JS_LOG
- (! grep -q . $JS_LOG) - (! grep -q . $JS_LOG)
@@ -88,8 +112,9 @@ js_check:
eslint: eslint:
stage: review stage: review
<<: *prereview_req
script: script:
- eslint -o $LINT_LOG -f junit extensions - eslint -o $LINT_LOG -f junit --resolve-plugins-relative-to $(npm root -g) extensions
artifacts: artifacts:
paths: paths:
- ${LINT_LOG} - ${LINT_LOG}
@@ -98,7 +123,7 @@ eslint:
build-bundles: build-bundles:
stage: build stage: build
needs: ["check_commit_log"] <<: *prereview_req
script: script:
- ./export-zips.sh - ./export-zips.sh
artifacts: artifacts:
@@ -106,3 +131,43 @@ build-bundles:
expose_as: 'Get Extension bundles here' expose_as: 'Get Extension bundles here'
paths: paths:
- zip-files/ - zip-files/
fedora-build:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell-extensions.fedora:34
stage: build
needs:
- build-fedora-container
script:
- meson setup build --werror -Dextension_set=all -Dclassic=true
- meson compile -C build
- meson test -C build
- meson install -C build
artifacts:
paths:
- build
fedora-dist:
extends:
- .fdo.distribution-image@fedora
- .gnome-shell-extensions.fedora:34
stage: deploy
needs:
- fedora-build
script:
- meson dist -C build
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- "**/meson.build"
- meson/*
fedora-dist-tarball:
extends: fedora-dist
artifacts:
expose_as: 'Get tarball here'
paths:
- build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
rules:
- if: '$CI_COMMIT_TAG'
+1 -1
View File
@@ -28,4 +28,4 @@ imports (like imports.lang or imports.dbus) and introspection,
the other for Shell API. Within the same group, put everything the other for Shell API. Within the same group, put everything
in alphabetic order. in alphabetic order.
[coding-style]: https://gitlab.gnome.org/GNOME/gjs/blob/master/doc/Style_Guide.md [coding-style]: https://gitlab.gnome.org/GNOME/gjs/blob/HEAD/doc/Style_Guide.md
+13 -38
View File
@@ -1,50 +1,25 @@
40.7 41.rc
==== =====
* Bump version * window-list: Adapt to overview-on-startup [Florian; !185]
* apps-menu: Use a custom 'toggle-menu' shortcut [Florian; !173]
40.6 * Misc. bug fixes and cleanups [Florian; !186]
====
* window-list: Update window tracking to avoid missing icons [Florian; #372]
Contributors: Contributors:
Florian Müllner Florian Müllner
40.5 41.beta
==== =======
* native-window-placement: Fix distorted layout in app grid [Sebastian; !189]
* window-list: Fix on-screen keyboard [Florian; !199]
* Misc. bug fixes [Neal; !195]
Contributors:
Neal Gompa, Sebastian Keller, Florian Müllner
40.4
====
* drive-menu: Fix indicator visibility [Florian; !176]
* Use distinct gettext domain for e.g.o uploads [Florian; #335]
Contributors:
Florian Müllner
40.3
====
* drive-menu: Improve detection of network mounts [Florian; !27]
* Misc. bug fixes [Florian; #340]
Contributors:
Florian Müllner
40.2
====
* window-list: Extend reactive area of minimap to screen edges [Adam; !171] * window-list: Extend reactive area of minimap to screen edges [Adam; !171]
* Misc. bug fixes [Florian; !172] * drive-menu: Improve detection of network mounts [Florian; !27, !176]
* Use distinct gettext domain for e.g.o uploads [Florian; #335]
* Misc. bug fixes and cleanups [Florian; !172, !174, !177, !167, !178, !180,
!181, !182, !183]
Contributors: Contributors:
Adam Goode, Florian Müllner Marco Trevisan (Treviño), Adam Goode, Florian Müllner
Translators: Translators:
Hugo Carvalho [pt], Juliano de Souza Camargo [pt] Hugo Carvalho [pt], Juliano de Souza Camargo [pt], Alexander Shopov [bg]
40.1 40.1
==== ====
+13
View File
@@ -69,6 +69,19 @@ GSettings key.
Adds a simple workspace switcher to the top bar. Adds a simple workspace switcher to the top bar.
## Default branch
The default development branch is `main`. If you still have a local
checkout under the old name, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/master
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
## License ## License
GNOME Shell Extensions are distributed under the terms of the GNU General GNOME Shell Extensions are distributed under the terms of the GNU General
-1
View File
@@ -5,4 +5,3 @@ Exec=env GNOME_SHELL_SESSION_MODE=classic gnome-session
TryExec=gnome-session TryExec=gnome-session
Type=Application Type=Application
DesktopNames=GNOME-Classic;GNOME; DesktopNames=GNOME-Classic;GNOME;
X-GDM-SessionRegisters=true
+1 -1
View File
@@ -84,8 +84,8 @@ $variant: 'light';
} }
#appMenu { #appMenu {
padding: 0 8px 0 8px;
spinner-image: url("classic-process-working.svg"); spinner-image: url("classic-process-working.svg");
.panel-status-menu-box { padding: 0; }
} }
.tile-preview-left.on-primary, .tile-preview-left.on-primary,
.tile-preview-right.on-primary, .tile-preview-right.on-primary,
+1 -1
View File
@@ -7,7 +7,7 @@ builddir=`mktemp -p $srcdir -d _build.XXXXXX` || exit 1
installdir=`mktemp -p $srcdir -d _install.XXXXXX` || exit 1 installdir=`mktemp -p $srcdir -d _install.XXXXXX` || exit 1
meson setup --prefix=$installdir -Dextension_set=all $srcdir $builddir meson setup --prefix=$installdir -Dextension_set=all $srcdir $builddir
ninja -C$builddir install meson install -C $builddir
rm -rf $srcdir/zip-files rm -rf $srcdir/zip-files
mkdir $srcdir/zip-files mkdir $srcdir/zip-files
+11 -17
View File
@@ -12,9 +12,7 @@ const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Me = ExtensionUtils.getCurrentExtension(); const _ = ExtensionUtils.gettext;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const appSys = Shell.AppSystem.get_default(); const appSys = Shell.AppSystem.get_default();
@@ -380,9 +378,12 @@ class ApplicationsButton extends PanelMenu.Button {
this._hidingId = Main.overview.connect('hiding', () => { this._hidingId = Main.overview.connect('hiding', () => {
this.remove_accessible_state(Atk.StateType.CHECKED); this.remove_accessible_state(Atk.StateType.CHECKED);
}); });
Main.layoutManager.connect('startup-complete', Main.wm.addKeybinding(
this._setKeybinding.bind(this)); 'apps-menu-toggle-menu',
this._setKeybinding(); ExtensionUtils.getSettings(),
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
() => this.menu.toggle());
this._desktopTarget = new DesktopTarget(); this._desktopTarget = new DesktopTarget();
this._desktopTarget.connect('app-dropped', () => { this._desktopTarget.connect('app-dropped', () => {
@@ -433,11 +434,7 @@ class ApplicationsButton extends PanelMenu.Button {
this._tree.disconnect(this._treeChangedId); this._tree.disconnect(this._treeChangedId);
this._tree = null; this._tree = null;
Main.wm.setCustomKeybindingHandler('panel-main-menu', Main.wm.removeKeybinding('apps-menu-toggle-menu');
Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
Main.sessionMode.hasOverview
? Main.overview.toggle.bind(Main.overview)
: null);
this._desktopTarget.destroy(); this._desktopTarget.destroy();
} }
@@ -479,12 +476,6 @@ class ApplicationsButton extends PanelMenu.Button {
super._onOpenStateChanged(menu, open); super._onOpenStateChanged(menu, open);
} }
_setKeybinding() {
Main.wm.setCustomKeybindingHandler('panel-main-menu',
Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
() => this.menu.toggle());
}
_redisplay() { _redisplay() {
this.applicationsBox.destroy_all_children(); this.applicationsBox.destroy_all_children();
this.categoriesBox.destroy_all_children(); this.categoriesBox.destroy_all_children();
@@ -674,17 +665,20 @@ class ApplicationsButton extends PanelMenu.Button {
let appsMenuButton; let appsMenuButton;
/** */
function enable() { function enable() {
appsMenuButton = new ApplicationsButton(); appsMenuButton = new ApplicationsButton();
let index = Main.sessionMode.panel.left.indexOf('activities') + 1; let index = Main.sessionMode.panel.left.indexOf('activities') + 1;
Main.panel.addToStatusArea('apps-menu', appsMenuButton, index, 'left'); Main.panel.addToStatusArea('apps-menu', appsMenuButton, index, 'left');
} }
/** */
function disable() { function disable() {
Main.panel.menuManager.removeMenu(appsMenuButton.menu); Main.panel.menuManager.removeMenu(appsMenuButton.menu);
appsMenuButton.destroy(); appsMenuButton.destroy();
} }
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
+1
View File
@@ -3,3 +3,4 @@ extension_data += configure_file(
output: metadata_name, output: metadata_name,
configuration: metadata_conf configuration: metadata_conf
) )
extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')
+1
View File
@@ -1,6 +1,7 @@
{ {
"extension-id": "@extension_id@", "extension-id": "@extension_id@",
"uuid": "@uuid@", "uuid": "@uuid@",
"settings-schema": "@gschemaname@",
"gettext-domain": "@gettext_domain@", "gettext-domain": "@gettext_domain@",
"name": "Applications Menu", "name": "Applications Menu",
"description": "Add a category-based menu for applications.\nThis extension is part of Classic Mode and is officially supported by GNOME. Please do not report bugs using the form below, use GNOME's GitLab instance instead.", "description": "Add a category-based menu for applications.\nThis extension is part of Classic Mode and is officially supported by GNOME. Please do not report bugs using the form below, use GNOME's GitLab instance instead.",
@@ -0,0 +1,12 @@
<schemalist gettext-domain="gnome-shell-extensions">
<schema id="org.gnome.shell.extensions.apps-menu"
path="/org/gnome/shell/extensions/apps-menu/">
<key name="apps-menu-toggle-menu" type="as">
<default>["&lt;Alt&gt;F1"]</default>
<summary>Keybinding to open the applications menu</summary>
<description>
Keybinding to open the applications menu.
</description>
</key>
</schema>
</schemalist>
@@ -108,10 +108,14 @@ class WindowMover {
let prevCheckWorkspaces; let prevCheckWorkspaces;
let winMover; let winMover;
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
/**
* @returns {bool} - false (used as MetaLater handler)
*/
function myCheckWorkspaces() { function myCheckWorkspaces() {
let keepAliveWorkspaces = []; let keepAliveWorkspaces = [];
let foundNonEmpty = false; let foundNonEmpty = false;
@@ -132,6 +136,7 @@ function myCheckWorkspaces() {
return false; return false;
} }
/** */
function enable() { function enable() {
prevCheckWorkspaces = Main.wm._workspaceTracker._checkWorkspaces; prevCheckWorkspaces = Main.wm._workspaceTracker._checkWorkspaces;
Main.wm._workspaceTracker._checkWorkspaces = myCheckWorkspaces; Main.wm._workspaceTracker._checkWorkspaces = myCheckWorkspaces;
@@ -139,6 +144,7 @@ function enable() {
winMover = new WindowMover(); winMover = new WindowMover();
} }
/** */
function disable() { function disable() {
Main.wm._workspaceTracker._checkWorkspaces = prevCheckWorkspaces; Main.wm._workspaceTracker._checkWorkspaces = prevCheckWorkspaces;
winMover.destroy(); winMover.destroy();
+5 -3
View File
@@ -5,10 +5,8 @@
const { Gio, GLib, GObject, Gtk, Pango } = imports.gi; const { Gio, GLib, GObject, Gtk, Pango } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); const _ = ExtensionUtils.gettext;
const _ = Gettext.gettext;
const SETTINGS_KEY = 'application-list'; const SETTINGS_KEY = 'application-list';
@@ -267,10 +265,14 @@ class NewRuleDialog extends Gtk.AppChooserDialog {
} }
}); });
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() { function buildPrefsWidget() {
return new AutoMoveSettingsWidget(); return new AutoMoveSettingsWidget();
} }
+4 -3
View File
@@ -8,9 +8,7 @@ const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const ShellMountOperation = imports.ui.shellMountOperation; const ShellMountOperation = imports.ui.shellMountOperation;
const Me = ExtensionUtils.getCurrentExtension(); const _ = ExtensionUtils.gettext;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
var MountMenuItem = GObject.registerClass( var MountMenuItem = GObject.registerClass(
class MountMenuItem extends PopupMenu.PopupBaseMenuItem { class MountMenuItem extends PopupMenu.PopupBaseMenuItem {
@@ -218,17 +216,20 @@ class DriveMenu extends PanelMenu.Button {
} }
}); });
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
let _indicator; let _indicator;
/** */
function enable() { function enable() {
_indicator = new DriveMenu(); _indicator = new DriveMenu();
Main.panel.addToStatusArea('drive-menu', _indicator); Main.panel.addToStatusArea('drive-menu', _indicator);
} }
/** */
function disable() { function disable() {
_indicator.destroy(); _indicator.destroy();
} }
@@ -3,6 +3,7 @@ const AppDisplay = imports.ui.appDisplay;
let _activateOriginal = null; let _activateOriginal = null;
/** */
function enable() { function enable() {
_activateOriginal = AppDisplay.AppIcon.prototype.activate; _activateOriginal = AppDisplay.AppIcon.prototype.activate;
AppDisplay.AppIcon.prototype.activate = function () { AppDisplay.AppIcon.prototype.activate = function () {
@@ -10,6 +11,7 @@ function enable() {
}; };
} }
/** */
function disable() { function disable() {
AppDisplay.AppIcon.prototype.activate = _activateOriginal; AppDisplay.AppIcon.prototype.activate = _activateOriginal;
} }
@@ -238,11 +238,13 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
let winInjections, workspaceInjections; let winInjections, workspaceInjections;
/** */
function resetState() { function resetState() {
winInjections = { }; winInjections = { };
workspaceInjections = { }; workspaceInjections = { };
} }
/** */
function enable() { function enable() {
resetState(); resetState();
@@ -282,6 +284,11 @@ function enable() {
}; };
} }
/**
* @param {Object} object - object that was modified
* @param {Object} injection - the map of previous injections
* @param {string} name - the @injection key that should be removed
*/
function removeInjection(object, injection, name) { function removeInjection(object, injection, name) {
if (injection[name] === undefined) if (injection[name] === undefined)
delete object[name]; delete object[name];
@@ -289,6 +296,7 @@ function removeInjection(object, injection, name) {
object[name] = injection[name]; object[name] = injection[name];
} }
/** */
function disable() { function disable() {
var i; var i;
@@ -1 +1,9 @@
/* This extensions requires no special styling */ .window-caption {
-shell-caption-spacing: 13px; /* current caption height is 26px => set it to half of it. TODO: better solution needed */
}
.window-picker {
-horizontal-spacing: 32px;
-vertical-spacing: 32px;
padding: 64px 32px;
}
+6 -5
View File
@@ -9,13 +9,11 @@ const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Me = ExtensionUtils.getCurrentExtension(); const Me = ExtensionUtils.getCurrentExtension();
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const N_ = x => x;
const PlaceDisplay = Me.imports.placeDisplay; const PlaceDisplay = Me.imports.placeDisplay;
const _ = ExtensionUtils.gettext;
const N_ = x => x;
const PLACE_ICON_SIZE = 16; const PLACE_ICON_SIZE = 16;
var PlaceMenuItem = GObject.registerClass( var PlaceMenuItem = GObject.registerClass(
@@ -134,12 +132,14 @@ class PlacesMenu extends PanelMenu.Button {
} }
}); });
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
let _indicator; let _indicator;
/** */
function enable() { function enable() {
_indicator = new PlacesMenu(); _indicator = new PlacesMenu();
@@ -149,6 +149,7 @@ function enable() {
Main.panel.addToStatusArea('places-menu', _indicator, pos, 'left'); Main.panel.addToStatusArea('places-menu', _indicator, pos, 'left');
} }
/** */
function disable() { function disable() {
_indicator.destroy(); _indicator.destroy();
} }
+1 -4
View File
@@ -7,10 +7,7 @@ const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main; const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation; const ShellMountOperation = imports.ui.shellMountOperation;
const Me = ExtensionUtils.getCurrentExtension(); const _ = ExtensionUtils.gettext;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const N_ = x => x; const N_ = x => x;
const BACKGROUND_SCHEMA = 'org.gnome.desktop.background'; const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
@@ -28,11 +28,15 @@ const MESSAGE_FADE_TIME = 2000;
let text; let text;
/** */
function hideMessage() { function hideMessage() {
text.destroy(); text.destroy();
text = null; text = null;
} }
/**
* @param {string} message - the message to flash
*/
function flashMessage(message) { function flashMessage(message) {
if (!text) { if (!text) {
text = new St.Label({ style_class: 'screenshot-sizer-message' }); text = new St.Label({ style_class: 'screenshot-sizer-message' });
@@ -67,6 +71,11 @@ let SIZES = [
[720, 360], // Phone landscape fullscreen [720, 360], // Phone landscape fullscreen
]; ];
/**
* @param {Meta.Display} display - the display
* @param {Meta.Window=} window - for per-window bindings, the window
* @param {Meta.KeyBinding} binding - the key binding
*/
function cycleScreenshotSizes(display, window, binding) { function cycleScreenshotSizes(display, window, binding) {
// Probably this isn't useful with 5 sizes, but you can decrease instead // Probably this isn't useful with 5 sizes, but you can decrease instead
// of increase by holding down shift. // of increase by holding down shift.
@@ -133,6 +142,7 @@ function cycleScreenshotSizes(display, window, binding) {
flashMessage(message); flashMessage(message);
} }
/** */
function enable() { function enable() {
Main.wm.addKeybinding( Main.wm.addKeybinding(
'cycle-screenshot-sizes', 'cycle-screenshot-sizes',
@@ -148,6 +158,7 @@ function enable() {
cycleScreenshotSizes); cycleScreenshotSizes);
} }
/** */
function disable() { function disable() {
Main.wm.removeKeybinding('cycle-screenshot-sizes'); Main.wm.removeKeybinding('cycle-screenshot-sizes');
Main.wm.removeKeybinding('cycle-screenshot-sizes-backward'); Main.wm.removeKeybinding('cycle-screenshot-sizes-backward');
+3
View File
@@ -58,6 +58,9 @@ class ThemeManager {
} }
} }
/**
* @returns {ThemeManager} - the extension state object
*/
function init() { function init() {
return new ThemeManager(); return new ThemeManager();
} }
+4
View File
@@ -174,9 +174,13 @@ class ThemeRow extends Gtk.ListBoxRow {
} }
}); });
/** */
function init() { function init() {
} }
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() { function buildPrefsWidget() {
return new UserThemePrefsWidget(); return new UserThemePrefsWidget();
} }
+6
View File
@@ -3,6 +3,9 @@ const { GLib } = imports.gi;
const fn = (...args) => GLib.build_filenamev(args); const fn = (...args) => GLib.build_filenamev(args);
/**
* @returns {string[]} - an ordered list of theme directories
*/
function getThemeDirs() { function getThemeDirs() {
return [ return [
fn(GLib.get_home_dir(), '.themes'), fn(GLib.get_home_dir(), '.themes'),
@@ -11,6 +14,9 @@ function getThemeDirs() {
]; ];
} }
/**
* @returns {string[]} - an ordered list of mode theme directories
*/
function getModeThemeDirs() { function getModeThemeDirs() {
return GLib.get_system_data_dirs() return GLib.get_system_data_dirs()
.map(dir => fn(dir, 'gnome-shell', 'theme')); .map(dir => fn(dir, 'gnome-shell', 'theme'));
+99 -63
View File
@@ -11,8 +11,7 @@ const Me = ExtensionUtils.getCurrentExtension();
const { WindowPicker, WindowPickerToggle } = Me.imports.windowPicker; const { WindowPicker, WindowPickerToggle } = Me.imports.windowPicker;
const { WorkspaceIndicator } = Me.imports.workspaceIndicator; const { WorkspaceIndicator } = Me.imports.workspaceIndicator;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); const _ = ExtensionUtils.gettext;
const _ = Gettext.gettext;
const ICON_TEXTURE_SIZE = 24; const ICON_TEXTURE_SIZE = 24;
const DND_ACTIVATE_TIMEOUT = 500; const DND_ACTIVATE_TIMEOUT = 500;
@@ -23,34 +22,10 @@ const GroupingMode = {
ALWAYS: 2, ALWAYS: 2,
}; };
/**
function _minimizeOrActivateWindow(window) { * @param {Shell.App} app - an app
let focusWindow = global.display.focus_window; * @returns {number} - the smallest stable sequence of the app's windows
if (focusWindow === window || */
focusWindow && focusWindow.get_transient_for() === window)
window.minimize();
else
window.activate(global.get_current_time());
}
function _openMenu(menu) {
menu.open();
let event = Clutter.get_current_event();
if (event && event.type() === Clutter.EventType.KEY_RELEASE)
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
function _onMenuStateChanged(menu, isOpen) {
if (isOpen)
return;
let [x, y] = global.get_pointer();
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
if (Me.stateObj.someWindowListContains(actor))
actor.sync_hover();
}
function _getAppStableSequence(app) { function _getAppStableSequence(app) {
let windows = app.get_windows().filter(w => !w.skip_taskbar); let windows = app.get_windows().filter(w => !w.skip_taskbar);
return windows.reduce((prev, cur) => { return windows.reduce((prev, cur) => {
@@ -58,7 +33,6 @@ function _getAppStableSequence(app) {
}, Infinity); }, Infinity);
} }
class WindowContextMenu extends PopupMenu.PopupMenu { class WindowContextMenu extends PopupMenu.PopupMenu {
constructor(source, metaWindow) { constructor(source, metaWindow) {
super(source, 0.5, St.Side.BOTTOM); super(source, 0.5, St.Side.BOTTOM);
@@ -282,10 +256,37 @@ const BaseButton = GObject.registerClass({
return true; return true;
} }
_openMenu(menu) {
menu.open();
let event = Clutter.get_current_event();
if (event && event.type() === Clutter.EventType.KEY_RELEASE)
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
_minimizeOrActivateWindow(window) {
let focusWindow = global.display.focus_window;
if (focusWindow === window ||
focusWindow && focusWindow.get_transient_for() === window)
window.minimize();
else
window.activate(global.get_current_time());
}
_onMenuStateChanged(menu, isOpen) {
if (isOpen)
return;
let [x, y] = global.get_pointer();
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
if (Me.stateObj.someWindowListContains(actor))
actor.sync_hover();
}
_onPopupMenu(_actor) { _onPopupMenu(_actor) {
if (!this._canOpenPopupMenu() || this._contextMenu.isOpen) if (!this._canOpenPopupMenu() || this._contextMenu.isOpen)
return; return;
_openMenu(this._contextMenu); this._openMenu(this._contextMenu);
} }
_isFocused() { _isFocused() {
@@ -362,7 +363,8 @@ class WindowButton extends BaseButton {
this.label_actor = this._windowTitle.label_actor; this.label_actor = this._windowTitle.label_actor;
this._contextMenu = new WindowContextMenu(this, this.metaWindow); this._contextMenu = new WindowContextMenu(this, this.metaWindow);
this._contextMenu.connect('open-state-changed', _onMenuStateChanged); this._contextMenu.connect('open-state-changed',
this._onMenuStateChanged.bind(this));
this._contextMenu.actor.hide(); this._contextMenu.actor.hide();
this._contextMenuManager.addMenu(this._contextMenu); this._contextMenuManager.addMenu(this._contextMenu);
Main.uiGroup.add_actor(this._contextMenu.actor); Main.uiGroup.add_actor(this._contextMenu.actor);
@@ -382,9 +384,9 @@ class WindowButton extends BaseButton {
} }
if (button === 1) if (button === 1)
_minimizeOrActivateWindow(this.metaWindow); this._minimizeOrActivateWindow(this.metaWindow);
else else
_openMenu(this._contextMenu); this._openMenu(this._contextMenu);
} }
_isFocused() { _isFocused() {
@@ -518,14 +520,16 @@ class AppButton extends BaseButton {
this._menuManager = new PopupMenu.PopupMenuManager(this); this._menuManager = new PopupMenu.PopupMenuManager(this);
this._menu = new PopupMenu.PopupMenu(this, 0.5, St.Side.BOTTOM); this._menu = new PopupMenu.PopupMenu(this, 0.5, St.Side.BOTTOM);
this._menu.connect('open-state-changed', _onMenuStateChanged); this._menu.connect('open-state-changed',
this._onMenuStateChanged.bind(this));
this._menu.actor.hide(); this._menu.actor.hide();
this._menu.connect('activate', this._onMenuActivate.bind(this)); this._menu.connect('activate', this._onMenuActivate.bind(this));
this._menuManager.addMenu(this._menu); this._menuManager.addMenu(this._menu);
Main.uiGroup.add_actor(this._menu.actor); Main.uiGroup.add_actor(this._menu.actor);
this._appContextMenu = new AppContextMenu(this); this._appContextMenu = new AppContextMenu(this);
this._appContextMenu.connect('open-state-changed', _onMenuStateChanged); this._appContextMenu.connect('open-state-changed',
this._onMenuStateChanged.bind(this));
this._appContextMenu.actor.hide(); this._appContextMenu.actor.hide();
Main.uiGroup.add_actor(this._appContextMenu.actor); Main.uiGroup.add_actor(this._appContextMenu.actor);
@@ -592,7 +596,7 @@ class AppButton extends BaseButton {
this._singleWindowTitle.child = this._windowTitle; this._singleWindowTitle.child = this._windowTitle;
this._windowContextMenu = new WindowContextMenu(this, this.metaWindow); this._windowContextMenu = new WindowContextMenu(this, this.metaWindow);
this._windowContextMenu.connect( this._windowContextMenu.connect(
'open-state-changed', _onMenuStateChanged); 'open-state-changed', this._onMenuStateChanged.bind(this));
Main.uiGroup.add_actor(this._windowContextMenu.actor); Main.uiGroup.add_actor(this._windowContextMenu.actor);
this._windowContextMenu.actor.hide(); this._windowContextMenu.actor.hide();
this._contextMenuManager.addMenu(this._windowContextMenu); this._contextMenuManager.addMenu(this._windowContextMenu);
@@ -631,7 +635,7 @@ class AppButton extends BaseButton {
if (windows.length === 1) { if (windows.length === 1) {
if (contextMenuWasOpen) if (contextMenuWasOpen)
return; return;
_minimizeOrActivateWindow(windows[0]); this._minimizeOrActivateWindow(windows[0]);
} else { } else {
this._menu.removeAll(); this._menu.removeAll();
@@ -642,12 +646,12 @@ class AppButton extends BaseButton {
item._window = windows[i]; item._window = windows[i];
this._menu.addMenuItem(item); this._menu.addMenuItem(item);
} }
_openMenu(this._menu); this._openMenu(this._menu);
} }
} else { } else {
if (contextMenuWasOpen) if (contextMenuWasOpen)
return; return;
_openMenu(this._contextMenu); this._openMenu(this._contextMenu);
} }
} }
@@ -761,9 +765,10 @@ class WindowList extends St.Widget {
let workspaceManager = global.workspace_manager; let workspaceManager = global.workspace_manager;
this._workspaceSignals = new Map();
this._nWorkspacesChangedId = workspaceManager.connect( this._nWorkspacesChangedId = workspaceManager.connect(
'notify::n-workspaces', this._updateWorkspaceIndicatorVisibility.bind(this)); 'notify::n-workspaces', this._onWorkspacesChanged.bind(this));
this._updateWorkspaceIndicatorVisibility(); this._onWorkspacesChanged();
this._switchWorkspaceId = global.window_manager.connect( this._switchWorkspaceId = global.window_manager.connect(
'switch-workspace', this._checkGrouping.bind(this)); 'switch-workspace', this._checkGrouping.bind(this));
@@ -773,20 +778,19 @@ class WindowList extends St.Widget {
this._updateKeyboardAnchor(); this._updateKeyboardAnchor();
}); });
this._overviewHidingId = Main.overview.connect('hiding', () => { this._overviewHidingId = Main.overview.connect('hidden', () => {
this.visible = !Main.layoutManager.primaryMonitor.inFullscreen; this.visible = !Main.layoutManager.primaryMonitor.inFullscreen;
this._updateKeyboardAnchor(); this._updateKeyboardAnchor();
}); });
this._fullscreenChangedId = this._fullscreenChangedId =
global.display.connect('in-fullscreen-changed', () => { global.display.connect('in-fullscreen-changed', () => {
// Work-around for initial change from unknown to !fullscreen
if (Main.overview.visible)
this.hide();
this._updateKeyboardAnchor(); this._updateKeyboardAnchor();
}); });
this._windowSignals = new Map();
this._windowCreatedId = global.display.connect(
'window-created', (dsp, win) => this._addWindow(win));
this._dragBeginId = Main.xdndHandler.connect('drag-begin', this._dragBeginId = Main.xdndHandler.connect('drag-begin',
this._monitorDrag.bind(this)); this._monitorDrag.bind(this));
this._dragEndId = Main.xdndHandler.connect('drag-end', this._dragEndId = Main.xdndHandler.connect('drag-end',
@@ -909,7 +913,7 @@ class WindowList extends St.Widget {
w2.metaWindow.get_stable_sequence(); w2.metaWindow.get_stable_sequence();
}); });
for (let i = 0; i < windows.length; i++) for (let i = 0; i < windows.length; i++)
this._addWindow(windows[i].metaWindow); this._onWindowAdded(null, windows[i].metaWindow);
} else { } else {
let apps = this._appSystem.get_running().sort((a1, a2) => { let apps = this._appSystem.get_running().sort((a1, a2) => {
return _getAppStableSequence(a1) - return _getAppStableSequence(a1) -
@@ -921,8 +925,11 @@ class WindowList extends St.Widget {
} }
_updateKeyboardAnchor() { _updateKeyboardAnchor() {
const translationY = Main.overview.visible ? 0 : this.height; if (!Main.keyboard.keyboardActor)
Main.layoutManager.keyboardBox.translation_y = -translationY; return;
let translationY = Main.overview.visible ? 0 : this.height;
Main.keyboard.keyboardActor.translation_y = -translationY;
} }
_onAppStateChanged(appSys, app) { _onAppStateChanged(appSys, app) {
@@ -949,7 +956,7 @@ class WindowList extends St.Widget {
child.destroy(); child.destroy();
} }
_addWindow(win) { _onWindowAdded(ws, win) {
if (!this._grouped) if (!this._grouped)
this._checkGrouping(); this._checkGrouping();
@@ -960,26 +967,21 @@ class WindowList extends St.Widget {
if (children.find(c => c.metaWindow === win)) if (children.find(c => c.metaWindow === win))
return; return;
this._windowSignals.set(
win, win.connect('unmanaged', () => this._removeWindow(win)));
let button = new WindowButton(win, this._perMonitor, this._monitor.index); let button = new WindowButton(win, this._perMonitor, this._monitor.index);
this._settings.bind('display-all-workspaces', this._settings.bind('display-all-workspaces',
button, 'ignore-workspace', Gio.SettingsBindFlags.GET); button, 'ignore-workspace', Gio.SettingsBindFlags.GET);
this._windowList.add_child(button); this._windowList.add_child(button);
} }
_removeWindow(win) { _onWindowRemoved(ws, win) {
if (this._grouped) if (this._grouped)
this._checkGrouping(); this._checkGrouping();
if (this._grouped) if (this._grouped)
return; return;
const id = this._windowSignals.get(win); if (win.get_compositor_private())
if (id) return; // not actually removed, just moved to another workspace
win.disconnect(id);
this._windowSignals.delete(id);
let children = this._windowList.get_children(); let children = this._windowList.get_children();
let child = children.find(c => c.metaWindow === win); let child = children.find(c => c.metaWindow === win);
@@ -987,6 +989,39 @@ class WindowList extends St.Widget {
child.destroy(); child.destroy();
} }
_onWorkspacesChanged() {
let workspaceManager = global.workspace_manager;
let numWorkspaces = workspaceManager.n_workspaces;
for (let i = 0; i < numWorkspaces; i++) {
let workspace = workspaceManager.get_workspace_by_index(i);
if (this._workspaceSignals.has(workspace))
continue;
let signals = { windowAddedId: 0, windowRemovedId: 0 };
signals._windowAddedId = workspace.connect_after(
'window-added', this._onWindowAdded.bind(this));
signals._windowRemovedId = workspace.connect(
'window-removed', this._onWindowRemoved.bind(this));
this._workspaceSignals.set(workspace, signals);
}
this._updateWorkspaceIndicatorVisibility();
}
_disconnectWorkspaceSignals() {
let workspaceManager = global.workspace_manager;
let numWorkspaces = workspaceManager.n_workspaces;
for (let i = 0; i < numWorkspaces; i++) {
let workspace = workspaceManager.get_workspace_by_index(i);
let signals = this._workspaceSignals.get(workspace);
this._workspaceSignals.delete(workspace);
workspace.disconnect(signals._windowAddedId);
workspace.disconnect(signals._windowRemovedId);
}
}
_monitorDrag() { _monitorDrag() {
DND.addDragMonitor(this._dragMonitor); DND.addDragMonitor(this._dragMonitor);
} }
@@ -1050,20 +1085,18 @@ class WindowList extends St.Widget {
Main.keyboard._bottomDragAction.disconnect(this._keyboardVisiblechangedId); Main.keyboard._bottomDragAction.disconnect(this._keyboardVisiblechangedId);
this._keyboardVisiblechangedId = 0; this._keyboardVisiblechangedId = 0;
this._disconnectWorkspaceSignals();
global.workspace_manager.disconnect(this._nWorkspacesChangedId); global.workspace_manager.disconnect(this._nWorkspacesChangedId);
this._nWorkspacesChangedId = 0; this._nWorkspacesChangedId = 0;
global.window_manager.disconnect(this._switchWorkspaceId); global.window_manager.disconnect(this._switchWorkspaceId);
this._switchWorkspaceId = 0; this._switchWorkspaceId = 0;
this._windowSignals.forEach((id, win) => win.disconnect(id));
this._windowSignals.clear();
Main.overview.disconnect(this._overviewShowingId); Main.overview.disconnect(this._overviewShowingId);
Main.overview.disconnect(this._overviewHidingId); Main.overview.disconnect(this._overviewHidingId);
global.display.disconnect(this._fullscreenChangedId); global.display.disconnect(this._fullscreenChangedId);
global.display.disconnect(this._windowCreatedId);
this._stopMonitoringDrag(); this._stopMonitoringDrag();
Main.xdndHandler.disconnect(this._dragBeginId); Main.xdndHandler.disconnect(this._dragBeginId);
@@ -1144,6 +1177,9 @@ class Extension {
} }
} }
/**
* @returns {Extension} - the extension's state object
*/
function init() { function init() {
return new Extension(); return new Extension();
} }
+36 -49
View File
@@ -1,15 +1,13 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- // -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */ /* exported init buildPrefsWidget */
const { Gio, GObject, Gtk } = imports.gi; const { Gio, GLib, GObject, Gtk } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const _ = ExtensionUtils.gettext;
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
@@ -27,6 +25,17 @@ class WindowListPrefsWidget extends Gtk.Box {
halign: Gtk.Align.CENTER, halign: Gtk.Align.CENTER,
}); });
this._actionGroup = new Gio.SimpleActionGroup();
this.insert_action_group('window-list', this._actionGroup);
this._settings = ExtensionUtils.getSettings();
this._actionGroup.add_action(
this._settings.create_action('grouping-mode'));
this._actionGroup.add_action(
this._settings.create_action('show-on-all-monitors'));
this._actionGroup.add_action(
this._settings.create_action('display-all-workspaces'));
let groupingLabel = '<b>%s</b>'.format(_('Window Grouping')); let groupingLabel = '<b>%s</b>'.format(_('Window Grouping'));
this.append(new Gtk.Label({ this.append(new Gtk.Label({
label: groupingLabel, use_markup: true, label: groupingLabel, use_markup: true,
@@ -50,61 +59,39 @@ class WindowListPrefsWidget extends Gtk.Box {
context.add_class('frame'); context.add_class('frame');
context.add_class('view'); context.add_class('view');
this._settings = ExtensionUtils.getSettings(); const modes = [
let currentMode = this._settings.get_string('grouping-mode'); { mode: 'never', label: _('Never group windows') },
let range = this._settings.get_range('grouping-mode'); { mode: 'auto', label: _('Group windows when space is limited') },
let modes = range.deep_unpack()[1].deep_unpack(); { mode: 'always', label: _('Always group windows') },
];
let modeLabels = { let group = null;
'never': _('Never group windows'), for (const { mode, label } of modes) {
'auto': _('Group windows when space is limited'), const check = new Gtk.CheckButton({
'always': _('Always group windows'), action_name: 'window-list.grouping-mode',
}; action_target: new GLib.Variant('s', mode),
let radio = null;
let currentRadio = null;
for (let i = 0; i < modes.length; i++) {
let mode = modes[i];
let label = modeLabels[mode];
if (!label) {
log('Unhandled option "%s" for grouping-mode'.format(mode));
continue;
}
radio = new Gtk.CheckButton({
active: !i,
label, label,
group: radio, group,
margin_end: 12, margin_end: 12,
}); });
box.append(radio); group = check;
box.append(check);
if (currentMode === mode)
currentRadio = radio;
radio.connect('toggled', button => {
if (button.active)
this._settings.set_string('grouping-mode', mode);
});
} }
if (currentRadio) this.append(new Gtk.CheckButton({
currentRadio.active = true;
let check = new Gtk.CheckButton({
label: _('Show on all monitors'), label: _('Show on all monitors'),
}); action_name: 'window-list.show-on-all-monitors',
this._settings.bind('show-on-all-monitors', check, 'active', Gio.SettingsBindFlags.DEFAULT); }));
this.append(check);
check = new Gtk.CheckButton({ this.append(new Gtk.CheckButton({
label: _('Show windows from all workspaces'), label: _('Show windows from all workspaces'),
}); action_name: 'window-list.display-all-workspaces',
this._settings.bind('display-all-workspaces', check, 'active', Gio.SettingsBindFlags.DEFAULT); }));
this.append(check);
} }
}); });
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() { function buildPrefsWidget() {
return new WindowListPrefsWidget(); return new WindowListPrefsWidget();
} }
+1 -4
View File
@@ -7,10 +7,7 @@ const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Me = ExtensionUtils.getCurrentExtension(); const _ = ExtensionUtils.gettext;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const TOOLTIP_OFFSET = 6; const TOOLTIP_OFFSET = 6;
const TOOLTIP_ANIMATION_TIME = 150; const TOOLTIP_ANIMATION_TIME = 150;
+3
View File
@@ -262,6 +262,9 @@ class Extension {
} }
} }
/**
* @returns {Extension} - the extension's state object
*/
function init() { function init() {
return new Extension(); return new Extension();
} }
+4 -4
View File
@@ -9,10 +9,7 @@ const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Me = ExtensionUtils.getCurrentExtension(); const _ = ExtensionUtils.gettext;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
const WORKSPACE_KEY = 'workspace-names'; const WORKSPACE_KEY = 'workspace-names';
@@ -445,17 +442,20 @@ class WorkspaceIndicator extends PanelMenu.Button {
} }
}); });
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
let _indicator; let _indicator;
/** */
function enable() { function enable() {
_indicator = new WorkspaceIndicator(); _indicator = new WorkspaceIndicator();
Main.panel.addToStatusArea('workspace-indicator', _indicator); Main.panel.addToStatusArea('workspace-indicator', _indicator);
} }
/** */
function disable() { function disable() {
_indicator.destroy(); _indicator.destroy();
} }
+5 -3
View File
@@ -4,10 +4,8 @@
const { Gio, GLib, GObject, Gtk, Pango } = imports.gi; const { Gio, GLib, GObject, Gtk, Pango } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); const _ = ExtensionUtils.gettext;
const _ = Gettext.gettext;
const N_ = e => e; const N_ = e => e;
const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences'; const WORKSPACE_SCHEMA = 'org.gnome.desktop.wm.preferences';
@@ -210,10 +208,14 @@ class NewWorkspaceRow extends Gtk.ListBoxRow {
} }
}); });
/** */
function init() { function init() {
ExtensionUtils.initTranslations(); ExtensionUtils.initTranslations();
} }
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() { function buildPrefsWidget() {
return new WorkspaceSettingsWidget(); return new WorkspaceSettingsWidget();
} }
+29 -3
View File
@@ -1,8 +1,12 @@
--- ---
# SPDX-License-Identifier: MIT OR LGPL-2.0-or-later # SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
# SPDX-FileCopyrightText: 2018 Claudio André <claudioandre.br@gmail.com>
env: env:
es6: true es6: true
es2020: true
extends: 'eslint:recommended' extends: 'eslint:recommended'
plugins:
- jsdoc
rules: rules:
array-bracket-newline: array-bracket-newline:
- error - error
@@ -60,6 +64,17 @@ rules:
- 'CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child' - 'CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child'
# Allow dedenting chained member expressions # Allow dedenting chained member expressions
MemberExpression: 'off' MemberExpression: 'off'
jsdoc/check-alignment: error
jsdoc/check-param-names: error
jsdoc/check-tag-names: error
jsdoc/check-types: error
jsdoc/implements-on-classes: error
jsdoc/newline-after-description: error
jsdoc/require-jsdoc: error
jsdoc/require-param: error
jsdoc/require-param-description: error
jsdoc/require-param-name: error
jsdoc/require-param-type: error
key-spacing: key-spacing:
- error - error
- beforeColon: false - beforeColon: false
@@ -107,8 +122,15 @@ rules:
no-octal-escape: error no-octal-escape: error
no-proto: error no-proto: error
no-prototype-builtins: 'off' no-prototype-builtins: 'off'
no-restricted-globals: [error, window]
no-restricted-properties: no-restricted-properties:
- error - error
- object: imports
property: format
message: Use template strings
- object: pkg
property: initFormat
message: Use template strings
- object: Lang - object: Lang
property: copyProperties property: copyProperties
message: Use Object.assign() message: Use Object.assign()
@@ -167,6 +189,7 @@ rules:
object-curly-newline: object-curly-newline:
- error - error
- consistent: true - consistent: true
multiline: true
object-curly-spacing: error object-curly-spacing: error
object-shorthand: error object-shorthand: error
operator-assignment: error operator-assignment: error
@@ -214,14 +237,14 @@ rules:
template-curly-spacing: error template-curly-spacing: error
template-tag-spacing: error template-tag-spacing: error
unicode-bom: error unicode-bom: error
valid-jsdoc:
- error
- requireReturn: false
wrap-iife: wrap-iife:
- error - error
- inside - inside
yield-star-spacing: error yield-star-spacing: error
yoda: error yoda: error
settings:
jsdoc:
mode: typescript
globals: globals:
ARGV: readonly ARGV: readonly
Debugger: readonly Debugger: readonly
@@ -233,5 +256,8 @@ globals:
logError: readonly logError: readonly
print: readonly print: readonly
printerr: readonly printerr: readonly
window: readonly
TextEncoder: readonly
TextDecoder: readonly
parserOptions: parserOptions:
ecmaVersion: 2020 ecmaVersion: 2020
+4 -1
View File
@@ -1,5 +1,5 @@
project('gnome-shell-extensions', project('gnome-shell-extensions',
version: '40.7', version: '41.rc',
meson_version: '>= 0.44.0', meson_version: '>= 0.44.0',
license: 'GPL2+' license: 'GPL2+'
) )
@@ -89,3 +89,6 @@ subdir('extensions')
subdir('po') subdir('po')
meson.add_dist_script('meson/generate-stylesheets.py') meson.add_dist_script('meson/generate-stylesheets.py')
meson.add_dist_script('meson/check-version.py',
meson.project_version(),
'NEWS')
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env python3
import os, sys
from pathlib import Path
import argparse, subprocess
def check_version(version, file, type='news'):
if type == 'news':
line = file.open().readline()
ok = line.startswith(version)
print("{}: {}".format(file, "OK" if ok else "FAILED"))
if not ok:
raise Exception("{} does not start with {}".format(file, version))
elif type == 'metainfo':
subprocess.run(['appstream-util', 'validate-version', file, version],
check=True)
else:
raise Exception('Not implemented')
parser = argparse.ArgumentParser(description='Check release version information.')
parser.add_argument('--type', choices=['metainfo','news'], default='news')
parser.add_argument('version', help='the version to check for')
parser.add_argument('files', nargs='+', help='files to check')
args = parser.parse_args()
distroot = os.environ.get('MESON_DIST_ROOT', './')
try:
for file in args.files:
check_version(args.version, Path(distroot, file), args.type)
except:
sys.exit(1)
+263 -359
View File
@@ -1,359 +1,263 @@
# Bulgarian translation for gnome-shell-extensions po-file. # Bulgarian translation for gnome-shell-extensions po-file.
# Copyright (C) 2014, 2015, 2017 Free Software Foundation, Inc. # Copyright (C) 2014, 2015, 2017 Free Software Foundation, Inc.
# This file is distributed under the same license as the gnome-shell-extensions package. # Copyright (C) 2021 Alexander Shopov <ash@kambanaria.org>.
# Ivaylo Valkov <ivaylo@e-valkov.org>, 2014. # This file is distributed under the same license as the gnome-shell-extensions package.
# Alexander Shopov <ash@kambanaria.org>, 2014, 2015. # Ivaylo Valkov <ivaylo@e-valkov.org>, 2014.
# Lyubomir Vasilev <lyubomirv@abv.bg>, 2017. # Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2021.
msgid "" # Lyubomir Vasilev <lyubomirv@abv.bg>, 2017.
msgstr "" msgid ""
"Project-Id-Version: gnome-shell-extensions master\n" msgstr ""
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Project-Id-Version: gnome-shell-extensions master\n"
"shell&keywords=I18N+L10N&component=extensions\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/"
"POT-Creation-Date: 2017-09-09 15:20+0000\n" "issues\n"
"PO-Revision-Date: 2017-09-08 08:47+0300\n" "POT-Creation-Date: 2021-07-05 17:13+0000\n"
"Last-Translator: Lyubomir Vasilev <lyubomirv@abv.bg>\n" "PO-Revision-Date: 2021-07-11 10:19+0200\n"
"Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
"Language: bg\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
"MIME-Version: 1.0\n" "Language: bg\n"
"Content-Type: text/plain; charset=UTF-8\n" "MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: data/gnome-classic.desktop.in:3 data/gnome-classic.session.desktop.in:3
msgid "GNOME Classic" #: data/gnome-classic.desktop.in:3
msgstr "Класически GNOME" msgid "GNOME Classic"
msgstr "Класически GNOME"
#: data/gnome-classic.desktop.in:4
msgid "This session logs you into GNOME Classic" #: data/gnome-classic.desktop.in:4
msgstr "Работната среда изглежда като класическия GNOME (2.x)" msgid "This session logs you into GNOME Classic"
msgstr "Работната среда изглежда като класическия GNOME (2.x)"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:7
msgid "Attach modal dialog to the parent window" #: extensions/apps-menu/extension.js:113
msgstr "Прикрепяне на модалните прозорци към родителските им прозорци" msgid "Favorites"
msgstr "Любими"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:8
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:25 #: extensions/apps-menu/extension.js:367
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:33 msgid "Applications"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:41 msgstr "Програми"
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell." #: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:6
msgstr "" msgid "Application and workspace list"
"Този ключ при е с по-голям приоритет от „org.gnome.mutter“ при изпълнението " msgstr "Списък с програмите и работните плотове"
"на обвивката на GNOME."
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:7
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:16 msgid ""
msgid "Arrangement of buttons on the titlebar" "A list of strings, each containing an application id (desktop file name), "
msgstr "Подредба на бутоните на заглавната лента" "followed by a colon and the workspace number"
msgstr ""
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:17 "Списък от низове. Всеки съдържа идентификатор на програма (име на файл „."
msgid "" "desktop“), следван от знака „:“ и номер на работен плот"
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell." #: extensions/auto-move-windows/prefs.js:35
msgstr "" msgid "Workspace Rules"
"Този ключ при е с по-голям приоритет от „org.gnome.desktop.wm.preferences“ " msgstr "Правила за работните плотове"
"при изпълнението на обвивката на GNOME."
#: extensions/auto-move-windows/prefs.js:237
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:24 msgid "Add Rule"
msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Добавяне на правило"
msgstr ""
"Включване на специална подредба при приближаване на прозорец до ръбовете на " #. TRANSLATORS: %s is the filesystem name
"екрана" #: extensions/drive-menu/extension.js:132
#: extensions/places-menu/placeDisplay.js:233
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:32 #, javascript-format
msgid "Workspaces only on primary monitor" msgid "Ejecting drive “%s” failed:"
msgstr "Работни плотове само на основния екран" msgstr "Неуспешно изваждане на устройство „%s“:"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:40 #: extensions/drive-menu/extension.js:148
msgid "Delay focus changes in mouse mode until the pointer stops moving" msgid "Removable devices"
msgstr "Забавяне на смяната на фокуса до спирането на движението на показалеца" msgstr "Преносими медии"
#: extensions/alternate-tab/prefs.js:20 #: extensions/drive-menu/extension.js:172
msgid "Thumbnail only" msgid "Open Files"
msgstr "Само миниатюри" msgstr "Отваряне на файлове"
#: extensions/alternate-tab/prefs.js:21 #: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:5
msgid "Application icon only" msgid "Use more screen for windows"
msgstr "Само икони на приложенията" msgstr "Повече пространство за прозорците"
#: extensions/alternate-tab/prefs.js:22 #: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:6
msgid "Thumbnail and application icon" msgid ""
msgstr "Миниатюри и икони на приложенията" "Try to use more screen for placing window thumbnails by adapting to screen "
"aspect ratio, and consolidating them further to reduce the bounding box. "
#: extensions/alternate-tab/prefs.js:38 "This setting applies only with the natural placement strategy."
msgid "Present windows as" msgstr ""
msgstr "Показване на прозорците като" "Използване на по-голяма част от екрана за поставянето на мини изображения "
"чрез промяна на съотношението на страните и допълнително обединяване за "
#: extensions/alternate-tab/prefs.js:69 "смаляване на обхващащия ги правоъгълник. Тази настройка се прилага само при "
msgid "Show only windows in the current workspace" "естествената стратегия за поставяне на прозорците."
msgstr "Да се показват само прозорците на текущия работен плот"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:11
#: extensions/apps-menu/extension.js:41 msgid "Place window captions on top"
msgid "Activities Overview" msgstr "Заглавия на прозорците отгоре"
msgstr "Показване на програмите"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:12
#: extensions/apps-menu/extension.js:141 msgid ""
msgid "Favorites" "If true, place window captions on top the respective thumbnail, overriding "
msgstr "Любими" "shell default of placing it at the bottom. Changing this setting requires "
"restarting the shell to have any effect."
#: extensions/apps-menu/extension.js:436 msgstr ""
msgid "Applications" "Ако е истина, заглавията на прозорците се поставят над мини изображенията "
msgstr "Програми" "им, а не както е стандартно — отдолу. За прилагане на промяната на "
"настройката трябва да рестартирате обвивката на GNOME."
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:6
msgid "Application and workspace list" #: extensions/places-menu/extension.js:89
msgstr "Списък с програмите и работните плотове" #: extensions/places-menu/extension.js:92
msgid "Places"
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:7 msgstr "Места"
msgid ""
"A list of strings, each containing an application id (desktop file name), " #: extensions/places-menu/placeDisplay.js:46
"followed by a colon and the workspace number" #, javascript-format
msgstr "" msgid "Failed to launch “%s”"
"Списък от низове. Всеки съдържа идентификатор на програма (име на файл „." msgstr "Неуспешно стартиране на „%s“"
"desktop“ file name), следван от знака „:“ и номер на работен плот"
#: extensions/places-menu/placeDisplay.js:61
#: extensions/auto-move-windows/prefs.js:60 #, javascript-format
msgid "Application" msgid "Failed to mount volume for “%s”"
msgstr "Програма" msgstr "Неуспешно монтиране на тома „%s“"
#: extensions/auto-move-windows/prefs.js:69 #: extensions/places-menu/placeDisplay.js:148
#: extensions/auto-move-windows/prefs.js:127 #: extensions/places-menu/placeDisplay.js:171
msgid "Workspace" msgid "Computer"
msgstr "Работен плот" msgstr "Компютър"
#: extensions/auto-move-windows/prefs.js:85 #: extensions/places-menu/placeDisplay.js:359
msgid "Add Rule" msgid "Home"
msgstr "Добавяне на правило" msgstr "Домашна папка"
#: extensions/auto-move-windows/prefs.js:106 #: extensions/places-menu/placeDisplay.js:404
msgid "Create new matching rule" msgid "Browse Network"
msgstr "Създаване на правило за съвпадение" msgstr "Мрежа"
#: extensions/auto-move-windows/prefs.js:111 #: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:7
msgid "Add" msgid "Cycle Screenshot Sizes"
msgstr "Добавяне" msgstr "Смяна на размерите на снимката на екрана"
#. TRANSLATORS: %s is the filesystem name #: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:11
#: extensions/drive-menu/extension.js:107 msgid "Cycle Screenshot Sizes Backward"
#, javascript-format msgstr "Смяна на размерите на снимката на екрана наобратно"
msgid "Ejecting drive “%s” failed:"
msgstr "Неуспешно изваждане на устройство „%s“:" #: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:5
msgid "Theme name"
#: extensions/drive-menu/extension.js:125 msgstr "Име на темата"
msgid "Removable devices"
msgstr "Преносими медии" #: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:6
msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell"
#: extensions/drive-menu/extension.js:150 msgstr ""
msgid "Open Files" "Името на темата, която да бъде заредена от „~/.themes/name/gnome-shell“"
msgstr "Отваряне на файлове"
#: extensions/window-list/extension.js:98
#: extensions/example/extension.js:17 msgid "Close"
msgid "Hello, world!" msgstr "Затваряне"
msgstr "Здравей, свят!"
#: extensions/window-list/extension.js:118
#: extensions/example/org.gnome.shell.extensions.example.gschema.xml:5 msgid "Unminimize"
msgid "Alternative greeting text." msgstr "Деминимизиране"
msgstr "Друго приветстващо съобщение."
#: extensions/window-list/extension.js:118
#: extensions/example/org.gnome.shell.extensions.example.gschema.xml:6 msgid "Minimize"
msgid "" msgstr "Минимизиране"
"If not empty, it contains the text that will be shown when clicking on the "
"panel." #: extensions/window-list/extension.js:125
msgstr "" msgid "Unmaximize"
"Ако ключът не е празен, съдържанието му се извежда при натискането на панела." msgstr "Демаксимизиране"
#: extensions/example/prefs.js:30 #: extensions/window-list/extension.js:125
msgid "Message" msgid "Maximize"
msgstr "Съобщение" msgstr "Максимизиране"
#. TRANSLATORS: Example is the name of the extension, should not be #: extensions/window-list/extension.js:432
#. translated msgid "Minimize all"
#: extensions/example/prefs.js:43 msgstr "Минимизиране на всички"
msgid ""
"Example aims to show how to build well behaved extensions for the Shell and " #: extensions/window-list/extension.js:438
"as such it has little functionality on its own.\n" msgid "Unminimize all"
"Nevertheless its possible to customize the greeting message." msgstr "Деминимизиране на всички"
msgstr ""
"Това е пример за добре работещо разширение на обвивката на GNOME и има " #: extensions/window-list/extension.js:444
"минимална функционалност.\n" msgid "Maximize all"
"С него можете да промените приветстващото съобщение на панела." msgstr "Максимизиране на всички"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:5 #: extensions/window-list/extension.js:452
msgid "Use more screen for windows" msgid "Unmaximize all"
msgstr "Повече пространство за прозорците" msgstr "Демаксимизиране на всички"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:6 #: extensions/window-list/extension.js:460
msgid "" msgid "Close all"
"Try to use more screen for placing window thumbnails by adapting to screen " msgstr "Затваряне на всички"
"aspect ratio, and consolidating them further to reduce the bounding box. "
"This setting applies only with the natural placement strategy." #: extensions/window-list/extension.js:737
msgstr "" msgid "Window List"
"Използване на по-голяма част от екрана за поставянето на мини изображения " msgstr "Списък на прозорците"
"чрез промяна на съотношението на страните и допълнително обединяване за "
"смаляване на обхващащия ги правоъгълник. Тази настройка се прилага само при " #: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:12
"естествената стратегия за поставяне на прозорците." msgid "When to group windows"
msgstr "Кога прозорците да се групират"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:11
msgid "Place window captions on top" #: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:13
msgstr "Заглавия на прозорците отгоре" msgid ""
"Decides when to group windows from the same application on the window list. "
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:12 "Possible values are “never”, “auto” and “always”."
msgid "" msgstr ""
"If true, place window captions on top the respective thumbnail, overriding " "Кога прозорците на една програма да се групират в списъка с прозорците. "
"shell default of placing it at the bottom. Changing this setting requires " "Възможните стойности са „never“ (никога), „auto“ (автоматично) и "
"restarting the shell to have any effect." "„always“ (винаги)."
msgstr ""
"Ако е истина, заглавията на прозорците се поставят над мини изображенията " #: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20
"им, а не както е стандартно — отдолу. За прилагане на промяната на " #: extensions/window-list/prefs.js:100
"настройката трябва да рестартирате обвивката на GNOME." msgid "Show windows from all workspaces"
msgstr "Да се показват прозорците от всички работни плотове"
#: extensions/places-menu/extension.js:78
#: extensions/places-menu/extension.js:81 #: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:21
msgid "Places" msgid "Whether to show windows from all workspaces or only the current one."
msgstr "Места" msgstr ""
"Дали да се показват прозорците от всички работни плотове или само от текущия."
#: extensions/places-menu/placeDisplay.js:65
#, javascript-format #: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:27
msgid "Failed to mount volume for “%s”" msgid "Show the window list on all monitors"
msgstr "Неуспешно монтиране на тома „%s“" msgstr "Извеждане на списъка с прозорци на всички монитори"
#: extensions/places-menu/placeDisplay.js:78 #: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:28
#, javascript-format msgid ""
msgid "Failed to launch “%s”" "Whether to show the window list on all connected monitors or only on the "
msgstr "Неуспешно стартиране на „%s“" "primary one."
msgstr ""
#: extensions/places-menu/placeDisplay.js:137 "Дали списъкът с прозорци да се извежда на всички монитори или само на "
#: extensions/places-menu/placeDisplay.js:160 "основния"
msgid "Computer"
msgstr "Компютър" #: extensions/window-list/prefs.js:29
msgid "Window Grouping"
#: extensions/places-menu/placeDisplay.js:303 msgstr "Групиране на прозорци"
msgid "Home"
msgstr "Домашна папка" #: extensions/window-list/prefs.js:58
msgid "Never group windows"
#: extensions/places-menu/placeDisplay.js:347 msgstr "Никога да не се групират"
msgid "Browse Network"
msgstr "Мрежа" #: extensions/window-list/prefs.js:59
msgid "Group windows when space is limited"
#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:7 msgstr "Групиране при ограничено място"
msgid "Cycle Screenshot Sizes"
msgstr "Смяна на размерите на снимката на екрана" #: extensions/window-list/prefs.js:60
msgid "Always group windows"
#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:11 msgstr "Винаги да се групират"
msgid "Cycle Screenshot Sizes Backward"
msgstr "Смяна на размерите на снимката на екрана наобратно" #: extensions/window-list/prefs.js:94
msgid "Show on all monitors"
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:5 msgstr "На всички монитори"
msgid "Theme name"
msgstr "Име на темата" #: extensions/window-list/workspaceIndicator.js:249
#: extensions/workspace-indicator/extension.js:255
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:6 msgid "Workspace Indicator"
msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell" msgstr "Индикатор на работните плотове"
msgstr ""
"Името на темата, която да бъде заредена от „~/.themes/name/gnome-shell“" #: extensions/workspace-indicator/prefs.js:34
msgid "Workspace Names"
#: extensions/window-list/extension.js:110 msgstr "Имена на работните плотове"
msgid "Close"
msgstr "Затваряне" #: extensions/workspace-indicator/prefs.js:67
#, javascript-format
#: extensions/window-list/extension.js:129 msgid "Workspace %d"
msgid "Unminimize" msgstr "Работен плот %d"
msgstr "Деминимизиране"
#: extensions/workspace-indicator/prefs.js:208
#: extensions/window-list/extension.js:130 msgid "Add Workspace"
msgid "Minimize" msgstr "Добавяне на работен плот"
msgstr "Минимизиране"
#: extensions/window-list/extension.js:136
msgid "Unmaximize"
msgstr "Демаксимизиране"
#: extensions/window-list/extension.js:137
msgid "Maximize"
msgstr "Максимизиране"
#: extensions/window-list/extension.js:420
msgid "Minimize all"
msgstr "Минимизиране на всички"
#: extensions/window-list/extension.js:428
msgid "Unminimize all"
msgstr "Деминимизиране на всички"
#: extensions/window-list/extension.js:436
msgid "Maximize all"
msgstr "Максимизиране на всички"
#: extensions/window-list/extension.js:445
msgid "Unmaximize all"
msgstr "Демаксимизиране на всички"
#: extensions/window-list/extension.js:454
msgid "Close all"
msgstr "Затваряне на всички"
#: extensions/window-list/extension.js:678
#: extensions/workspace-indicator/extension.js:30
msgid "Workspace Indicator"
msgstr "Индикатор на работните плотове"
#: extensions/window-list/extension.js:842
msgid "Window List"
msgstr "Списък на прозорците"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:12
msgid "When to group windows"
msgstr "Кога да се групират прозорците"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:13
msgid ""
"Decides when to group windows from the same application on the window list. "
"Possible values are “never”, “auto” and “always”."
msgstr ""
"Кога да се групират прозорците на една програма в списъка с прозорците. "
"Възможните стойности са „never“ (никога), „auto“ (автоматично) и "
"„always“ (винаги)."
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20
msgid "Show the window list on all monitors"
msgstr "Извеждане на списъка с прозорци на всички монитори"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:21
msgid ""
"Whether to show the window list on all connected monitors or only on the "
"primary one."
msgstr ""
"Дали списъкът с прозорци да се извежда на всички монитори или само на "
"основния"
#: extensions/window-list/prefs.js:32
msgid "Window Grouping"
msgstr "Групиране на прозорци"
#: extensions/window-list/prefs.js:50
msgid "Never group windows"
msgstr "Никога да не се групират"
#: extensions/window-list/prefs.js:51
msgid "Group windows when space is limited"
msgstr "Групиране при ограничено място"
#: extensions/window-list/prefs.js:52
msgid "Always group windows"
msgstr "Винаги да се групират"
#: extensions/window-list/prefs.js:75
msgid "Show on all monitors"
msgstr "На всички монитори"
#: extensions/workspace-indicator/prefs.js:141
msgid "Workspace Names"
msgstr "Имена на работните плотове"
#: extensions/workspace-indicator/prefs.js:157
msgid "Name"
msgstr "Име"
#: extensions/workspace-indicator/prefs.js:198
#, javascript-format
msgid "Workspace %d"
msgstr "Работен плот %d"