summaryrefslogtreecommitdiffstats
path: root/extensions/44
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-12-10 13:32:02 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-12-10 14:44:01 +0000
commit2705a55fe1128387a1761cae93b1e41ebaeb750d (patch)
tree87178c5463e34efb0b3847e0559011ec7d49d8e2 /extensions/44
parentAdding upstream version 20230618. (diff)
downloadgnome-shell-extensions-extra-2705a55fe1128387a1761cae93b1e41ebaeb750d.tar.xz
gnome-shell-extensions-extra-2705a55fe1128387a1761cae93b1e41ebaeb750d.zip
Adding upstream version 20231210.upstream/20231012
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--extensions/44/disable-workspace-switcher.mk (renamed from extensions/disable-workspace-switcher.mk)0
-rw-r--r--extensions/44/disable-workspace-switcher/LICENSE (renamed from extensions/disable-workspace-switcher/LICENSE)0
-rw-r--r--extensions/44/disable-workspace-switcher/README.md (renamed from extensions/disable-workspace-switcher/README.md)0
-rw-r--r--extensions/44/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/extension.js (renamed from extensions/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/extension.js)0
-rw-r--r--extensions/44/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/metadata.json (renamed from extensions/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/metadata.json)0
-rw-r--r--extensions/44/hibernate-status.mk (renamed from extensions/hibernate-status.mk)0
-rw-r--r--extensions/44/hibernate-status/.gitignore (renamed from extensions/hibernate-status/.gitignore)0
-rw-r--r--extensions/44/hibernate-status/LICENSE (renamed from extensions/hibernate-status/LICENSE)0
-rw-r--r--extensions/44/hibernate-status/Makefile (renamed from extensions/hibernate-status/Makefile)0
-rw-r--r--extensions/44/hibernate-status/README.md (renamed from extensions/hibernate-status/README.md)0
-rwxr-xr-xextensions/44/hibernate-status/buildforupload.sh (renamed from extensions/hibernate-status/buildforupload.sh)0
-rw-r--r--extensions/44/hibernate-status/confirmDialog.js (renamed from extensions/hibernate-status/confirmDialog.js)2
-rw-r--r--extensions/44/hibernate-status/extension.js (renamed from extensions/hibernate-status/extension.js)0
-rw-r--r--extensions/44/hibernate-status/locale/bg/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/bg/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/cs/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/cs/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/de/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/de/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/es/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/es/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/fa/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/fa/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/fr/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/fr/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/hu/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/hu/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/it/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/it/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/nl/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/nl/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/oc/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/oc/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/pl/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/pl/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/pt/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/pt/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/pt_BR/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/pt_BR/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/ru/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/ru/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/uk/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/uk/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/locale/zh_CN/LC_MESSAGES/hibernate-status-button.po (renamed from extensions/hibernate-status/locale/zh_CN/LC_MESSAGES/hibernate-status-button.po)0
-rw-r--r--extensions/44/hibernate-status/metadata.json (renamed from extensions/hibernate-status/metadata.json)0
-rw-r--r--extensions/44/hibernate-status/prefs.js (renamed from extensions/hibernate-status/prefs.js)0
-rw-r--r--extensions/44/hibernate-status/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml (renamed from extensions/hibernate-status/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml)0
-rw-r--r--extensions/44/middleclickclose.mk (renamed from extensions/middleclickclose.mk)0
-rw-r--r--extensions/44/middleclickclose/.gitignore (renamed from extensions/middleclickclose/.gitignore)0
-rw-r--r--extensions/44/middleclickclose/LICENSE (renamed from extensions/middleclickclose/LICENSE)0
-rw-r--r--extensions/44/middleclickclose/README.md (renamed from extensions/middleclickclose/README.md)0
-rwxr-xr-xextensions/44/middleclickclose/buildforupload.sh (renamed from extensions/middleclickclose/buildforupload.sh)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/extension.js (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/extension.js)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.mo (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.mo)bin1335 -> 1335 bytes
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.po (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.po)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.mo (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.mo)bin1366 -> 1366 bytes
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.po (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.po)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.mo (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.mo)bin1401 -> 1401 bytes
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.po (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.po)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.mo (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.mo)bin1286 -> 1286 bytes
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.po (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.po)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.mo (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.mo)bin1387 -> 1387 bytes
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.po (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.po)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/metadata.json (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/metadata.json)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/prefs.js (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/prefs.js)0
-rw-r--r--extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/schemas/org.gnome.shell.extensions.middleclickclose.gschema.xml (renamed from extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/schemas/org.gnome.shell.extensions.middleclickclose.gschema.xml)0
-rw-r--r--extensions/44/middleclickclose/tweak-tool-screenshot.png (renamed from extensions/middleclickclose/tweak-tool-screenshot.png)bin73982 -> 73982 bytes
-rw-r--r--extensions/44/multi-monitors-add-on.mk (renamed from extensions/multi-monitors-add-on.mk)0
-rw-r--r--extensions/44/multi-monitors-add-on/.project (renamed from extensions/multi-monitors-add-on/.project)0
-rw-r--r--extensions/44/multi-monitors-add-on/LICENSE (renamed from extensions/multi-monitors-add-on/LICENSE)0
-rw-r--r--extensions/44/multi-monitors-add-on/README.md (renamed from extensions/multi-monitors-add-on/README.md)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/convenience.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/convenience.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-l-symbolic.svg (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-l-symbolic.svg)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-r-symbolic.svg (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-r-symbolic.svg)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/indicator.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/indicator.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.mo (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.mo)bin1722 -> 1722 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.po (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.po)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.mo (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.mo)bin1593 -> 1593 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.po (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.po)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.mo (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.mo)bin1701 -> 1701 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.po (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.po)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.mo (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.mo)bin1820 -> 1820 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.po (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.po)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.mo (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.mo)bin1743 -> 1743 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.po (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.po)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.mo (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.mo)bin1759 -> 1759 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.po (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.po)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/metadata.json (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/metadata.json)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmcalendar.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmcalendar.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmlayout.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmlayout.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmoverview.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmoverview.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmpanel.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmpanel.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/multi-monitors-add-on.pot (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/multi-monitors-add-on.pot)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/prefs.js (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/prefs.js)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/gschemas.compiled (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/gschemas.compiled)bin788 -> 788 bytes
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/org.gnome.shell.extensions.multi-monitors-add-on.gschema.xml (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/org.gnome.shell.extensions.multi-monitors-add-on.gschema.xml)0
-rw-r--r--extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/stylesheet.css (renamed from extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/stylesheet.css)0
-rw-r--r--extensions/44/no-overview.mk (renamed from extensions/no-overview.mk)0
-rw-r--r--extensions/44/no-overview/LICENSE (renamed from extensions/no-overview/LICENSE)0
-rw-r--r--extensions/44/no-overview/README.md (renamed from extensions/no-overview/README.md)0
-rw-r--r--extensions/44/no-overview/extension.js (renamed from extensions/no-overview/extension.js)0
-rw-r--r--extensions/44/no-overview/metadata.json18
-rw-r--r--extensions/44/vertical-workspaces.mk (renamed from extensions/vertical-workspaces.mk)0
-rw-r--r--extensions/44/vertical-workspaces/.github/ISSUE_TEMPLATE/bug_report.md (renamed from extensions/vertical-workspaces/.github/ISSUE_TEMPLATE/bug_report.md)0
-rw-r--r--extensions/44/vertical-workspaces/.github/ISSUE_TEMPLATE/feature_request.md (renamed from extensions/vertical-workspaces/.github/ISSUE_TEMPLATE/feature_request.md)0
-rw-r--r--extensions/44/vertical-workspaces/CHANGELOG.md (renamed from extensions/vertical-workspaces/CHANGELOG.md)96
-rw-r--r--extensions/44/vertical-workspaces/LICENSE (renamed from extensions/vertical-workspaces/LICENSE)0
-rw-r--r--extensions/44/vertical-workspaces/Makefile (renamed from extensions/vertical-workspaces/Makefile)0
-rw-r--r--extensions/44/vertical-workspaces/README.md (renamed from extensions/vertical-workspaces/README.md)18
-rw-r--r--extensions/44/vertical-workspaces/extension.js793
-rw-r--r--extensions/44/vertical-workspaces/lib/appDisplay.js (renamed from extensions/vertical-workspaces/lib/appDisplay.js)1243
-rw-r--r--extensions/44/vertical-workspaces/lib/appFavorites.js79
-rw-r--r--extensions/44/vertical-workspaces/lib/dash.js1506
-rw-r--r--extensions/44/vertical-workspaces/lib/extensionsSearchProvider.js423
-rw-r--r--extensions/44/vertical-workspaces/lib/iconGrid.js (renamed from extensions/vertical-workspaces/lib/iconGrid.js)131
-rw-r--r--extensions/44/vertical-workspaces/lib/layout.js (renamed from extensions/vertical-workspaces/lib/layout.js)211
-rw-r--r--extensions/44/vertical-workspaces/lib/messageTray.js91
-rw-r--r--extensions/44/vertical-workspaces/lib/optionsFactory.js (renamed from extensions/vertical-workspaces/lib/optionsFactory.js)251
-rw-r--r--extensions/44/vertical-workspaces/lib/osdWindow.js118
-rw-r--r--extensions/44/vertical-workspaces/lib/overlayKey.js168
-rw-r--r--extensions/44/vertical-workspaces/lib/overview.js165
-rw-r--r--extensions/44/vertical-workspaces/lib/overviewControls.js (renamed from extensions/vertical-workspaces/lib/overviewControls.js)827
-rw-r--r--extensions/44/vertical-workspaces/lib/panel.js256
-rw-r--r--extensions/44/vertical-workspaces/lib/recentFilesSearchProvider.js258
-rw-r--r--extensions/44/vertical-workspaces/lib/search.js323
-rw-r--r--extensions/44/vertical-workspaces/lib/searchController.js94
-rw-r--r--extensions/44/vertical-workspaces/lib/settings.js (renamed from extensions/vertical-workspaces/lib/settings.js)300
-rw-r--r--extensions/44/vertical-workspaces/lib/swipeTracker.js (renamed from extensions/vertical-workspaces/lib/swipeTracker.js)95
-rw-r--r--extensions/44/vertical-workspaces/lib/util.js (renamed from extensions/vertical-workspaces/lib/util.js)199
-rw-r--r--extensions/44/vertical-workspaces/lib/winTmb.js525
-rw-r--r--extensions/44/vertical-workspaces/lib/windowAttentionHandler.js (renamed from extensions/vertical-workspaces/lib/windowAttentionHandler.js)80
-rw-r--r--extensions/44/vertical-workspaces/lib/windowManager.js (renamed from extensions/vertical-workspaces/lib/windowManager.js)148
-rw-r--r--extensions/44/vertical-workspaces/lib/windowPreview.js633
-rw-r--r--extensions/44/vertical-workspaces/lib/windowSearchProvider.js (renamed from extensions/vertical-workspaces/lib/windowSearchProvider.js)229
-rw-r--r--extensions/44/vertical-workspaces/lib/workspace.js (renamed from extensions/vertical-workspaces/lib/workspace.js)75
-rw-r--r--extensions/44/vertical-workspaces/lib/workspaceAnimation.js206
-rw-r--r--extensions/44/vertical-workspaces/lib/workspaceSwitcherPopup.js109
-rw-r--r--extensions/44/vertical-workspaces/lib/workspaceThumbnail.js (renamed from extensions/vertical-workspaces/lib/workspaceThumbnail.js)248
-rw-r--r--extensions/44/vertical-workspaces/lib/workspacesView.js993
-rw-r--r--extensions/44/vertical-workspaces/metadata.json (renamed from extensions/vertical-workspaces/metadata.json)10
-rw-r--r--extensions/44/vertical-workspaces/po/cs.po (renamed from extensions/vertical-workspaces/po/cs.po)0
-rw-r--r--extensions/44/vertical-workspaces/po/nl.po1551
-rw-r--r--extensions/44/vertical-workspaces/po/vertical-workspaces.pot (renamed from extensions/vertical-workspaces/po/vertical-workspaces.pot)0
-rw-r--r--extensions/44/vertical-workspaces/prefs.js (renamed from extensions/vertical-workspaces/prefs.js)1039
-rw-r--r--extensions/44/vertical-workspaces/schemas/org.gnome.shell.extensions.vertical-workspaces.gschema.xml408
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot.jpg (renamed from extensions/vertical-workspaces/screenshots/screenshot.jpg)bin416550 -> 416550 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot0.jpg (renamed from extensions/vertical-workspaces/screenshots/screenshot0.jpg)bin290880 -> 290880 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot0.png (renamed from extensions/vertical-workspaces/screenshots/screenshot0.png)bin1027234 -> 1027234 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot1.png (renamed from extensions/vertical-workspaces/screenshots/screenshot1.png)bin280303 -> 280303 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot2.png (renamed from extensions/vertical-workspaces/screenshots/screenshot2.png)bin286557 -> 286557 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot3.png (renamed from extensions/vertical-workspaces/screenshots/screenshot3.png)bin384363 -> 384363 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot4.png (renamed from extensions/vertical-workspaces/screenshots/screenshot4.png)bin148233 -> 148233 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/screenshot5.png (renamed from extensions/vertical-workspaces/screenshots/screenshot5.png)bin51071 -> 51071 bytes
-rw-r--r--extensions/44/vertical-workspaces/screenshots/vertical-workspaces.gif (renamed from extensions/vertical-workspaces/screenshots/vertical-workspaces.gif)bin1213475 -> 1213475 bytes
-rw-r--r--extensions/44/vertical-workspaces/stylesheet.css307
141 files changed, 12264 insertions, 1962 deletions
diff --git a/extensions/disable-workspace-switcher.mk b/extensions/44/disable-workspace-switcher.mk
index f522857..f522857 100644
--- a/extensions/disable-workspace-switcher.mk
+++ b/extensions/44/disable-workspace-switcher.mk
diff --git a/extensions/disable-workspace-switcher/LICENSE b/extensions/44/disable-workspace-switcher/LICENSE
index f288702..f288702 100644
--- a/extensions/disable-workspace-switcher/LICENSE
+++ b/extensions/44/disable-workspace-switcher/LICENSE
diff --git a/extensions/disable-workspace-switcher/README.md b/extensions/44/disable-workspace-switcher/README.md
index bae853f..bae853f 100644
--- a/extensions/disable-workspace-switcher/README.md
+++ b/extensions/44/disable-workspace-switcher/README.md
diff --git a/extensions/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/extension.js b/extensions/44/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/extension.js
index e805c3b..e805c3b 100644
--- a/extensions/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/extension.js
+++ b/extensions/44/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/extension.js
diff --git a/extensions/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/metadata.json b/extensions/44/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/metadata.json
index 68f10c5..68f10c5 100644
--- a/extensions/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/metadata.json
+++ b/extensions/44/disable-workspace-switcher/disable-workspace-switcher@jbradaric.me/metadata.json
diff --git a/extensions/hibernate-status.mk b/extensions/44/hibernate-status.mk
index 05651b5..05651b5 100644
--- a/extensions/hibernate-status.mk
+++ b/extensions/44/hibernate-status.mk
diff --git a/extensions/hibernate-status/.gitignore b/extensions/44/hibernate-status/.gitignore
index 68270f9..68270f9 100644
--- a/extensions/hibernate-status/.gitignore
+++ b/extensions/44/hibernate-status/.gitignore
diff --git a/extensions/hibernate-status/LICENSE b/extensions/44/hibernate-status/LICENSE
index d6a9326..d6a9326 100644
--- a/extensions/hibernate-status/LICENSE
+++ b/extensions/44/hibernate-status/LICENSE
diff --git a/extensions/hibernate-status/Makefile b/extensions/44/hibernate-status/Makefile
index 80f5796..80f5796 100644
--- a/extensions/hibernate-status/Makefile
+++ b/extensions/44/hibernate-status/Makefile
diff --git a/extensions/hibernate-status/README.md b/extensions/44/hibernate-status/README.md
index ff88abd..ff88abd 100644
--- a/extensions/hibernate-status/README.md
+++ b/extensions/44/hibernate-status/README.md
diff --git a/extensions/hibernate-status/buildforupload.sh b/extensions/44/hibernate-status/buildforupload.sh
index d2c705c..d2c705c 100755
--- a/extensions/hibernate-status/buildforupload.sh
+++ b/extensions/44/hibernate-status/buildforupload.sh
diff --git a/extensions/hibernate-status/confirmDialog.js b/extensions/44/hibernate-status/confirmDialog.js
index 62069e2..8d56ed9 100644
--- a/extensions/hibernate-status/confirmDialog.js
+++ b/extensions/44/hibernate-status/confirmDialog.js
@@ -164,12 +164,12 @@ class ConfirmDialog extends ModalDialog.ModalDialog {
let keys = dialog.confirmButtons[i].key;
buttons.push({
action: () => {
- this.close();
let signalId = this.connect('closed',
() => {
this.disconnect(signalId);
this._confirm(signal);
});
+ this.close();
},
label: label,
key: keys
diff --git a/extensions/hibernate-status/extension.js b/extensions/44/hibernate-status/extension.js
index 6e0b248..6e0b248 100644
--- a/extensions/hibernate-status/extension.js
+++ b/extensions/44/hibernate-status/extension.js
diff --git a/extensions/hibernate-status/locale/bg/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/bg/LC_MESSAGES/hibernate-status-button.po
index 689fee9..689fee9 100644
--- a/extensions/hibernate-status/locale/bg/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/bg/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/cs/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/cs/LC_MESSAGES/hibernate-status-button.po
index 32e541d..32e541d 100644
--- a/extensions/hibernate-status/locale/cs/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/cs/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/de/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/de/LC_MESSAGES/hibernate-status-button.po
index 3fdb8c2..3fdb8c2 100644
--- a/extensions/hibernate-status/locale/de/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/de/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/es/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/es/LC_MESSAGES/hibernate-status-button.po
index 92c14bc..92c14bc 100644
--- a/extensions/hibernate-status/locale/es/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/es/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/fa/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/fa/LC_MESSAGES/hibernate-status-button.po
index e4edef0..e4edef0 100644
--- a/extensions/hibernate-status/locale/fa/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/fa/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/fr/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/fr/LC_MESSAGES/hibernate-status-button.po
index 9dca80d..9dca80d 100644
--- a/extensions/hibernate-status/locale/fr/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/fr/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/hu/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/hu/LC_MESSAGES/hibernate-status-button.po
index 70da5aa..70da5aa 100644
--- a/extensions/hibernate-status/locale/hu/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/hu/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/it/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/it/LC_MESSAGES/hibernate-status-button.po
index a41e5ac..a41e5ac 100644
--- a/extensions/hibernate-status/locale/it/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/it/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/nl/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/nl/LC_MESSAGES/hibernate-status-button.po
index 3146d8a..3146d8a 100644
--- a/extensions/hibernate-status/locale/nl/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/nl/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/oc/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/oc/LC_MESSAGES/hibernate-status-button.po
index 25debf8..25debf8 100644
--- a/extensions/hibernate-status/locale/oc/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/oc/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/pl/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/pl/LC_MESSAGES/hibernate-status-button.po
index 57b735c..57b735c 100644
--- a/extensions/hibernate-status/locale/pl/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/pl/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/pt/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/pt/LC_MESSAGES/hibernate-status-button.po
index 143129c..143129c 100644
--- a/extensions/hibernate-status/locale/pt/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/pt/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/pt_BR/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/pt_BR/LC_MESSAGES/hibernate-status-button.po
index 326481a..326481a 100644
--- a/extensions/hibernate-status/locale/pt_BR/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/pt_BR/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/ru/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/ru/LC_MESSAGES/hibernate-status-button.po
index c55e2c6..c55e2c6 100644
--- a/extensions/hibernate-status/locale/ru/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/ru/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/uk/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/uk/LC_MESSAGES/hibernate-status-button.po
index 68c6b8c..68c6b8c 100644
--- a/extensions/hibernate-status/locale/uk/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/uk/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/locale/zh_CN/LC_MESSAGES/hibernate-status-button.po b/extensions/44/hibernate-status/locale/zh_CN/LC_MESSAGES/hibernate-status-button.po
index d6a6ebe..d6a6ebe 100644
--- a/extensions/hibernate-status/locale/zh_CN/LC_MESSAGES/hibernate-status-button.po
+++ b/extensions/44/hibernate-status/locale/zh_CN/LC_MESSAGES/hibernate-status-button.po
diff --git a/extensions/hibernate-status/metadata.json b/extensions/44/hibernate-status/metadata.json
index 0c05d48..0c05d48 100644
--- a/extensions/hibernate-status/metadata.json
+++ b/extensions/44/hibernate-status/metadata.json
diff --git a/extensions/hibernate-status/prefs.js b/extensions/44/hibernate-status/prefs.js
index 83b5843..83b5843 100644
--- a/extensions/hibernate-status/prefs.js
+++ b/extensions/44/hibernate-status/prefs.js
diff --git a/extensions/hibernate-status/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml b/extensions/44/hibernate-status/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml
index f29ec1c..f29ec1c 100644
--- a/extensions/hibernate-status/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml
+++ b/extensions/44/hibernate-status/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml
diff --git a/extensions/middleclickclose.mk b/extensions/44/middleclickclose.mk
index d484427..d484427 100644
--- a/extensions/middleclickclose.mk
+++ b/extensions/44/middleclickclose.mk
diff --git a/extensions/middleclickclose/.gitignore b/extensions/44/middleclickclose/.gitignore
index 4df7101..4df7101 100644
--- a/extensions/middleclickclose/.gitignore
+++ b/extensions/44/middleclickclose/.gitignore
diff --git a/extensions/middleclickclose/LICENSE b/extensions/44/middleclickclose/LICENSE
index 22fbe5d..22fbe5d 100644
--- a/extensions/middleclickclose/LICENSE
+++ b/extensions/44/middleclickclose/LICENSE
diff --git a/extensions/middleclickclose/README.md b/extensions/44/middleclickclose/README.md
index fba2916..fba2916 100644
--- a/extensions/middleclickclose/README.md
+++ b/extensions/44/middleclickclose/README.md
diff --git a/extensions/middleclickclose/buildforupload.sh b/extensions/44/middleclickclose/buildforupload.sh
index be665d6..be665d6 100755
--- a/extensions/middleclickclose/buildforupload.sh
+++ b/extensions/44/middleclickclose/buildforupload.sh
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/extension.js b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/extension.js
index 931a405..931a405 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/extension.js
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/extension.js
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.mo b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.mo
index 33687cb..33687cb 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.mo
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.mo
Binary files differ
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.po b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.po
index aed9f54..aed9f54 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.po
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/de/LC_MESSAGES/de_DE.po
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.mo b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.mo
index eaedef4..eaedef4 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.mo
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.mo
Binary files differ
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.po b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.po
index b842115..b842115 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.po
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/fr/LC_MESSAGES/fr.po
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.mo b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.mo
index dbe500d..dbe500d 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.mo
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.mo
Binary files differ
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.po b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.po
index bcc71c4..bcc71c4 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.po
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/it/LC_MESSAGES/it.po
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.mo b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.mo
index 1b5cf7a..1b5cf7a 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.mo
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.mo
Binary files differ
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.po b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.po
index 62fc210..62fc210 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.po
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/nl/nl.po
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.mo b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.mo
index 4ceacc9..4ceacc9 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.mo
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.mo
Binary files differ
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.po b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.po
index 801f9bc..801f9bc 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.po
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/locale/sk/LC_MESSAGES/sk.po
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/metadata.json b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/metadata.json
index bc177b3..bc177b3 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/metadata.json
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/metadata.json
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/prefs.js b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/prefs.js
index c90e8cd..c90e8cd 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/prefs.js
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/prefs.js
diff --git a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/schemas/org.gnome.shell.extensions.middleclickclose.gschema.xml b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/schemas/org.gnome.shell.extensions.middleclickclose.gschema.xml
index 408a743..408a743 100644
--- a/extensions/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/schemas/org.gnome.shell.extensions.middleclickclose.gschema.xml
+++ b/extensions/44/middleclickclose/middleclickclose@paolo.tranquilli.gmail.com/schemas/org.gnome.shell.extensions.middleclickclose.gschema.xml
diff --git a/extensions/middleclickclose/tweak-tool-screenshot.png b/extensions/44/middleclickclose/tweak-tool-screenshot.png
index 995ee94..995ee94 100644
--- a/extensions/middleclickclose/tweak-tool-screenshot.png
+++ b/extensions/44/middleclickclose/tweak-tool-screenshot.png
Binary files differ
diff --git a/extensions/multi-monitors-add-on.mk b/extensions/44/multi-monitors-add-on.mk
index e3658ff..e3658ff 100644
--- a/extensions/multi-monitors-add-on.mk
+++ b/extensions/44/multi-monitors-add-on.mk
diff --git a/extensions/multi-monitors-add-on/.project b/extensions/44/multi-monitors-add-on/.project
index 58f94f4..58f94f4 100644
--- a/extensions/multi-monitors-add-on/.project
+++ b/extensions/44/multi-monitors-add-on/.project
diff --git a/extensions/multi-monitors-add-on/LICENSE b/extensions/44/multi-monitors-add-on/LICENSE
index d6a9326..d6a9326 100644
--- a/extensions/multi-monitors-add-on/LICENSE
+++ b/extensions/44/multi-monitors-add-on/LICENSE
diff --git a/extensions/multi-monitors-add-on/README.md b/extensions/44/multi-monitors-add-on/README.md
index 4aaa45a..4aaa45a 100644
--- a/extensions/multi-monitors-add-on/README.md
+++ b/extensions/44/multi-monitors-add-on/README.md
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/convenience.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/convenience.js
index bbc8608..bbc8608 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/convenience.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/convenience.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js
index 0a3dce7..0a3dce7 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/extension.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-l-symbolic.svg b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-l-symbolic.svg
index 6341c21..6341c21 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-l-symbolic.svg
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-l-symbolic.svg
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-r-symbolic.svg b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-r-symbolic.svg
index 6bf4651..6bf4651 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-r-symbolic.svg
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/icons/multi-monitors-r-symbolic.svg
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/indicator.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/indicator.js
index 8b500ee..8b500ee 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/indicator.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/indicator.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.mo b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.mo
index ce5795c..ce5795c 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.mo
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.mo
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.po b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.po
index 0691ac2..0691ac2 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.po
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/de/LC_MESSAGES/multi-monitors-add-on.po
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.mo b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.mo
index 0cd6a92..0cd6a92 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.mo
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.mo
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.po b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.po
index 6c51dca..6c51dca 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.po
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/es/LC_MESSAGES/multi-monitors-add-on.po
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.mo b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.mo
index 2aefbb2..2aefbb2 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.mo
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.mo
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.po b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.po
index 3b207cc..3b207cc 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.po
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/fr/LC_MESSAGES/multi-monitors-add-on.po
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.mo b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.mo
index 14040b3..14040b3 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.mo
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.mo
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.po b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.po
index fd41a90..fd41a90 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.po
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/it/LC_MESSAGES/multi-monitors-add-on.po
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.mo b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.mo
index 84f0f8e..84f0f8e 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.mo
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.mo
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.po b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.po
index 80116d8..80116d8 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.po
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pl/LC_MESSAGES/multi-monitors-add-on.po
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.mo b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.mo
index beae2e9..beae2e9 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.mo
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.mo
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.po b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.po
index 94c370c..94c370c 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.po
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/locale/pt_BR/LC_MESSAGES/multi-monitors-add-on.po
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/metadata.json b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/metadata.json
index 35ea54b..35ea54b 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/metadata.json
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/metadata.json
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmcalendar.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmcalendar.js
index 66237f4..66237f4 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmcalendar.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmcalendar.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmlayout.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmlayout.js
index a354ec1..a354ec1 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmlayout.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmlayout.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmoverview.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmoverview.js
index b7555d2..b7555d2 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmoverview.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmoverview.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmpanel.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmpanel.js
index a381f15..a381f15 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/mmpanel.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/mmpanel.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/multi-monitors-add-on.pot b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/multi-monitors-add-on.pot
index 6b18906..6b18906 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/multi-monitors-add-on.pot
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/multi-monitors-add-on.pot
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/prefs.js b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/prefs.js
index d1ba7ea..d1ba7ea 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/prefs.js
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/prefs.js
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/gschemas.compiled b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/gschemas.compiled
index 5a9e945..5a9e945 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/gschemas.compiled
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/gschemas.compiled
Binary files differ
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/org.gnome.shell.extensions.multi-monitors-add-on.gschema.xml b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/org.gnome.shell.extensions.multi-monitors-add-on.gschema.xml
index 4a42a23..4a42a23 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/org.gnome.shell.extensions.multi-monitors-add-on.gschema.xml
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/schemas/org.gnome.shell.extensions.multi-monitors-add-on.gschema.xml
diff --git a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/stylesheet.css b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/stylesheet.css
index b1d20c5..b1d20c5 100644
--- a/extensions/multi-monitors-add-on/multi-monitors-add-on@spin83/stylesheet.css
+++ b/extensions/44/multi-monitors-add-on/multi-monitors-add-on@spin83/stylesheet.css
diff --git a/extensions/no-overview.mk b/extensions/44/no-overview.mk
index f59ce6f..f59ce6f 100644
--- a/extensions/no-overview.mk
+++ b/extensions/44/no-overview.mk
diff --git a/extensions/no-overview/LICENSE b/extensions/44/no-overview/LICENSE
index f288702..f288702 100644
--- a/extensions/no-overview/LICENSE
+++ b/extensions/44/no-overview/LICENSE
diff --git a/extensions/no-overview/README.md b/extensions/44/no-overview/README.md
index 25fb2aa..25fb2aa 100644
--- a/extensions/no-overview/README.md
+++ b/extensions/44/no-overview/README.md
diff --git a/extensions/no-overview/extension.js b/extensions/44/no-overview/extension.js
index 32a9090..32a9090 100644
--- a/extensions/no-overview/extension.js
+++ b/extensions/44/no-overview/extension.js
diff --git a/extensions/44/no-overview/metadata.json b/extensions/44/no-overview/metadata.json
new file mode 100644
index 0000000..6d158a3
--- /dev/null
+++ b/extensions/44/no-overview/metadata.json
@@ -0,0 +1,18 @@
+{
+ "_generated": "Generated by SweetTooth, do not edit",
+ "description": "No overview at start-up. For GNOME Shell 40+.",
+ "name": "No overview at start-up",
+ "original-authors": [
+ "fthx"
+ ],
+ "shell-version": [
+ "40",
+ "41",
+ "42",
+ "43",
+ "44"
+ ],
+ "url": "https://github.com/fthx/no-overview",
+ "uuid": "no-overview@fthx",
+ "version": 13
+}
diff --git a/extensions/vertical-workspaces.mk b/extensions/44/vertical-workspaces.mk
index 3dd5bd0..3dd5bd0 100644
--- a/extensions/vertical-workspaces.mk
+++ b/extensions/44/vertical-workspaces.mk
diff --git a/extensions/vertical-workspaces/.github/ISSUE_TEMPLATE/bug_report.md b/extensions/44/vertical-workspaces/.github/ISSUE_TEMPLATE/bug_report.md
index 74daf6a..74daf6a 100644
--- a/extensions/vertical-workspaces/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/extensions/44/vertical-workspaces/.github/ISSUE_TEMPLATE/bug_report.md
diff --git a/extensions/vertical-workspaces/.github/ISSUE_TEMPLATE/feature_request.md b/extensions/44/vertical-workspaces/.github/ISSUE_TEMPLATE/feature_request.md
index f455865..f455865 100644
--- a/extensions/vertical-workspaces/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/extensions/44/vertical-workspaces/.github/ISSUE_TEMPLATE/feature_request.md
diff --git a/extensions/vertical-workspaces/CHANGELOG.md b/extensions/44/vertical-workspaces/CHANGELOG.md
index 0beb20c..e8fd632 100644
--- a/extensions/vertical-workspaces/CHANGELOG.md
+++ b/extensions/44/vertical-workspaces/CHANGELOG.md
@@ -1,4 +1,100 @@
## Changelog:
+### v45.2 for GNOME 45.2+, v44.10 for GNOME 42-44 (2023-12-02)
+**Added:**
+- *Dash* option *Isolate Workspaces* on *Behavior* tab
+- *Brightness for Search View* option allows adjusting background wallpaper brightness in overview search view
+- *Extensions Search Provider* module allows to search for extensions from the overview, open their settings and enable or disable them
+
+
+### v45.1 for GNOME 45.1+ (EGO 2023-11-25) v44.9 for GNOME 42-44 (not released)
+**Added:**
+- *Window Thumbnail - PIP* option in app icon menu and as an click actions for Window Preview
+- Workspace switcher options *Wraparound* and *Ignore Last (empty)*
+- *Overlay key (Super)* and *Hot Corner* actions offer different overview modes independent on global *Overview Mode*
+- Workspace thumbnails background without wallpaper is now semi-transparent to match other overview elements
+- App Grid sorting options allow alphabetical order with folders
+
+**Fixed:**
+- App grid has less rows than it should
+- Many minor fixes that reflect gnome-shell development and backports
+- Centered app folder position on multi-monitor system
+- Window can't be activated using touchscreen
+- Setting background wallpaper too early on startup can crash Wayland session
+
+**Other changes:**
+- Since GNOME 45 V-Shell has 2 versions - one for GS 45 and the second for GS 42-44. Versioning no longer depends on EGO's upload counter
+- Dash light style background opacity is not limited
+- Refactored Recent Files Search Provider and other modules
+- Settings window - ComboBox replaced with (finally fixed) DropDown
+
+
+### v37 (2023-07-01)
+**Fixed:**
+- False detections of conflicting extensions
+
+
+### v36 (2023-07-01) (35/34/33/32/31 skipped due to issues with extensions.gnome.org)
+**Added:**
+- Option *Fix New Windows Not In Focus* on *Misc* tab
+
+**Fixed:**
+- Improved compatibility with Dash to Dock extension - hidden dock in the overview, broken layout after startup
+- Compatibility with Hide Top Bar extension
+- App search provider ignores non-localized app names
+- App folders grid dimensions wrong if set to *Adaptive* and folder icon is set to a fixed size
+- Dash and active app folder icons running indicator position
+- Blur/Brightness transitions in static overview mode
+- Hot corner edge barrier can be active even if hot corner is disabled
+- Disabling dash module does not reset dash position to default
+
+**Other changes:**
+- Removed css class reducing Quick Settings buttons height in GNOME 44
+
+
+### v30 (2023-06-09)
+**Added:**
+- Dash option - Click Behavior: *Prefer Current Workspace* - opens a new window if app not present on the active workspace
+- Window search provider sorting options
+- Esc key behavior options
+- Window preview - middle and secondary mouse button behavior options, close button can be hidden
+- GNOME 3 vertical dash style is now optional
+- Window preview title position option
+- Light dash background option
+- Remove app folder button in folder dialog
+- *Updating V-Shell* banner appears during updating V-Shell settings when settings window is irresponsive
+- Dutch translation by @Vistaus
+
+**Fixed:**
+- Dash icon scroll action conflicts with Dash to Dock
+- Open new window by middle click on app icon or Ctrl+Enter doesn't work
+- Dash icon label can extend to the adjacent display
+- WindowPreview module not updated when "always-activate-selected-window" changed
+- App folder dialog position if secondary monitor connected
+- App folder dialog sizing and positioning
+- Background brightness in search view reduced independently to avoid unreadable text and consistent style
+- Compatibility with Burn My Windows - freeze after screen unlocked, or extensions re-enabled
+- Window and Recent files search providers modes not isolated well from results of other providers
+- Recent file search provider results sorting
+- App grid icons with multi-line label move on hover when label expands
+- Search view animation skipped id triggered from app grid state
+- DING desktop icons not visible during static background workspace animation
+
+
+**Other changes:**
+- Added `unlock-dialog` session mode to avoid unnecessary system load when using screen lock
+- App Grid refactored, added transparent app folder dialogs on clean background
+- Search view transparency and fixed background brightness in classic overview
+- Search view in static workspace overview with full opacity and close to default style
+- Settings window - Profiles tab moved at first position, Dash icons position options moved back to layout
+- Updated default profiles
+
+
+### v29 (2023-04-11)
+**Fixed:**
+- Window switcher/highlighter logic when scrolling over an dash icon
+- Unhandled promise rejection warnings on GS 43+
+
+
### v28 (2023-04-06)
**Added:**
- App Grid - vertical app folder orientation
diff --git a/extensions/vertical-workspaces/LICENSE b/extensions/44/vertical-workspaces/LICENSE
index f288702..f288702 100644
--- a/extensions/vertical-workspaces/LICENSE
+++ b/extensions/44/vertical-workspaces/LICENSE
diff --git a/extensions/vertical-workspaces/Makefile b/extensions/44/vertical-workspaces/Makefile
index b0afba4..b0afba4 100644
--- a/extensions/vertical-workspaces/Makefile
+++ b/extensions/44/vertical-workspaces/Makefile
diff --git a/extensions/vertical-workspaces/README.md b/extensions/44/vertical-workspaces/README.md
index ebff9df..449bafa 100644
--- a/extensions/vertical-workspaces/README.md
+++ b/extensions/44/vertical-workspaces/README.md
@@ -2,7 +2,7 @@
A GNOME Shell extension that lets you customize your GNOME Shell UX to suit your workflow, whether you like horizontally or vertically stacked workspaces.
-Currently supported GNOME versions: 42, 43, 44
+Currently supported GNOME versions: 42 - 45
[<img alt="" height="100" src="https://raw.githubusercontent.com/andyholmes/gnome-shell-extensions-badge/master/get-it-on-ego.svg?sanitize=true">](https://extensions.gnome.org/extension/5177/vertical-workspaces/)
@@ -17,6 +17,7 @@ Currently supported GNOME versions: 42, 43, 44
- Support for secondary monitors, workspace thumbnails can be placed on the opposite side than on the primary monitor
- Wallpaper background with adjustable blur effect and brightness in the overview
- Custom Dash icon size and on-click/scroll behavior
+- Optional workspace isolated Dash
- Dash background transparency and corner radius adjustments
- Adjustable app grid icon size, number of columns and rows, content, optional active and draggable icons in folder preview in optional 3x3 grid
- Custom search view width, app results icons size and number of result lists rows, improved app search
@@ -26,12 +27,14 @@ Currently supported GNOME versions: 42, 43, 44
- Control over transition animations, including speed
- Window search provider with *Space* hotkey allows quick window navigation
- Recent files search provider with *Ctrl + Space* hotkey
+- Extensions search provider with *Ctrl + Shift + Space* hotkey allows to search for extensions, open their settings and enable or disable them
- Reorder workspaces in overview using *Shift + Scroll* or *Shift + Page Up/Down*
- Adds *Force Quit*, *Close Windows on Current Workspace* and *Move Windows to Current Workspace* items to app icon menu. The latter action can be activated using *Shift + click* on app icon
- Change notification banners and OSD popups position
- Window attention handler options can activate the attention-demanding window immediately or silence its notification
- Optional position of the hot corner that can follow the dash and expand to hot edge
- Super key double-press options
+- Window thumbnail (PIP) options allows you to create scaled down clone of the window by clicking on its preview in the overview (secondary mouse buttons or window preview icon)
## Changelog
[CHANGELOG.md](CHANGELOG.md)
@@ -51,12 +54,21 @@ Install the extension (`--force` switch needs to be used only if some version of
gnome-extensions install --force vertical-workspaces@G-dH.github.com.zip
### Installation from GitHub repository
-The most recent version in the repository is the one I'm currently using and developing on my own systems, problems may occur, but usually nothing serious. The repository version may change often and doesn't updates automatically on your system, but once the stable release shows up on extensions.gnome.org, it should be updated automatically from there. If you want to help me, use this latest version and report bugs.
-You may need to install `git`, `gettext` and `glib2.0` for successful installation.
+The most recent version in the repository is the one I'm currently using and developing on my own systems, problems may occur, but usually nothing serious. The repository version may change often and doesn't updates automatically on your system. If you want to help me, use this latest version and report bugs.
+You may need to install `git`, `make`, `gettext` and `glib2.0` for successful installation.
Navigate to the directory you want to download the source code and execute following commands in the terminal:
+GNOME 45:
+
+ git clone https://github.com/G-dH/vertical-workspaces.git
+ cd vertical-workspaces
+ make install
+
+GNOME 42 - 44:
+
git clone https://github.com/G-dH/vertical-workspaces.git
cd vertical-workspaces
+ git checkout gnome-42-44
make install
If you get `Can't recursively copy directory` error, take a look at issue #51.
diff --git a/extensions/44/vertical-workspaces/extension.js b/extensions/44/vertical-workspaces/extension.js
new file mode 100644
index 0000000..911d7dd
--- /dev/null
+++ b/extensions/44/vertical-workspaces/extension.js
@@ -0,0 +1,793 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * extension.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Meta = imports.gi.Meta;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+const Search = imports.ui.search;
+const Workspace = imports.ui.workspace;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const MyExtension = ExtensionUtils.getCurrentExtension();
+
+let Me;
+// gettext
+let _;
+let opt;
+
+function init() {
+ ExtensionUtils.initTranslations();
+ return new Extension();
+}
+
+class Extension {
+ _init() {
+ Me = {};
+
+ Me.shellVersion = parseFloat(imports.misc.config.PACKAGE_VERSION);
+ Me.imports = MyExtension.imports;
+ Me.metadata = MyExtension.metadata;
+ Me.gSettings = ExtensionUtils.getSettings(Me.metadata['settings-schema']);
+ Me.Settings = MyExtension.imports.lib.settings;
+ Me.gettext = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
+ Me.Util = MyExtension.imports.lib.util;
+
+ Me.Modules = this._importModules();
+ Me.moduleList = this._getModuleList();
+
+ Me.WSP_PREFIX = Me.Modules.windowSearchProviderModule._PREFIX;
+ Me.RFSP_PREFIX = Me.Modules.recentFilesSearchProviderModule._PREFIX;
+ Me.ESP_PREFIX = Me.Modules.extensionsSearchProviderModule._PREFIX;
+
+ Me.opt = new Me.Settings.Options(Me);
+ _ = Me.gettext;
+ opt = Me.opt;
+
+ Me.Util.init(Me);
+
+ Me.moduleList.forEach(module => {
+ Me.Modules[module] = new Me.Modules[module](Me);
+ });
+
+ Me.repairOverrides = this._repairOverrides;
+ }
+
+ _importModules() {
+ return {
+ appDisplayModule: Me.imports.lib.appDisplay.AppDisplayModule,
+ appFavoritesModule: Me.imports.lib.appFavorites.AppFavoritesModule,
+ dashModule: Me.imports.lib.dash.DashModule,
+ iconGridModule: Me.imports.lib.iconGrid.IconGridModule,
+ layoutModule: Me.imports.lib.layout.LayoutModule,
+ messageTrayModule: Me.imports.lib.messageTray.MessageTrayModule,
+ osdWindowModule: Me.imports.lib.osdWindow.OsdWindowModule,
+ overviewModule: Me.imports.lib.overview.OverviewModule,
+ overlayKeyModule: Me.imports.lib.overlayKey.OverlayKeyModule,
+ overviewControlsModule: Me.imports.lib.overviewControls.OverviewControlsModule,
+ panelModule: Me.imports.lib.panel.PanelModule,
+ searchModule: Me.imports.lib.search.SearchModule,
+ searchControllerModule: Me.imports.lib.searchController.SearchControllerModule,
+ swipeTrackerModule: Me.imports.lib.swipeTracker.SwipeTrackerModule,
+ windowAttentionHandlerModule: Me.imports.lib.windowAttentionHandler.WindowAttentionHandlerModule,
+ windowManagerModule: Me.imports.lib.windowManager.WindowManagerModule,
+ windowPreviewModule: Me.imports.lib.windowPreview.WindowPreviewModule,
+ workspaceAnimationModule: Me.imports.lib.workspaceAnimation.WorkspaceAnimationModule,
+ workspaceModule: Me.imports.lib.workspace.WorkspaceModule,
+ workspaceSwitcherPopupModule: Me.imports.lib.workspaceSwitcherPopup.WorkspaceSwitcherPopupModule,
+ workspaceThumbnailModule: Me.imports.lib.workspaceThumbnail.WorkspaceThumbnailModule,
+ workspacesViewModule: Me.imports.lib.workspacesView.WorkspacesViewModule,
+ windowSearchProviderModule: Me.imports.lib.windowSearchProvider.WindowSearchProviderModule,
+ winTmbModule: Me.imports.lib.winTmb.WinTmbModule,
+ recentFilesSearchProviderModule: Me.imports.lib.recentFilesSearchProvider.RecentFilesSearchProviderModule,
+ extensionsSearchProviderModule: Me.imports.lib.extensionsSearchProvider.ExtensionsSearchProviderModule,
+ };
+ }
+
+ _getModuleList() {
+ return Object.keys(Me.Modules);
+ }
+
+ _cleanGlobals() {
+ Me = null;
+ opt = null;
+ _ = null;
+ }
+
+ enable() {
+ this._init();
+ // flag for Util.getEnabledExtensions()
+ Me.extensionsLoadIncomplete = Main.layoutManager._startingUp;
+
+ this._activateVShell();
+ Me.extensionsLoadIncomplete = false;
+ console.debug(`${Me.metadata.name}: enabled`);
+ }
+
+ // Reason for using "unlock-dialog" session mode:
+ // Updating the "appDisplay" content every time the screen is locked/unlocked takes quite a lot of time and affects the user experience.
+ disable() {
+ this._removeVShell();
+ this._disposeModules();
+
+ // If Dash to Dock is enabled, disabling V-Shell can end in broken overview
+ Main.overview.hide();
+
+ console.debug(`${Me.metadata.name}: disabled`);
+
+ this._cleanGlobals();
+ }
+
+ _disposeModules() {
+ Me.opt.destroy();
+ Me.opt = null;
+
+ for (let module of Me.moduleList) {
+ if (!Me.Modules[module].moduleEnabled)
+ Me.Modules[module].cleanGlobals();
+ }
+
+ Me.Util.cleanGlobals();
+ Me.Modules = null;
+ }
+
+ _activateVShell() {
+ this._enabled = true;
+
+ this._originalGetNeighbor = Meta.Workspace.prototype.get_neighbor;
+
+ this._removeTimeouts();
+ this._timeouts = {};
+
+ // load VShell configuration
+ this._updateSettings();
+
+ // activate all enabled VShell modules
+ this._updateOverrides();
+
+ // connect signals to help VShell adapt to changes in DE configuration
+ this._updateConnections();
+
+ // switch PageUp/PageDown workspace switcher shortcuts
+ this._switchPageShortcuts();
+
+ // if Dash to Dock detected force enable "Fix for DtD" option
+ this._updateFixDashToDockOption();
+
+ // update overview background wallpaper if enabled, but don't set it too early on session startup
+ // because it crashes wayland
+ if (!Main.layoutManager._startingUp || Meta.is_restart())
+ Main.overview._overview.controls._setBackground();
+
+ this._updateSettingsConnection();
+
+ // store dash _workId so we will be able to detect replacement when entering overview
+ this._storeDashId();
+
+ // workaround for upstream bug - overview always shows workspace 1 instead of the active one after restart
+ this._setInitialWsIndex();
+ }
+
+ _removeVShell() {
+ this._enabled = false;
+
+ const reset = true;
+ this._removeTimeouts();
+
+ this._removeConnections();
+ Main.overview._overview.controls._setBackground(reset);
+
+ // remove changes mede by VShell modules
+ this._updateOverrides(reset);
+
+ // switch PageUp/PageDown workspace switcher shortcuts
+ this._switchPageShortcuts();
+
+ // remove any position offsets from dash and ws thumbnails
+ if (!Me.Util.dashNotDefault()) {
+ Main.overview.dash.translation_x = 0;
+ Main.overview.dash.translation_y = 0;
+ }
+ Main.overview._overview._controls._thumbnailsBox.translation_x = 0;
+ Main.overview._overview._controls._thumbnailsBox.translation_y = 0;
+ Main.overview._overview._controls._searchEntryBin.translation_y = 0;
+ Main.overview._overview._controls.set_child_above_sibling(Main.overview._overview._controls._workspacesDisplay, null);
+ // restore default animation speed
+ St.Settings.get().slow_down_factor = 1;
+
+ // restore default dash background style
+ Main.overview.dash._background.set_style('');
+ // hide status message if shown
+ this._showStatusMessage(false);
+ this._prevDash = null;
+
+ Meta.Workspace.prototype.get_neighbor = this._originalGetNeighbor;
+ }
+
+ _removeTimeouts() {
+ if (this._timeouts) {
+ Object.values(this._timeouts).forEach(id => {
+ if (id)
+ GLib.source_remove(id);
+ });
+ }
+ this._timeouts = null;
+ }
+
+ _storeDashId() {
+ const dash = Main.overview.dash;
+ this._prevDash = dash._workId;
+ }
+
+ _setInitialWsIndex() {
+ if (Main.layoutManager._startingUp) {
+ GLib.idle_add(GLib.PRIORITY_LOW, () => {
+ Main.overview._overview.controls._workspaceAdjustment.set_value(global.workspace_manager.get_active_workspace_index());
+ });
+ }
+ }
+
+ _updateSettingsConnection() {
+ if (!opt._extensionUpdateId)
+ opt._extensionUpdateId = opt.connect('changed', this._updateSettings.bind(this));
+ }
+
+ _updateFixDashToDockOption() {
+ const dtdEnabled = !!(Me.Util.getEnabledExtensions('dash-to-dock').length ||
+ Me.Util.getEnabledExtensions('ubuntu-dock').length);
+
+ // force enable Fix Dash to Dock option if DtD detected
+ opt._watchDashToDock = dtdEnabled;
+ // opt.set('fixUbuntuDock', dtdEnabled);
+ }
+
+ _updateConnections() {
+ if (!this._monitorsChangedConId)
+ this._monitorsChangedConId = Main.layoutManager.connect('monitors-changed', () => this._updateVShell(2000));
+
+
+ if (!this._showingOverviewConId)
+ this._showingOverviewConId = Main.overview.connect('showing', this._onShowingOverview.bind(this));
+
+ if (!this._sessionModeConId) {
+ // the panel must be visible when screen is locked
+ this._sessionModeConId = Main.sessionMode.connect('updated', session => {
+ if (session.currentMode === 'user' || session.parentMode === 'user') {
+ this._timeouts.unlock = GLib.idle_add(GLib.PRIORITY_LOW,
+ () => {
+ Me.Modules.panelModule.update();
+ Me.Modules.overviewControlsModule.update();
+ Me.Modules.winTmbModule.showThumbnails();
+
+ this._timeouts.unlock = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ } else if (session.currentMode === 'unlock-dialog') {
+ Me.Modules.panelModule.update(true);
+ Me.Modules.winTmbModule.hideThumbnails();
+ }
+ });
+ }
+
+ if (!this._watchDockSigId) {
+ this._watchDockSigId = Main.extensionManager.connect('extension-state-changed',
+ (source, extension) => {
+ const uuid = extension.uuid;
+ // ExtensionState = {
+ // ENABLED: 1,
+ // DISABLED: 2,
+ // ERROR: 3,
+ // OUT_OF_DATE: 4,
+ // DOWNLOADING: 5,
+ // INITIALIZED: 6,
+ // DISABLING: 7,
+ // ENABLING: 8,
+ //
+ // // Used as an error state for operations on unknown extensions,
+ // // should never be in a real extensionMeta object.
+ // UNINSTALLED: 99,
+ // };
+ // no need to restart on disable/remove
+ // - if DtD was enabled before VShell, VShell will be rebased by extensionSystem
+ // - if DtD was enabled after VShell, the first _showingOverview detect replacement of the dash and repair VShell
+ const reset = [1, 2].includes(extension.state);
+ const dashReplacement = uuid.includes('dash-to-dock') || uuid.includes('ubuntu-dock') || uuid.includes('dash-to-panel');
+ if (dashReplacement && reset)
+ opt._watchDashToDock = true;
+ if (!Main.layoutManager._startingUp && reset && dashReplacement)
+ this._updateVShell(1999);
+ }
+ );
+ }
+ }
+
+ _removeConnections() {
+ if (this._monitorsChangedConId) {
+ Main.layoutManager.disconnect(this._monitorsChangedConId);
+ this._monitorsChangedConId = 0;
+ }
+
+ if (this._showingOverviewConId) {
+ Main.overview.disconnect(this._showingOverviewConId);
+ this._showingOverviewConId = 0;
+ }
+
+ if (this._sessionModeConId) {
+ Main.sessionMode.disconnect(this._sessionModeConId);
+ this._sessionModeConId = 0;
+ }
+
+ if (this._watchDockSigId) {
+ Main.extensionManager.disconnect(this._watchDockSigId);
+ this._watchDockSigId = 0;
+ }
+ }
+
+ _updateOverrides(reset = false) {
+ Me.Modules.workspacesViewModule.update(reset);
+ Me.Modules.workspaceThumbnailModule.update(reset);
+ Me.Modules.overviewModule.update(reset);
+ Me.Modules.overviewControlsModule.update(reset);
+
+ Me.Modules.workspaceModule.update(reset);
+ Me.Modules.windowPreviewModule.update(reset);
+ Me.Modules.windowManagerModule.update(reset);
+
+ Me.Modules.layoutModule.update(reset);
+ Me.Modules.dashModule.update(reset);
+ // avoid enabling panel module when session is locked
+ if (reset || (!reset && !Main.sessionMode.isLocked))
+ Me.Modules.panelModule.update(reset);
+ // the panel must be visible when screen is locked
+ // at startup time, panel will be updated from the startupAnimation after allocation
+ if (!reset && Main.sessionMode.isLocked && !Main.layoutManager._startingUp)
+ Me.Modules.panelModule._showPanel(true);
+ // PanelModule._showPanel(true);
+ // hide panel so it appears directly on the final place
+ /* else if (Main.layoutManager._startingUp && !Meta.is_restart())
+ Main.panel.opacity = 0;*/
+
+ Me.Modules.workspaceAnimationModule.update(reset);
+ Me.Modules.workspaceSwitcherPopupModule.update(reset);
+
+ Me.Modules.swipeTrackerModule.update(reset);
+
+ Me.Modules.searchModule.update(reset);
+
+ Me.Modules.windowSearchProviderModule.update(reset);
+ Me.Modules.recentFilesSearchProviderModule.update(reset);
+ Me.Modules.extensionsSearchProviderModule.update(reset);
+
+ // don't rebuild app grid on any screen lock
+ // even if the extension includes unlock-screen session mode
+ // disable/enable is called at least once even on GS44
+ // when screen lock is activated for the first time
+ // because every first disable of each extension rebases
+ // the entire extensions stack that was enabled later
+ if (Main.sessionMode.isLocked)
+ this._sessionLockActive = true;
+
+ // This covers unnecessary enable/disable cycles during first screen lock when extensions are rebased, but is not allowed by the EGO rules
+ if (!this._sessionLockActive || !Main.extensionManager._getEnabledExtensions().includes(Me.metadata.uuid)) {
+ // iconGridModule will be updated from appDisplayModule
+ Me.Modules.appDisplayModule.update(reset);
+ }
+
+ if (!this._sessionLockActive && !Main.layoutManager._startingUp && opt.APP_GRID_PERFORMANCE) {
+ // Avoid showing status at startup, can cause freeze
+ this._showStatusMessage();
+ }
+
+ if (!Main.sessionMode.isLocked)
+ this._sessionLockActive = false;
+
+ // iconGridModule will be updated from appDisplayModule
+ // Me.Modules.appDisplayModule.update(reset);
+
+ Me.Modules.windowAttentionHandlerModule.update(reset);
+ Me.Modules.appFavoritesModule.update(reset);
+ Me.Modules.messageTrayModule.update(reset);
+ Me.Modules.osdWindowModule.update(reset);
+ Me.Modules.overlayKeyModule.update(reset);
+ Me.Modules.searchControllerModule.update(reset);
+ Me.Modules.winTmbModule.update(reset);
+
+ if (!reset && !Main.layoutManager._startingUp)
+ Main.overview._overview.controls.setInitialTranslations();
+ }
+
+ _onShowingOverview() {
+ if (Main.layoutManager._startingUp)
+ return;
+
+ Main.overview._overview.controls.opacity = 255;
+
+ // store pointer X coordinate for OVERVIEW_MODE 1 window spread - if mouse pointer is steady, don't spread
+ opt.showingPointerX = global.get_pointer()[0];
+
+ if (!Main.overview._overview.controls._bgManagers && (opt.SHOW_BG_IN_OVERVIEW || opt.SHOW_WS_PREVIEW_BG))
+ Main.overview._overview.controls._setBackground();
+
+ if (opt._watchDashToDock) {
+ // workaround for Dash to Dock (Ubuntu Dock) breaking overview allocations after enabled and changed position
+ // DtD replaces dock and its _workId on every position change
+ const dash = Main.overview.dash;
+ if (this._prevDash !== dash._workId)
+ this._updateVShell(0);
+ }
+ }
+
+ _updateVShell(timeout = 200) {
+ if (!this._enabled || Main.layoutManager._startingUp)
+ return;
+
+ if (this._timeouts.reset)
+ GLib.source_remove(this._timeouts.reset);
+ this._timeouts.reset = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT,
+ timeout,
+ () => {
+ if (!this._enabled)
+ return GLib.SOURCE_REMOVE;
+
+ const dash = Main.overview.dash;
+ if (timeout < 2000) { // timeout < 2000 for partial update
+ this._prevDash = dash._workId;
+ console.warn(`[${Me.metadata.name}]: Dash has been replaced, updating extension ...`);
+ Me._resetInProgress = true;
+ // update only necessary modules if dash has been replaced
+ this._repairOverrides();
+ Me._resetInProgress = false;
+ } else {
+ console.warn(`[${Me.metadata.name}]: Updating extension ...`);
+ // for case the monitor configuration has been changed, update all
+ Me._resetInProgress = true;
+ this._activateVShell();
+ Me._resetInProgress = false;
+ }
+ this._timeouts.reset = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ }
+
+ // the key modules that can be affected by the supported incompatible extensions
+ _repairOverrides() {
+ Me.Modules.overviewModule.update();
+ Me.Modules.overviewControlsModule.update();
+ Me.Modules.workspacesViewModule.update();
+ Me.Modules.windowPreviewModule.update();
+ Me.Modules.panelModule.update();
+ Me.Modules.dashModule.update();
+ }
+
+ _updateSettings(settings, key) {
+ // update settings cache and option variables
+ opt._updateSettings();
+
+ // avoid overload while loading profile - update only once
+ // delayed gsettings writes are processed alphabetically
+ if (key === 'aaa-loading-profile') {
+ this._showStatusMessage();
+ if (this._timeouts.loadingProfile)
+ GLib.source_remove(this._timeouts.loadingProfile);
+ this._timeouts.loadingProfile = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT,
+ 100, () => {
+ this._activateVShell();
+ this._timeouts.loadingProfile = 0;
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+ if (this._timeouts.loadingProfile)
+ return;
+
+ if (key?.includes('profile-data')) {
+ const index = key.replace('profile-data-', '');
+ Main.notify(`${Me.metadata.name}`, `Profile ${index} has been updated`);
+ }
+
+ opt.WORKSPACE_MIN_SPACING = Main.overview._overview._controls._thumbnailsBox.get_theme_node().get_length('spacing');
+ // update variables that cannot be processed within settings
+ const dash = Main.overview.dash;
+ if (Me.Util.dashIsDashToDock()) {
+ opt.DASH_POSITION = dash._position;
+ opt.DASH_TOP = opt.DASH_POSITION === 0;
+ opt.DASH_RIGHT = opt.DASH_POSITION === 1;
+ opt.DASH_BOTTOM = opt.DASH_POSITION === 2;
+ opt.DASH_LEFT = opt.DASH_POSITION === 3;
+ opt.DASH_VERTICAL = opt.DASH_LEFT || opt.DASH_RIGHT;
+ }
+
+ opt.DASH_VISIBLE = opt.DASH_VISIBLE && !Me.Util.getEnabledExtensions('dash-to-panel@jderose9.github.com').length;
+
+ const monitorWidth = global.display.get_monitor_geometry(global.display.get_primary_monitor()).width;
+ if (monitorWidth < 1600) {
+ opt.APP_GRID_ICON_SIZE_DEFAULT = opt.APP_GRID_ACTIVE_PREVIEW && !opt.APP_GRID_USAGE ? 128 : 64;
+ opt.APP_GRID_FOLDER_ICON_SIZE_DEFAULT = 64;
+ }
+
+ Workspace.WINDOW_PREVIEW_MAXIMUM_SCALE = opt.OVERVIEW_MODE === 1 ? 0.1 : 0.95;
+
+ // adjust search entry style for OM2
+ if (opt.OVERVIEW_MODE2)
+ Main.overview.searchEntry.add_style_class_name('search-entry-om2');
+ else
+ Main.overview.searchEntry.remove_style_class_name('search-entry-om2');
+
+ Main.overview.searchEntry.visible = opt.SHOW_SEARCH_ENTRY;
+ Main.overview.searchEntry.opacity = 255;
+ St.Settings.get().slow_down_factor = opt.ANIMATION_TIME_FACTOR;
+ Search.MAX_LIST_SEARCH_RESULTS_ROWS = opt.SEARCH_MAX_ROWS;
+
+ opt.START_Y_OFFSET = (opt.get('panelModule') && opt.PANEL_OVERVIEW_ONLY && opt.PANEL_POSITION_TOP) ||
+ // better to add unnecessary space than to have a panel overlapping other objects
+ Me.Util.getEnabledExtensions('hidetopbar').length
+ ? Main.panel.height
+ : 0;
+
+ // Options for workspace switcher, apply custom function only if needed
+ if (opt.WS_WRAPAROUND || opt.WS_IGNORE_LAST)
+ Meta.Workspace.prototype.get_neighbor = this._getNeighbor;
+ else
+ Meta.Workspace.prototype.get_neighbor = this._originalGetNeighbor;
+
+ if (settings)
+ this._applySettings(key);
+ }
+
+ _applySettings(key) {
+ if (key?.endsWith('-module')) {
+ for (let module of Me.moduleList) {
+ if (opt.options[module] && key === opt.options[module][1]) {
+ if (key === 'app-display-module')
+ this._showStatusMessage();
+ Me.Modules[module].update();
+ break;
+ }
+ }
+ return;
+ }
+
+ Main.overview._overview.controls._setBackground();
+ this._switchPageShortcuts();
+
+ if (key?.includes('panel'))
+ Me.Modules.panelModule.update();
+
+ if (key?.includes('dash') || key?.includes('icon') || key?.includes('dot-style'))
+ Me.Modules.dashModule.update();
+
+ if (key?.includes('hot-corner') || key?.includes('dash'))
+ Me.Modules.layoutModule.update();
+
+ switch (key) {
+ case 'ws-thumbnails-position':
+ this._updateOverrides();
+ break;
+ case 'workspace-switcher-animation':
+ Me.Modules.workspaceAnimationModule.update();
+ break;
+ case 'search-width-scale':
+ Me.Modules.searchModule.update();
+ break;
+ case 'favorites-notify':
+ Me.Modules.appFavoritesModule.update();
+ break;
+ case 'window-attention-mode':
+ Me.Modules.windowAttentionHandlerModule.update();
+ break;
+ case 'show-ws-preview-bg':
+ Me.Modules.panelModule.update();
+ break;
+ case 'notification-position':
+ Me.Modules.messageTrayModule.update();
+ break;
+ case 'osd-position':
+ Me.Modules.osdWindowModule.update();
+ break;
+ case 'overlay-key':
+ Me.Modules.overlayKeyModule.update();
+ break;
+ case 'always-activate-selected-window':
+ Me.Modules.windowPreviewModule.update();
+ break;
+ }
+
+ if (key?.includes('app-grid') ||
+ key?.includes('app-folder') ||
+ key?.includes('dot-style') ||
+ key === 'show-search-entry' ||
+ key === 'ws-thumbnail-scale' ||
+ key === 'ws-thumbnail-scale-appgrid') {
+ this._showStatusMessage();
+ Me.Modules.appDisplayModule.update();
+ }
+ }
+
+ _switchPageShortcuts() {
+ // ignore screen lock
+ if (!opt.get('enablePageShortcuts') || this._sessionLockActive)
+ return;
+
+ const vertical = global.workspaceManager.layout_rows === -1;
+ const schema = 'org.gnome.desktop.wm.keybindings';
+ const settings = new Gio.Settings({ schema_id: schema });
+
+ const keyLeft = 'switch-to-workspace-left';
+ const keyRight = 'switch-to-workspace-right';
+ const keyUp = 'switch-to-workspace-up';
+ const keyDown = 'switch-to-workspace-down';
+
+ const keyMoveLeft = 'move-to-workspace-left';
+ const keyMoveRight = 'move-to-workspace-right';
+ const keyMoveUp = 'move-to-workspace-up';
+ const keyMoveDown = 'move-to-workspace-down';
+
+ const switchPrevSc = '<Super>Page_Up';
+ const switchNextSc = '<Super>Page_Down';
+ const movePrevSc = '<Super><Shift>Page_Up';
+ const moveNextSc = '<Super><Shift>Page_Down';
+
+ let switchLeft = settings.get_strv(keyLeft);
+ let switchRight = settings.get_strv(keyRight);
+ let switchUp = settings.get_strv(keyUp);
+ let switchDown = settings.get_strv(keyDown);
+
+ let moveLeft = settings.get_strv(keyMoveLeft);
+ let moveRight = settings.get_strv(keyMoveRight);
+ let moveUp = settings.get_strv(keyMoveUp);
+ let moveDown = settings.get_strv(keyMoveDown);
+
+ if (vertical) {
+ if (switchLeft.includes(switchPrevSc))
+ switchLeft.splice(switchLeft.indexOf(switchPrevSc), 1);
+ if (switchRight.includes(switchNextSc))
+ switchRight.splice(switchRight.indexOf(switchNextSc), 1);
+ if (moveLeft.includes(movePrevSc))
+ moveLeft.splice(moveLeft.indexOf(movePrevSc), 1);
+ if (moveRight.includes(moveNextSc))
+ moveRight.splice(moveRight.indexOf(moveNextSc), 1);
+
+ if (!switchUp.includes(switchPrevSc))
+ switchUp.push(switchPrevSc);
+ if (!switchDown.includes(switchNextSc))
+ switchDown.push(switchNextSc);
+ if (!moveUp.includes(movePrevSc))
+ moveUp.push(movePrevSc);
+ if (!moveDown.includes(moveNextSc))
+ moveDown.push(moveNextSc);
+ } else {
+ if (!switchLeft.includes(switchPrevSc))
+ switchLeft.push(switchPrevSc);
+ if (!switchRight.includes(switchNextSc))
+ switchRight.push(switchNextSc);
+ if (!moveLeft.includes(movePrevSc))
+ moveLeft.push(movePrevSc);
+ if (!moveRight.includes(moveNextSc))
+ moveRight.push(moveNextSc);
+
+ if (switchUp.includes(switchPrevSc))
+ switchUp.splice(switchUp.indexOf(switchPrevSc), 1);
+ if (switchDown.includes(switchNextSc))
+ switchDown.splice(switchDown.indexOf(switchNextSc), 1);
+ if (moveUp.includes(movePrevSc))
+ moveUp.splice(moveUp.indexOf(movePrevSc), 1);
+ if (moveDown.includes(moveNextSc))
+ moveDown.splice(moveDown.indexOf(moveNextSc), 1);
+ }
+
+ settings.set_strv(keyLeft, switchLeft);
+ settings.set_strv(keyRight, switchRight);
+ settings.set_strv(keyUp, switchUp);
+ settings.set_strv(keyDown, switchDown);
+
+ settings.set_strv(keyMoveLeft, moveLeft);
+ settings.set_strv(keyMoveRight, moveRight);
+ settings.set_strv(keyMoveUp, moveUp);
+ settings.set_strv(keyMoveDown, moveDown);
+ }
+
+ // Status dialog that appears during updating V-Shell configuration and blocks inputs
+ _showStatusMessage(show = true) {
+ if ((show && Me._resetInProgress) || Main.layoutManager._startingUp || !Main.overview._overview.controls._appDisplay._sortOrderedItemsAlphabetically)
+ return;
+
+ if (Me._vShellMessageTimeoutId) {
+ GLib.source_remove(Me._vShellMessageTimeoutId);
+ Me._vShellMessageTimeoutId = 0;
+ }
+
+ if (Me._vShellStatusMessage && !show) {
+ Me._vShellStatusMessage.close();
+ Me._vShellStatusMessage.destroy();
+ Me._vShellStatusMessage = null;
+ }
+
+ if (!show)
+ return;
+
+ if (!Me._vShellStatusMessage) {
+ const sm = new Main.RestartMessage(_('Updating V-Shell...'));
+ sm.set_style('background-color: rgba(0,0,0,0.3);');
+ sm.open();
+ Me._vShellStatusMessage = sm;
+ }
+
+ // just for case the message wasn't removed from appDisplay after App Grid realization
+ Me._vShellMessageTimeoutId = GLib.timeout_add_seconds(
+ GLib.PRIORITY_DEFAULT,
+ 5,
+ () => {
+ if (Me._vShellStatusMessage) {
+ Me._vShellStatusMessage.close();
+ Me._vShellStatusMessage.destroy();
+ Me._vShellStatusMessage = null;
+ Me._resetInProgress = false;
+ }
+
+ Me._vShellMessageTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ }
+
+ _getNeighbor(direction) {
+ // workspace matrix is supported
+ const activeIndex = this.index();
+ const ignoreLast = opt.WS_IGNORE_LAST && !Main.overview._shown ? 1 : 0;
+ const wraparound = opt.WS_WRAPAROUND;
+ const nWorkspaces = global.workspace_manager.n_workspaces;
+ const lastIndex = nWorkspaces - 1 - ignoreLast;
+ const rows = global.workspace_manager.layout_rows > -1 ? global.workspace_manager.layout_rows : nWorkspaces;
+ const columns = global.workspace_manager.layout_columns > -1 ? global.workspace_manager.layout_columns : nWorkspaces;
+
+ let index = activeIndex;
+ let neighborExists;
+
+ if (direction === Meta.MotionDirection.LEFT) {
+ index -= 1;
+ const currentRow = Math.floor(activeIndex / columns);
+ const indexRow = Math.floor(index / columns);
+ neighborExists = index > -1 && indexRow === currentRow;
+ if (wraparound && !neighborExists) {
+ index = currentRow * columns + columns - 1;
+ const maxIndexOnLastRow = lastIndex % columns;
+ index = index < (lastIndex - ignoreLast) ? index : currentRow * columns + maxIndexOnLastRow;
+ }
+ } else if (direction === Meta.MotionDirection.RIGHT) {
+ index += 1;
+ const currentRow = Math.floor(activeIndex / columns);
+ const indexRow = Math.floor(index / columns);
+ neighborExists = index <= lastIndex && indexRow === currentRow;
+ if (wraparound && !neighborExists)
+ index = currentRow * columns;
+ } else if (direction === Meta.MotionDirection.UP) {
+ index -= columns;
+ neighborExists = index > -1;
+ if (wraparound && !neighborExists) {
+ index = rows * columns + index;
+ index = index < nWorkspaces - ignoreLast ? index : index - columns;
+ }
+ } else if (direction === Meta.MotionDirection.DOWN) {
+ index += columns;
+ neighborExists = index <= lastIndex;
+ if (wraparound && !neighborExists)
+ index %= columns;
+ }
+
+ return global.workspace_manager.get_workspace_by_index(neighborExists || wraparound ? index : activeIndex);
+ }
+}
diff --git a/extensions/vertical-workspaces/lib/appDisplay.js b/extensions/44/vertical-workspaces/lib/appDisplay.js
index 2ac70b1..aeb2808 100644
--- a/extensions/vertical-workspaces/lib/appDisplay.js
+++ b/extensions/44/vertical-workspaces/lib/appDisplay.js
@@ -10,246 +10,501 @@
'use strict';
-const { Clutter, GLib, GObject, Meta, Shell, St, Graphene, Pango } = imports.gi;
+const Clutter = imports.gi.Clutter;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Graphene = imports.gi.Graphene;
+const Meta = imports.gi.Meta;
+const Pango = imports.gi.Pango;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
-const DND = imports.ui.dnd;
-const Main = imports.ui.main;
const AppDisplay = imports.ui.appDisplay;
+const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid;
+const Main = imports.ui.main;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-const IconGridOverride = Me.imports.lib.iconGrid;
-const _Util = Me.imports.lib.util;
+let Me;
+let opt;
-const DIALOG_SHADE_NORMAL = Clutter.Color.from_pixel(0x00000022);
-const DIALOG_SHADE_HIGHLIGHT = Clutter.Color.from_pixel(0x00000000);
+let _timeouts;
-// gettext
-const _ = Me.imports.lib.settings._;
+// DIALOG_SHADE_NORMAL = Clutter.Color.from_pixel(0x00000022);
+// DIALOG_SHADE_HIGHLIGHT = Clutter.Color.from_pixel(0x00000000);
-let _overrides;
+var AppDisplayModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
-let _appGridLayoutSettings;
-let _appDisplayScrollConId;
-let _appSystemStateConId;
-let _appGridLayoutConId;
-let _origAppViewItemAcceptDrop;
-let _updateFolderIcons;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
-let opt;
-let shellVersion = _Util.shellVersion;
-let _firstRun = true;
+ this._appGridLayoutSettings = null;
+ this._appDisplayScrollConId = 0;
+ this._appSystemStateConId = 0;
+ this._appGridLayoutConId = 0;
+ this._origAppViewItemAcceptDrop = null;
+ this._updateFolderIcons = 0;
+ }
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('appDisplayModule', true);
- reset = reset || !moduleEnabled;
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
- // don't even touch this module if disabled
- if (_firstRun && reset)
- return;
+ update(reset) {
+ this._removeTimeouts();
+ this.moduleEnabled = opt.get('appDisplayModule');
+ const conflict = false;
- _firstRun = false;
+ reset = reset || !this.moduleEnabled || conflict;
- if (_overrides)
- _overrides.removeAll();
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ this.moduleEnabled = false;
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation) {
+ this.moduleEnabled = false;
+ console.debug(' AppDisplayModule - Keeping untouched');
+ }
+ }
- if (reset) {
- _setAppDisplayOrientation(false);
- _updateAppGridProperties(reset);
- _updateAppGridDND(reset);
- _restoreOverviewGroup();
- _overrides = null;
- opt = null;
- return;
+ _activateModule() {
+ Me.Modules.iconGridModule.update();
+
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ _timeouts = {};
+
+ // Common
+ this._overrides.addOverride('FolderView', AppDisplay.FolderView.prototype, FolderView);
+ this._overrides.addOverride('FolderIcon', AppDisplay.FolderIcon.prototype, FolderIcon);
+ if (opt.APP_GRID_ACTIVE_PREVIEW)
+ this._overrides.addOverride('ActiveFolderIcon', AppDisplay.FolderIcon, ActiveFolderIcon);
+ this._overrides.addOverride('AppIcon', AppDisplay.AppIcon.prototype, AppIcon);
+ this._overrides.addOverride('AppDisplay', AppDisplay.AppDisplay.prototype, AppDisplayCommon);
+ this._overrides.addOverride('AppViewItem', AppDisplay.AppViewItem.prototype, AppViewItemCommon);
+ this._overrides.addOverride('BaseAppViewCommon', AppDisplay.BaseAppView.prototype, BaseAppViewCommon);
+
+ if (opt.ORIENTATION === Clutter.Orientation.VERTICAL) {
+ this._overrides.addOverride('AppDisplayVertical', AppDisplay.AppDisplay.prototype, AppDisplayVertical);
+ this._overrides.addOverride('BaseAppViewVertical', AppDisplay.BaseAppView.prototype, BaseAppViewVertical);
+ }
+
+ // Custom App Grid
+ this._overrides.addOverride('AppFolderDialog', AppDisplay.AppFolderDialog.prototype, AppFolderDialog);
+ if (Me.shellVersion >= 43) {
+ // const defined class needs to be touched before real access
+ this._dummy = AppDisplay.AppGrid;
+ delete this._dummy;
+ // BaseAppViewGridLayout is not exported, we can only access current instance
+ this._overrides.addOverride('BaseAppViewGridLayout', Main.overview._overview.controls._appDisplay._appGridLayout, BaseAppViewGridLayout);
+ this._overrides.addOverride('FolderGrid', AppDisplay.FolderGrid.prototype, FolderGrid);
+ } else {
+ this._overrides.addOverride('FolderGrid', AppDisplay.FolderGrid.prototype, FolderGridLegacy);
+ }
+
+ this._setAppDisplayOrientation(opt.ORIENTATION === Clutter.Orientation.VERTICAL);
+ this._updateDND();
+ if (!Main.sessionMode.isGreeter)
+ this._updateAppDisplayProperties();
+
+ console.debug(' AppDisplayModule - Activated');
}
- _overrides = new _Util.Overrides();
+ _disableModule() {
+ Me.Modules.iconGridModule.update(true);
+
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
- if (opt.ORIENTATION === Clutter.Orientation.VERTICAL) {
- _overrides.addOverride('AppDisplayVertical', AppDisplay.AppDisplay.prototype, AppDisplayVertical);
- _overrides.addOverride('BaseAppViewVertical', AppDisplay.BaseAppView.prototype, BaseAppViewVertical);
+ const reset = true;
+ this._setAppDisplayOrientation(false);
+ this._updateAppDisplayProperties(reset);
+ this._updateDND(reset);
+ this._restoreOverviewGroup();
+ this._removeStatusMessage();
+
+ console.debug(' AppDisplayModule - Disabled');
}
- // Custom App Grid
- _overrides.addOverride('AppFolderDialog', AppDisplay.AppFolderDialog.prototype, AppFolderDialog);
- if (shellVersion >= 43) {
- // const defined class needs to be touched before real access
- AppDisplay.BaseAppViewGridLayout;
- _overrides.addOverride('BaseAppViewGridLayout', AppDisplay.BaseAppViewGridLayout.prototype, BaseAppViewGridLayout);
+ _removeTimeouts() {
+ if (_timeouts) {
+ Object.values(_timeouts).forEach(t => {
+ if (t)
+ GLib.source_remove(t);
+ });
+ _timeouts = null;
+ }
}
- _overrides.addOverride('FolderView', AppDisplay.FolderView.prototype, FolderView);
- _overrides.addOverride('FolderIcon', AppDisplay.FolderIcon.prototype, FolderIcon);
- _overrides.addOverride('AppIcon', AppDisplay.AppIcon.prototype, AppIcon);
- _overrides.addOverride('AppDisplay', AppDisplay.AppDisplay.prototype, AppDisplayCommon);
- _overrides.addOverride('AppViewItem', AppDisplay.AppViewItem.prototype, AppViewItemCommon);
- _overrides.addOverride('BaseAppViewCommon', AppDisplay.BaseAppView.prototype, BaseAppViewCommon);
-
- _setAppDisplayOrientation(opt.ORIENTATION === Clutter.Orientation.VERTICAL);
- _updateAppGridProperties();
- _updateAppGridDND();
- opt._appGridNeedsRedisplay = true;
-}
-
-function _setAppDisplayOrientation(vertical = false) {
- const CLUTTER_ORIENTATION = vertical ? Clutter.Orientation.VERTICAL : Clutter.Orientation.HORIZONTAL;
- const scroll = vertical ? 'vscroll' : 'hscroll';
- // app display to vertical has issues - page indicator not working
- // global appDisplay orientation switch is not built-in
- let appDisplay = Main.overview._overview._controls._appDisplay;
- // following line itself only changes in which axis will operate overshoot detection which switches appDisplay pages while dragging app icon to vertical
- appDisplay._orientation = CLUTTER_ORIENTATION;
- appDisplay._grid.layoutManager._orientation = CLUTTER_ORIENTATION;
- appDisplay._swipeTracker.orientation = CLUTTER_ORIENTATION;
- appDisplay._swipeTracker._reset();
- if (vertical) {
- appDisplay._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.EXTERNAL);
-
- // move and change orientation of page indicators
- // needs corrections in appgrid page calculations, e.g. appDisplay.adaptToSize() fnc,
- // which complicates use of super call inside the function
- const pageIndicators = appDisplay._pageIndicators;
- pageIndicators.vertical = true;
- appDisplay._box.vertical = false;
- pageIndicators.x_expand = false;
- pageIndicators.y_align = Clutter.ActorAlign.CENTER;
- pageIndicators.x_align = Clutter.ActorAlign.START;
-
- const scrollContainer = appDisplay._scrollView.get_parent();
- if (shellVersion < 43) {
- // remove touch friendly side navigation bars / arrows
- if (appDisplay._hintContainer && appDisplay._hintContainer.get_parent())
- scrollContainer.remove_child(appDisplay._hintContainer);
+
+ _setAppDisplayOrientation(vertical = false) {
+ const CLUTTER_ORIENTATION = vertical ? Clutter.Orientation.VERTICAL : Clutter.Orientation.HORIZONTAL;
+ const scroll = vertical ? 'vscroll' : 'hscroll';
+ // app display to vertical has issues - page indicator not working
+ // global appDisplay orientation switch is not built-in
+ let appDisplay = Main.overview._overview._controls._appDisplay;
+ // following line itself only changes in which axis will operate overshoot detection which switches appDisplay pages while dragging app icon to vertical
+ appDisplay._orientation = CLUTTER_ORIENTATION;
+ appDisplay._grid.layoutManager._orientation = CLUTTER_ORIENTATION;
+ appDisplay._swipeTracker.orientation = CLUTTER_ORIENTATION;
+ appDisplay._swipeTracker._reset();
+ if (vertical) {
+ appDisplay._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.EXTERNAL);
+
+ // move and change orientation of page indicators
+ const pageIndicators = appDisplay._pageIndicators;
+ pageIndicators.vertical = true;
+ appDisplay._box.vertical = false;
+ pageIndicators.x_expand = false;
+ pageIndicators.y_align = Clutter.ActorAlign.CENTER;
+ pageIndicators.x_align = Clutter.ActorAlign.START;
+
+ const scrollContainer = appDisplay._scrollView.get_parent();
+ if (Me.shellVersion < 43) {
+ // remove touch friendly side navigation bars / arrows
+ if (appDisplay._hintContainer && appDisplay._hintContainer.get_parent())
+ scrollContainer.remove_child(appDisplay._hintContainer);
+ } else {
+ // moving these bars needs more patching of the appDisplay's code
+ // for now we just change bars style to be more like vertically oriented arrows indicating direction to prev/next page
+ appDisplay._nextPageIndicator.add_style_class_name('nextPageIndicator');
+ appDisplay._prevPageIndicator.add_style_class_name('prevPageIndicator');
+ }
+
+ // setting their x_scale to 0 removes the arrows and avoid allocation issues compared to .hide() them
+ appDisplay._nextPageArrow.scale_x = 0;
+ appDisplay._prevPageArrow.scale_x = 0;
} else {
- // moving these bars needs more patching of the appDisplay's code
- // for now we just change bars style to be more like vertically oriented arrows indicating direction to prev/next page
- appDisplay._nextPageIndicator.add_style_class_name('nextPageIndicator');
- appDisplay._prevPageIndicator.add_style_class_name('prevPageIndicator');
- }
+ appDisplay._scrollView.set_policy(St.PolicyType.EXTERNAL, St.PolicyType.NEVER);
+ if (this._appDisplayScrollConId) {
+ appDisplay._adjustment.disconnect(this._appDisplayScrollConId);
+ this._appDisplayScrollConId = 0;
+ }
- // setting their x_scale to 0 removes the arrows and avoid allocation issues compared to .hide() them
- appDisplay._nextPageArrow.scale_x = 0;
- appDisplay._prevPageArrow.scale_x = 0;
- } else {
- appDisplay._scrollView.set_policy(St.PolicyType.EXTERNAL, St.PolicyType.NEVER);
- if (_appDisplayScrollConId) {
- appDisplay._adjustment.disconnect(_appDisplayScrollConId);
- _appDisplayScrollConId = 0;
+ // restore original page indicators
+ const pageIndicators = appDisplay._pageIndicators;
+ pageIndicators.vertical = false;
+ appDisplay._box.vertical = true;
+ pageIndicators.x_expand = true;
+ pageIndicators.y_align = Clutter.ActorAlign.END;
+ pageIndicators.x_align = Clutter.ActorAlign.CENTER;
+
+ // put back touch friendly navigation bars/buttons
+ const scrollContainer = appDisplay._scrollView.get_parent();
+ if (appDisplay._hintContainer && !appDisplay._hintContainer.get_parent()) {
+ scrollContainer.add_child(appDisplay._hintContainer);
+ // the hit container covers the entire app grid and added at the top of the stack blocks DND drops
+ // so it needs to be pushed below
+ scrollContainer.set_child_below_sibling(appDisplay._hintContainer, null);
+ }
+
+ appDisplay._nextPageArrow.scale_x = 1;
+ appDisplay._prevPageArrow.scale_x = 1;
+
+ appDisplay._nextPageIndicator.remove_style_class_name('nextPageIndicator');
+ appDisplay._prevPageIndicator.remove_style_class_name('prevPageIndicator');
}
- // restore original page indicators
- const pageIndicators = appDisplay._pageIndicators;
- pageIndicators.vertical = false;
- appDisplay._box.vertical = true;
- pageIndicators.x_expand = true;
- pageIndicators.y_align = Clutter.ActorAlign.END;
- pageIndicators.x_align = Clutter.ActorAlign.CENTER;
-
- // put back touch friendly navigation bars/buttons
- const scrollContainer = appDisplay._scrollView.get_parent();
- if (appDisplay._hintContainer && !appDisplay._hintContainer.get_parent()) {
- scrollContainer.add_child(appDisplay._hintContainer);
- // the hit container covers the entire app grid and added at the top of the stack blocks DND drops
- // so it needs to be pushed below
- scrollContainer.set_child_below_sibling(appDisplay._hintContainer, null);
+ // value for page indicator is calculated from scroll adjustment, horizontal needs to be replaced by vertical
+ appDisplay._adjustment = appDisplay._scrollView[scroll].adjustment;
+
+ // no need to connect already connected signal (wasn't removed the original one before)
+ if (!vertical) {
+ // reset used appDisplay properties
+ Main.overview._overview._controls._appDisplay.scale_y = 1;
+ Main.overview._overview._controls._appDisplay.scale_x = 1;
+ Main.overview._overview._controls._appDisplay.opacity = 255;
+ return;
}
- appDisplay._nextPageArrow.scale_x = 1;
- appDisplay._prevPageArrow.scale_x = 1;
+ // update appGrid dot pages indicators
+ this._appDisplayScrollConId = appDisplay._adjustment.connect('notify::value', adj => {
+ const value = adj.value / adj.page_size;
+ appDisplay._pageIndicators.setCurrentPosition(value);
+ });
+ }
+
+ // Set App Grid columns, rows, icon size, incomplete pages
+ _updateAppDisplayProperties(reset = false) {
+ opt._appGridNeedsRedisplay = false;
+ // columns, rows, icon size
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ appDisplay.visible = true;
+ if (reset) {
+ appDisplay._grid.layoutManager.fixedIconSize = -1;
+ appDisplay._grid.layoutManager.allow_incomplete_pages = true;
+ appDisplay._grid._currentMode = -1;
+ appDisplay._grid.setGridModes();
+ if (this._appGridLayoutSettings) {
+ this._appGridLayoutSettings.disconnect(this._appGridLayoutConId);
+ this._appGridLayoutConId = 0;
+ this._appGridLayoutSettings = null;
+ }
+ appDisplay._redisplay();
- appDisplay._nextPageIndicator.remove_style_class_name('nextPageIndicator');
- appDisplay._prevPageIndicator.remove_style_class_name('prevPageIndicator');
+ appDisplay._grid.set_style('');
+ this._updateAppGrid(reset);
+ } else {
+ // update grid on layout reset
+ if (!this._appGridLayoutSettings) {
+ this._appGridLayoutSettings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
+ this._appGridLayoutConId = this._appGridLayoutSettings.connect('changed::app-picker-layout', this._updateLayout);
+ }
+
+ appDisplay._grid.layoutManager.allow_incomplete_pages = opt.APP_GRID_ALLOW_INCOMPLETE_PAGES;
+ // appDisplay._grid.set_style(`column-spacing: ${opt.APP_GRID_SPACING}px; row-spacing: ${opt.APP_GRID_SPACING}px;`);
+ // APP_GRID_SPACING constant is used for grid dimensions calculation
+ // but sometimes the actual grid spacing properties affect/change the calculated size, therefore we set it lower to avoid this problem
+ // main app grid always use available space and the spacing is optimized for the grid dimensions
+ appDisplay._grid.set_style('column-spacing: 5px; row-spacing: 5px;');
+
+ // force redisplay
+ appDisplay._grid._currentMode = -1;
+ appDisplay._grid.setGridModes();
+ appDisplay._grid.layoutManager.fixedIconSize = opt.APP_GRID_ICON_SIZE;
+ // avoid resetting appDisplay before startup animation
+ // x11 shell restart skips startup animation
+ if (!Main.layoutManager._startingUp) {
+ this._updateAppGrid();
+ } else if (Main.layoutManager._startingUp && (Meta.is_restart() || Me.Util.dashIsDashToDock())) {
+ _timeouts.three = GLib.idle_add(GLib.PRIORITY_LOW, () => {
+ this._updateAppGrid();
+ _timeouts.three = 0;
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+ }
}
- // value for page indicator is calculated from scroll adjustment, horizontal needs to be replaced by vertical
- appDisplay._adjustment = appDisplay._scrollView[scroll].adjustment;
+ _updateDND(reset) {
+ if (!reset) {
+ if (!this._appSystemStateConId && opt.APP_GRID_INCLUDE_DASH >= 3) {
+ this._appSystemStateConId = Shell.AppSystem.get_default().connect(
+ 'app-state-changed',
+ () => {
+ this._updateFolderIcons = true;
+ Main.overview._overview.controls._appDisplay._redisplay();
+ }
+ );
+ }
+ } else if (this._appSystemStateConId) {
+ Shell.AppSystem.get_default().disconnect(this._appSystemStateConId);
+ this._appSystemStateConId = 0;
+ }
+ }
- // no need to connect already connected signal (wasn't removed the original one before)
- if (!vertical) {
- // reset used appDisplay properties
- Main.overview._overview._controls._appDisplay.scale_y = 1;
- Main.overview._overview._controls._appDisplay.scale_x = 1;
+ _restoreOverviewGroup() {
+ Main.overview.dash.showAppsButton.checked = false;
+ Main.layoutManager.overviewGroup.opacity = 255;
+ Main.layoutManager.overviewGroup.scale_x = 1;
+ Main.layoutManager.overviewGroup.scale_y = 1;
+ Main.layoutManager.overviewGroup.hide();
+ Main.overview._overview._controls._appDisplay.translation_x = 0;
+ Main.overview._overview._controls._appDisplay.translation_y = 0;
+ Main.overview._overview._controls._appDisplay.visible = true;
Main.overview._overview._controls._appDisplay.opacity = 255;
- return;
}
- // update appGrid dot pages indicators
- _appDisplayScrollConId = appDisplay._adjustment.connect('notify::value', adj => {
- const value = adj.value / adj.page_size;
- appDisplay._pageIndicators.setCurrentPosition(value);
- });
-}
-
-// Set App Grid columns, rows, icon size, incomplete pages
-function _updateAppGridProperties(reset = false) {
- opt._appGridNeedsRedisplay = false;
- // columns, rows, icon size
- const appDisplay = Main.overview._overview._controls._appDisplay;
- appDisplay.visible = true;
-
- if (reset) {
- appDisplay._grid.layoutManager.fixedIconSize = -1;
- appDisplay._grid.layoutManager.allow_incomplete_pages = true;
- appDisplay._grid.setGridModes();
- if (_appGridLayoutSettings) {
- _appGridLayoutSettings.disconnect(_appGridLayoutConId);
- _appGridLayoutConId = 0;
- _appGridLayoutSettings = null;
+ // update all invalid positions that may be result of grid/icon size change
+ _updateIconPositions() {
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ const layout = JSON.stringify(global.settings.get_value('app-picker-layout').recursiveUnpack());
+ // if app grid layout is empty, sort source alphabetically to avoid misplacing
+ if (layout === JSON.stringify([]) && appDisplay._sortOrderedItemsAlphabetically)
+ appDisplay._sortOrderedItemsAlphabetically();
+ const icons = [...appDisplay._orderedItems];
+ for (let i = 0; i < icons.length; i++)
+ appDisplay._moveItem(icons[i], -1, -1);
+ }
+
+ _removeIcons() {
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ const icons = [...appDisplay._orderedItems];
+ for (let i = 0; i < icons.length; i++) {
+ const icon = icons[i];
+ if (icon._dialog)
+ Main.layoutManager.overviewGroup.remove_child(icon._dialog);
+ appDisplay._removeItem(icon);
+ icon.destroy();
}
- appDisplay._redisplay();
+ appDisplay._folderIcons = [];
+ }
+
+ _removeStatusMessage() {
+ if (Me._vShellStatusMessage) {
+ if (Me._vShellMessageTimeoutId) {
+ GLib.source_remove(Me._vShellMessageTimeoutId);
+ Me._vShellMessageTimeoutId = 0;
+ }
+ Me._vShellStatusMessage.destroy();
+ Me._vShellStatusMessage = null;
+ }
+ }
- appDisplay._grid.set_style('');
- _resetAppGrid();
- } else {
- // update grid on layout reset
- if (!_appGridLayoutSettings) {
- _appGridLayoutSettings = ExtensionUtils.getSettings('org.gnome.shell');
- _appGridLayoutConId = _appGridLayoutSettings.connect('changed::app-picker-layout', _resetAppGrid);
+ _updateLayout(settings, key) {
+ const currentValue = JSON.stringify(settings.get_value(key).deep_unpack());
+ const emptyValue = JSON.stringify([]);
+ const customLayout = currentValue !== emptyValue;
+ if (!customLayout) {
+ this._updateAppGrid();
+ }
+ }
+
+ _updateAppGrid(reset = false, callback) {
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ // reset the grid only if called directly without args or if all folders where removed by using reset button in Settings window
+ // otherwise this function is called every time a user moves icon to another position as a settings callback
+
+ // force update icon size using adaptToSize(), the page size cannot be the same as the current one
+ appDisplay._grid.layoutManager._pageWidth += 1;
+ appDisplay._grid.layoutManager.adaptToSize(appDisplay._grid.layoutManager._pageWidth - 1, appDisplay._grid.layoutManager._pageHeight);
+
+ // don't delay the first screen lock on GS < 44, removing icons takes a time and with other 15 enabled extensions it can be multiplied by 15
+ if (!Main.sessionMode.isLocked)
+ this._removeIcons();
+
+ appDisplay._redisplay();
+ // don't realize appDisplay on disable, or at startup if disabled
+ // always realize appDisplay otherwise to avoid errors while opening folders (that I was unable to trace)
+ if (reset || (!opt.APP_GRID_PERFORMANCE && callback)) {
+ this._removeStatusMessage();
+ if (callback)
+ callback();
+ return;
}
- appDisplay._grid.layoutManager.allow_incomplete_pages = opt.APP_GRID_ALLOW_INCOMPLETE_PAGES;
- appDisplay._grid.set_style(`column-spacing: ${opt.APP_GRID_SPACING}px; row-spacing: ${opt.APP_GRID_SPACING}px;`);
+ // workaround - silently realize appDisplay
+ // appDisplay and its content must be "visible" (opacity > 0) on the screen (within monitor geometry)
+ // to realize its objects
+ // this action takes some time and affects animations during the first use
+ // if we do it invisibly before user needs it, it can improve the user's experience
+
+ this._exposeAppGrid();
+
+ // let the main loop process our changes before continuing
+ _timeouts.one = GLib.idle_add(GLib.PRIORITY_LOW, () => {
+ this._updateIconPositions();
+ if (appDisplay._sortOrderedItemsAlphabetically) {
+ appDisplay._sortOrderedItemsAlphabetically();
+ appDisplay._grid.layoutManager._pageWidth += 1;
+ appDisplay._grid.layoutManager.adaptToSize(appDisplay._grid.layoutManager._pageWidth - 1, appDisplay._grid.layoutManager._pageHeight);
+ appDisplay._setLinearPositions(appDisplay._orderedItems);
+ }
- // force redisplay
- appDisplay._grid._currentMode = -1;
- appDisplay._grid.setGridModes();
- appDisplay._grid.layoutManager.fixedIconSize = opt.APP_GRID_ICON_SIZE;
- // appDisplay._folderIcons.forEach(folder => folder._dialog?._updateFolderSize());
- _resetAppGrid();
+ appDisplay._redisplay();
+ // realize also all app folders (by opening them) so the first popup is as smooth as the second one
+ // let the main loop process our changes before continuing
+ _timeouts.two = GLib.idle_add(GLib.PRIORITY_LOW, () => {
+ this._restoreAppGrid();
+ Me._resetInProgress = false;
+ this._removeStatusMessage();
+
+ if (callback)
+ callback();
+
+ _timeouts.two = 0;
+ return GLib.SOURCE_REMOVE;
+ });
+ _timeouts.one = 0;
+ return GLib.SOURCE_REMOVE;
+ });
}
-}
-function _updateAppGridDND(reset) {
- if (!reset) {
- if (!_appSystemStateConId && opt.APP_GRID_INCLUDE_DASH >= 3) {
- _appSystemStateConId = Shell.AppSystem.get_default().connect(
- 'app-state-changed',
- () => {
- _updateFolderIcons = true;
- Main.overview._overview._controls._appDisplay._redisplay();
- }
- );
+ _exposeAppGrid() {
+ const overviewGroup = Main.layoutManager.overviewGroup;
+ if (!overviewGroup.visible) {
+ // scale down the overviewGroup so it don't cover uiGroup
+ overviewGroup.scale_y = 0.001;
+ // make it invisible to the eye, but visible for the renderer
+ overviewGroup.opacity = 1;
+ // if overview is hidden, show it
+ overviewGroup.visible = true;
}
- } else if (_appSystemStateConId) {
- Shell.AppSystem.get_default().disconnect(_appSystemStateConId);
- _appSystemStateConId = 0;
+
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ appDisplay.opacity = 1;
+
+ // find usable value, sometimes it's one, sometime the other...
+ let [x, y] = appDisplay.get_position();
+ let { x1, y1 } = appDisplay.allocation;
+ x = x === Infinity ? 0 : x;
+ y = y === Infinity ? 0 : y;
+ x1 = x1 === Infinity ? 0 : x1;
+ y1 = y1 === Infinity ? 0 : y1;
+ appDisplay.translation_x = -(x ? x : x1);
+ appDisplay.translation_y = -(y ? y : y1);
+ this._exposeAppFolders();
+ }
+
+ _exposeAppFolders() {
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ appDisplay._folderIcons.forEach(d => {
+ d._ensureFolderDialog();
+ d._dialog._updateFolderSize();
+ d._dialog.scale_y = 0.0001;
+ d._dialog.show();
+ });
+ }
+
+ _restoreAppGrid() {
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ appDisplay.translation_x = 0;
+ appDisplay.translation_y = 0;
+ // appDisplay.opacity = 0;
+ this._hideAppFolders();
+
+ const overviewGroup = Main.layoutManager.overviewGroup;
+ if (!Main.overview._shown)
+ overviewGroup.hide();
+ overviewGroup.scale_y = 1;
+ overviewGroup.opacity = 255;
+
+ this._removeStatusMessage();
+ }
+
+ _hideAppFolders() {
+ const appDisplay = Main.overview._overview._controls._appDisplay;
+ appDisplay._folderIcons.forEach(d => {
+ if (d._dialog) {
+ d._dialog._updateFolderSize();
+ d._dialog.hide();
+ d._dialog.scale_y = 1;
+ }
+ });
+ }
+
+ _getWindowApp(metaWin) {
+ const tracker = Shell.WindowTracker.get_default();
+ return tracker.get_window_app(metaWin);
}
- if (opt.APP_GRID_ORDER && !reset) {
- if (!_origAppViewItemAcceptDrop)
- _origAppViewItemAcceptDrop = AppDisplay.AppViewItem.prototype.acceptDrop;
- AppDisplay.AppViewItem.prototype.acceptDrop = () => false;
- } else if (_origAppViewItemAcceptDrop) {
- AppDisplay.AppViewItem.prototype.acceptDrop = _origAppViewItemAcceptDrop;
+
+ _getAppLastUsedWindow(app) {
+ let recentWin;
+ global.display.get_tab_list(Meta.TabList.NORMAL_ALL, null).forEach(metaWin => {
+ const winApp = this._getWindowApp(metaWin);
+ if (!recentWin && winApp === app)
+ recentWin = metaWin;
+ });
+ return recentWin;
}
-}
-function _restoreOverviewGroup() {
- Main.overview.dash.showAppsButton.checked = false;
- Main.layoutManager.overviewGroup.opacity = 255;
- Main.layoutManager.overviewGroup.scale_x = 1;
- Main.layoutManager.overviewGroup.hide();
-}
+ _getAppRecentWorkspace(app) {
+ const recentWin = this._getAppLastUsedWindow(app);
+ if (recentWin)
+ return recentWin.get_workspace();
+
+ return null;
+ }
+};
const AppDisplayVertical = {
// correction of the appGrid size when page indicators were moved from the bottom to the right
@@ -302,7 +557,7 @@ const AppDisplayCommon = {
const appsInsideFolders = new Set();
this._folderIcons = [];
- if (!opt.APP_GRID_ORDER) {
+ if (!opt.APP_GRID_USAGE) {
let folders = this._folderSettings.get_strv('folder-children');
folders.forEach(id => {
let path = `${this._folderSettings.path}folders/${id}/`;
@@ -317,8 +572,8 @@ const AppDisplayCommon = {
if (icon.pressed)
this.updateDragFocus(icon);
});
- } else if (_updateFolderIcons && opt.APP_GRID_EXCLUDE_RUNNING) {
- // if any app changed its running state, update folder icon
+ } else if (this._updateFolderIcons && opt.APP_GRID_EXCLUDE_RUNNING) {
+ // if any app changed its running state, update folder icon
icon.icon.update();
}
@@ -334,8 +589,9 @@ const AppDisplayCommon = {
icon.getAppIds().forEach(appId => appsInsideFolders.add(appId));
});
}
+
// reset request to update active icon
- _updateFolderIcons = false;
+ this._updateFolderIcons = false;
// Allow dragging of the icon only if the Dash would accept a drop to
// change favorite-apps. There are no other possible drop targets from
@@ -348,7 +604,7 @@ const AppDisplayCommon = {
global.settings.is_writable('app-picker-layout');
apps.forEach(appId => {
- if (!opt.APP_GRID_ORDER && appsInsideFolders.has(appId))
+ if (!opt.APP_GRID_USAGE && appsInsideFolders.has(appId))
return;
let icon = this._items.get(appId);
@@ -380,7 +636,7 @@ const AppDisplayCommon = {
dragMotion: this._onDragMotion.bind(this),
};
DND.addDragMonitor(this._dragMonitor);
- if (shellVersion < 43)
+ if (Me.shellVersion < 43)
this._slideSidePages(AppDisplay.SidePages.PREVIOUS | AppDisplay.SidePages.NEXT | AppDisplay.SidePages.DND);
else
this._appGridLayout.showPageIndicators();
@@ -419,50 +675,16 @@ const AppDisplayCommon = {
this._redisplay();
},
- // accept source from active preview
+ // accept source from active folder preview
acceptDrop(source) {
- if (opt.APP_GRID_ORDER)
+ if (opt.APP_GRID_USAGE)
return false;
if (source._sourceItem)
source = source._sourceItem;
- let dropTarget = null;
- if (shellVersion >= 43) {
- dropTarget = this._dropTarget;
- delete this._dropTarget;
- }
-
- if (!this._canAccept(source))
+ if (!BaseAppViewCommon.acceptDrop.bind(this)(source))
return false;
- if ((shellVersion < 43 && this._dropPage) ||
- (shellVersion >= 43 && (dropTarget === this._prevPageIndicator ||
- dropTarget === this._nextPageIndicator))) {
- let increment;
-
- if (shellVersion < 43)
- increment = this._dropPage === AppDisplay.SidePages.NEXT ? 1 : -1;
- else
- increment = dropTarget === this._prevPageIndicator ? -1 : 1;
-
- const { currentPage, nPages } = this._grid;
- const page = Math.min(currentPage + increment, nPages);
- const position = page < nPages ? -1 : 0;
-
- this._moveItem(source, page, position);
- this.goToPage(page);
- } else if (this._delayedMoveData) {
- // Dropped before the icon was moved
- const { page, position } = this._delayedMoveData;
-
- try {
- this._moveItem(source, page, position);
- } catch (e) {
- log(`Warning:${e}`);
- }
- this._removeDelayedMove();
- }
-
this._savePages();
let view = AppDisplay._getViewFromIcon(source);
@@ -493,7 +715,7 @@ const BaseAppViewVertical = {
this._pageIndicators.x_align = Clutter.ActorAlign.START;
this._pageIndicators.set_style('margin-right: 10px;');
const scrollContainer = this._scrollView.get_parent();
- if (shellVersion < 43) {
+ if (Me.shellVersion < 43) {
// remove touch friendly side navigation bars / arrows
if (this._hintContainer && this._hintContainer.get_parent())
scrollContainer.remove_child(this._hintContainer);
@@ -536,7 +758,7 @@ const BaseAppViewCommon = {
try {
this._moveItem(icon, page, position);
} catch (e) {
- log(`Warning:${e}`);
+ console.warn(`Warning:${e}`);
}
});
},
@@ -570,14 +792,19 @@ const BaseAppViewCommon = {
}
});
- // sort all alphabetically
- if (opt.APP_GRID_ORDER > 0) {
+ // different options for root app grid and app folders
+ const thisIsFolder = this instanceof AppDisplay.FolderView;
+ const thisIsAppDisplay = !thisIsFolder;
+ if ((opt.APP_GRID_ORDER && thisIsAppDisplay) ||
+ (opt.APP_FOLDER_ORDER && thisIsFolder)) {
// const { itemsPerPage } = this._grid;
let appIcons = this._orderedItems;
+ // sort all alphabetically
this._sortOrderedItemsAlphabetically(appIcons);
// appIcons.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
// then sort used apps by usage
- if (opt.APP_GRID_ORDER === 2)
+ if ((opt.APP_GRID_USAGE && thisIsAppDisplay) ||
+ (opt.APP_FOLDER_USAGE && thisIsFolder))
appIcons.sort((a, b) => Shell.AppUsage.get_default().compare(a.app.id, b.app.id));
// sort favorites first
@@ -595,9 +822,14 @@ const BaseAppViewCommon = {
}
// sort running first
- if (opt.APP_GRID_DASH_FIRST)
+ if (opt.APP_GRID_DASH_FIRST && thisIsAppDisplay)
appIcons.sort((a, b) => a.app.get_state() !== Shell.AppState.RUNNING && b.app.get_state() === Shell.AppState.RUNNING);
+ if (opt.APP_GRID_FOLDERS_FIRST)
+ appIcons.sort((a, b) => b._folder && !a._folder);
+ else if (opt.APP_GRID_FOLDERS_LAST)
+ appIcons.sort((a, b) => a._folder && !b._folder);
+
this._setLinearPositions(appIcons);
this._orderedItems = appIcons;
@@ -611,7 +843,7 @@ const BaseAppViewCommon = {
},
_canAccept(source) {
- return opt.APP_GRID_ORDER ? false : source instanceof AppDisplay.AppViewItem;
+ return source instanceof AppDisplay.AppViewItem;
},
// support active preview icons
@@ -619,12 +851,25 @@ const BaseAppViewCommon = {
if (!this._canAccept(source))
return false;
- if (source._sourceItem)
- source = source._sourceItem;
+ let dropTarget = null;
+ if (Me.shellVersion >= 43) {
+ dropTarget = this._dropTarget;
+ delete this._dropTarget;
+ }
+
+ if (!this._canAccept(source))
+ return false;
+ if ((Me.shellVersion < 43 && this._dropPage) ||
+ (Me.shellVersion >= 43 && (dropTarget === this._prevPageIndicator ||
+ dropTarget === this._nextPageIndicator))) {
+ let increment;
+
+ if (Me.shellVersion < 43)
+ increment = this._dropPage === AppDisplay.SidePages.NEXT ? 1 : -1;
+ else
+ increment = dropTarget === this._prevPageIndicator ? -1 : 1;
- if (this._dropPage) {
- const increment = this._dropPage === AppDisplay.SidePages.NEXT ? 1 : -1;
const { currentPage, nPages } = this._grid;
const page = Math.min(currentPage + increment, nPages);
const position = page < nPages ? -1 : 0;
@@ -635,7 +880,11 @@ const BaseAppViewCommon = {
// Dropped before the icon was moved
const { page, position } = this._delayedMoveData;
- this._moveItem(source, page, position);
+ try {
+ this._moveItem(source, page, position);
+ } catch (e) {
+ console.warn(`Warning:${e}`);
+ }
this._removeDelayedMove();
}
@@ -652,7 +901,7 @@ const BaseAppViewCommon = {
const appIcon = dragEvent.source;
- if (shellVersion < 43) {
+ if (Me.shellVersion < 43) {
this._dropPage = this._pageForCoords(dragEvent.x, dragEvent.y);
if (this._dropPage &&
this._dropPage === AppDisplay.SidePages.PREVIOUS &&
@@ -663,7 +912,7 @@ const BaseAppViewCommon = {
}
if (appIcon instanceof AppDisplay.AppViewItem) {
- if (shellVersion < 44) {
+ if (Me.shellVersion < 44) {
// Handle the drag overshoot. When dragging to above the
// icon grid, move to the page above; when dragging below,
// move to the page below.
@@ -685,7 +934,10 @@ const BaseAppViewCommon = {
}
}
- this._maybeMoveItem(dragEvent);
+ const thisIsFolder = this instanceof AppDisplay.FolderView;
+ const thisIsAppDisplay = !thisIsFolder;
+ if ((!opt.APP_GRID_ORDER && thisIsAppDisplay) || (!opt.APP_FOLDER_ORDER && thisIsFolder))
+ this._maybeMoveItem(dragEvent);
return DND.DragMotionResult.CONTINUE;
},
@@ -771,16 +1023,12 @@ const FolderIcon = {
: St.ButtonMask.ONE | St.ButtonMask.TWO;
this.button_mask = buttonMask;*/
this.button_mask = St.ButtonMask.ONE | St.ButtonMask.TWO;
-
- // build the folders now to avoid node errors when dragging active folder preview icons
- if (this.visible && opt.APP_GRID_ACTIVE_PREVIEW)
- this._ensureFolderDialog();
},
open() {
this._ensureFolderDialog();
- if (this._dialog._designCapacity !== this.view._orderedItems.length)
- this._dialog._updateFolderSize();
+ // if (this._dialog._designCapacity !== this.view._orderedItems.length)
+ this._dialog._updateFolderSize();
this.view._scrollView.vscroll.adjustment.value = 0;
this._dialog.popup();
@@ -789,15 +1037,7 @@ const FolderIcon = {
const FolderView = {
_createGrid() {
- let grid;
- if (shellVersion < 43)
- grid = new FolderGrid();
- else
- grid = new FolderGrid43();
-
- // IconGrid algorithm for adaptive icon size
- // counts with different default(max) size for folders
- grid.layoutManager._isFolder = true;
+ let grid = new AppDisplay.FolderGrid();
return grid;
},
@@ -832,11 +1072,15 @@ const FolderView = {
bin.child = this._orderedItems[i].app.create_icon_texture(subSize);
} else {
const app = this._orderedItems[i].app;
- const child = new ActiveFolderIcon(app);
+ const child = new AppDisplay.AppIcon(app, {
+ setSizeManually: true,
+ showLabel: false,
+ });
child._sourceItem = this._orderedItems[i];
child._sourceFolder = this;
child.icon.style_class = '';
child.icon.set_style('margin: 0; padding: 0;');
+ child._dot.set_style('margin-bottom: 1px;');
child.icon.setIconSize(subSize);
bin.child = child;
@@ -863,9 +1107,9 @@ const FolderView = {
layout.attach(bin, rtl ? (i + 1) % gridSize : i % gridSize, Math.floor(i / gridSize), 1, 1);
}
- // if folder content changed, update folder size
- if (this._dialog && this._dialog._designCapacity !== this._orderedItems.length)
- this._dialog._updateFolderSize();
+ // if folder content changed, update folder size, but not if it's empty
+ /* if (this._dialog && this._dialog._designCapacity !== this._orderedItems.length && this._orderedItems.length)
+ this._dialog._updateFolderSize();*/
return icon;
},
@@ -927,6 +1171,13 @@ const FolderView = {
items.push(icon);
});
+
+ if (opt.APP_FOLDER_ORDER)
+ Main.overview._overview.controls._appDisplay._sortOrderedItemsAlphabetically(items);
+
+ if (opt.APP_FOLDER_USAGE)
+ items.sort((a, b) => Shell.AppUsage.get_default().compare(a.app.id, b.app.id));
+
this._appIds = this._apps.map(app => app.get_id());
return items;
},
@@ -942,10 +1193,9 @@ const FolderView = {
};
// folder columns and rows
-const FolderGrid = GObject.registerClass(
-class FolderGrid extends IconGrid.IconGrid {
+const FolderGridLegacy = {
_init() {
- super._init({
+ IconGrid.IconGrid.prototype._init.bind(this)({
allow_incomplete_pages: false,
// For adaptive size (0), set the numbers high enough to fit all the icons
// to avoid splitting the icons to pages
@@ -954,56 +1204,52 @@ class FolderGrid extends IconGrid.IconGrid {
page_halign: Clutter.ActorAlign.CENTER,
page_valign: Clutter.ActorAlign.CENTER,
});
-
+ this.layout_manager._isFolder = true;
// if (!opt.APP_GRID_FOLDER_DEFAULT)
const spacing = opt.APP_GRID_SPACING;
this.set_style(`column-spacing: ${spacing}px; row-spacing: ${spacing}px;`);
- this.layout_manager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
- }
+ this.layoutManager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
+ },
adaptToSize(width, height) {
this.layout_manager.adaptToSize(width, height);
- }
-});
-
-
-let FolderGrid43;
-// first reference to constant defined using const in other module returns undefined, the AppGrid const will remain empty and unused
-const AppGrid = AppDisplay.AppGrid;
-if (AppDisplay.AppGrid) {
- FolderGrid43 = GObject.registerClass(
- class FolderGrid43 extends AppDisplay.AppGrid {
- _init() {
- super._init({
- allow_incomplete_pages: false,
- columns_per_page: opt.APP_GRID_FOLDER_COLUMNS ? opt.APP_GRID_FOLDER_COLUMNS : 20,
- rows_per_page: opt.APP_GRID_FOLDER_ROWS ? opt.APP_GRID_FOLDER_ROWS : 20,
- page_halign: Clutter.ActorAlign.CENTER,
- page_valign: Clutter.ActorAlign.CENTER,
- });
+ },
+};
+
+const FolderGrid = {
+ _init() {
+ AppDisplay.AppGrid.prototype._init.bind(this)({
+ allow_incomplete_pages: false,
+ columns_per_page: opt.APP_GRID_FOLDER_COLUMNS ? opt.APP_GRID_FOLDER_COLUMNS : 20,
+ rows_per_page: opt.APP_GRID_FOLDER_ROWS ? opt.APP_GRID_FOLDER_ROWS : 20,
+ page_halign: Clutter.ActorAlign.CENTER,
+ page_valign: Clutter.ActorAlign.CENTER,
+ });
+ this.layout_manager._isFolder = true;
+ const spacing = opt.APP_GRID_SPACING;
+ this.set_style(`column-spacing: ${spacing}px; row-spacing: ${spacing}px;`);
+ this.layoutManager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
- const spacing = opt.APP_GRID_SPACING;
- this.set_style(`column-spacing: ${spacing}px; row-spacing: ${spacing}px;`);
- this.layout_manager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
+ this.setGridModes([
+ {
+ columns: opt.APP_GRID_FOLDER_COLUMNS ? opt.APP_GRID_FOLDER_COLUMNS : 3,
+ rows: opt.APP_GRID_FOLDER_ROWS ? opt.APP_GRID_FOLDER_ROWS : 3,
+ },
+ ]);
+ },
- this.setGridModes([
- {
- columns: opt.APP_GRID_FOLDER_COLUMNS ? opt.APP_GRID_FOLDER_COLUMNS : 3,
- rows: opt.APP_GRID_FOLDER_ROWS ? opt.APP_GRID_FOLDER_ROWS : 3,
- },
- ]);
- }
+ adaptToSize(width, height) {
+ this.layout_manager.adaptToSize(width, height);
+ },
+};
- adaptToSize(width, height) {
- this.layout_manager.adaptToSize(width, height);
- }
- });
-}
const FOLDER_DIALOG_ANIMATION_TIME = 200; // AppDisplay.FOLDER_DIALOG_ANIMATION_TIME
const AppFolderDialog = {
// injection to _init()
after__init() {
+ this._viewBox.add_style_class_name('app-folder-dialog-vshell');
+
// delegate this dialog to the FolderIcon._view
// so its _createFolderIcon function can update the dialog if folder content changed
this._view._dialog = this;
@@ -1023,18 +1269,65 @@ const AppFolderDialog = {
});
this.child.add_action(clickAction);
+
+ // Adjust empty actor to center the title
+ this._entryBox.get_first_child().width = 82;
+ },
+
+ after__addFolderNameEntry() {
+ // Edit button
+ this._removeButton = new St.Button({
+ style_class: 'edit-folder-button',
+ button_mask: St.ButtonMask.ONE,
+ toggle_mode: false,
+ reactive: true,
+ can_focus: true,
+ x_align: Clutter.ActorAlign.END,
+ y_align: Clutter.ActorAlign.CENTER,
+ child: new St.Icon({
+ icon_name: 'user-trash-symbolic',
+ icon_size: 16,
+ }),
+ });
+
+ this._removeButton.connect('clicked', () => {
+ if (Date.now() - this._removeButton._lastClick < Clutter.Settings.get_default().double_click_time) {
+ this._grabHelper.ungrab({ actor: this });
+ // without hiding the dialog, Shell crashes (at least on X11)
+ this.hide();
+ this._view._deletingFolder = true;
+
+ // Resetting all keys deletes the relocatable schema
+ let keys = this._folder.settings_schema.list_keys();
+ for (const key of keys)
+ this._folder.reset(key);
+
+ let settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders' });
+ let folders = settings.get_strv('folder-children');
+ folders.splice(folders.indexOf(this._view._id), 1);
+
+ // remove all abandoned folders (usually my own garbage and unwanted default folders...)
+ /* const appFolders = this._appDisplay._folderIcons.map(icon => icon._id);
+ folders.forEach(folder => {
+ if (!appFolders.includes(folder)) {
+ folders.splice(folders.indexOf(folder._id), 1);
+ }
+ });*/
+ settings.set_strv('folder-children', folders);
+
+ this._view._deletingFolder = false;
+ return;
+ }
+ this._removeButton._lastClick = Date.now();
+ });
+
+ this._entryBox.add_child(this._removeButton);
},
popup() {
if (this._isOpen)
return;
- /* if (!this._correctSize) {
- // update folder with the precise app item size when the dialog is realized
- GLib.idle_add(0, () => this._updateFolderSize(true));
- this._correctSize = true;
- }*/
-
this._isOpen = this._grabHelper.grab({
actor: this,
onUngrab: () => this.popdown(),
@@ -1046,26 +1339,48 @@ const AppFolderDialog = {
this.get_parent().set_child_above_sibling(this, null);
this._needsZoomAndFade = true;
- this.show();
+ // the first folder dialog realization needs size correction
+ // so set the folder size, let it realize and then update the folder content
+ if (!this.realized) {
+ this._updateFolderSize();
+ GLib.idle_add(
+ GLib.PRIORITY_DEFAULT,
+ () => {
+ this._updateFolderSize();
+ }
+ );
+ }
+
+ this.show();
this.emit('open-state-changed', true);
},
_updateFolderSize() {
- // adapt folder size according to the settings and number of icons
const view = this._view;
+ const [firstItem] = view._grid.layoutManager._container;
+ if (!firstItem)
+ return;
+ // adapt folder size according to the settings and number of icons
+ const appDisplay = this._source._parentView;
+ if (!appDisplay.width || appDisplay.allocation.x2 === Infinity || appDisplay.allocation.x2 === -Infinity) {
+ return;
+ }
+
view._grid.layoutManager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
view._grid.set_style(`column-spacing: ${opt.APP_GRID_SPACING}px; row-spacing: ${opt.APP_GRID_SPACING}px;`);
const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
- const dialogMargin = 30;
+ const itemPadding = 55; // default icon item padding on Fedora 44
+ // const dialogMargin = 30;
const nItems = view._orderedItems.length;
let columns = opt.APP_GRID_FOLDER_COLUMNS;
let rows = opt.APP_GRID_FOLDER_ROWS;
+ const fullAdaptiveGrid = !columns && !rows;
let spacing = opt.APP_GRID_SPACING;
- const monitor = global.display.get_monitor_geometry(global.display.get_primary_monitor());
+ const minItemSize = 48 + itemPadding;
- if (!columns && !rows) {
+ if (fullAdaptiveGrid) {
columns = Math.ceil(Math.sqrt(nItems));
rows = columns;
if (columns * (columns - 1) >= nItems) {
@@ -1081,38 +1396,67 @@ const AppFolderDialog = {
}
const iconSize = opt.APP_GRID_FOLDER_ICON_SIZE < 0 ? opt.APP_GRID_FOLDER_ICON_SIZE_DEFAULT : opt.APP_GRID_FOLDER_ICON_SIZE;
- let itemSize = iconSize + 53; // icon padding
+ view._grid.layoutManager.fixedIconSize = iconSize;
+
+ let itemSize = iconSize + 55; // icon padding
// first run sets the grid before we can read the real icon size
// so we estimate the size from default properties
// and correct it in the second run
- if (this._notFirstRun) {
- const [firstItem] = view._grid.layoutManager._container;
+ if (this.realized) {
firstItem.icon.setIconSize(iconSize);
const [firstItemWidth] = firstItem.get_preferred_size();
const realSize = firstItemWidth / scaleFactor;
- if (realSize > iconSize)
+ // if the preferred item size is smaller than icon plus some padding, ignore it
+ // (icons that are not yet realized are returning sizes like 45 or 53)
+ if (realSize > (iconSize + 24))
itemSize = realSize;
- } else {
- this._needsUpdateSize = true;
- this._notFirstRun = true;
}
-
let width = columns * (itemSize + spacing) + /* padding for nav arrows*/64;
- width = Math.round(width + (opt.ORIENTATION || !opt.APP_GRID_FOLDER_COLUMNS ? 100 : 160/* space for navigation arrows*/));
- let height = rows * (itemSize + spacing) + /* header*/75 + /* padding*/100;
+ width = Math.round(width + (opt.ORIENTATION ? 100 : 160/* space for navigation arrows*/));
+ let height = rows * (itemSize + spacing) + /* header*/75 + /* padding*/ 2 * 30 + /* padding + ?page indicator*/(!opt.ORIENTATION || !opt.APP_GRID_FOLDER_COLUMNS ? 100 : 70);
+
+ // allocation is more reliable than appDisplay width/height properties
+ const appDisplayWidth = appDisplay.allocation.x2 - appDisplay.allocation.x1;
+ const appDisplayHeight = appDisplay.allocation.y2 - appDisplay.allocation.y1 + (opt.SHOW_SEARCH_ENTRY ? Main.overview._overview.controls._searchEntryBin.height : 0);
- // folder must fit the primary monitor
+ // folder must fit the appDisplay area
// reduce columns/rows if needed and count with the scaled values
- while (width * scaleFactor > monitor.width - 2 * dialogMargin) {
- width -= itemSize + spacing;
- columns -= 1;
+ if (!opt.APP_GRID_FOLDER_ROWS) {
+ while ((height * scaleFactor) > appDisplayHeight) {
+ height -= itemSize + spacing;
+ rows -= 1;
+ }
+ }
+
+ if (!opt.APP_GRID_FOLDER_COLUMNS) {
+ while ((width * scaleFactor) > appDisplayWidth) {
+ width -= itemSize + spacing;
+ columns -= 1;
+ }
}
- while (height * scaleFactor > monitor.height - 2 * dialogMargin) {
- height -= itemSize + spacing;
- rows -= 1;
+ // try to compensate for the previous reduction if there is a space
+ if (!opt.APP_GRID_FOLDER_COLUMNS) {
+ while ((nItems > columns * rows) && ((width * scaleFactor + itemSize + spacing) <= appDisplayWidth)) {
+ width += itemSize + spacing;
+ columns += 1;
+ }
+ // remove columns that cannot be displayed
+ if ((columns * minItemSize + (columns - 1) * spacing) > appDisplayWidth)
+ columns = Math.floor(appDisplayWidth / (minItemSize + spacing));
}
- width = Math.max(540, width);
+ if (!opt.APP_GRID_FOLDER_ROWS) {
+ while ((nItems > columns * rows) && ((height * scaleFactor + itemSize + spacing) <= appDisplayHeight)) {
+ height += itemSize + spacing;
+ rows += 1;
+ }
+ // remove rows that cannot be displayed
+ if ((rows * minItemSize + (rows - 1) * spacing) > appDisplayHeight)
+ rows = Math.floor(appDisplayWidth / (minItemSize + spacing));
+ }
+
+ width = Math.clamp(width, 640, appDisplayWidth);
+ height = Math.min(height, appDisplayHeight);
const layoutManager = view._grid.layoutManager;
layoutManager.rows_per_page = rows;
@@ -1127,6 +1471,8 @@ const AppFolderDialog = {
padding: 30px;
`);
+ view._grid.layoutManager._pageWidth += 1;
+ view._grid.layoutManager.adaptToSize(view._grid.layoutManager._pageWidth - 1, view._grid.layoutManager._pageHeight);
view._redisplay();
// store original item count
@@ -1145,40 +1491,34 @@ const AppFolderDialog = {
// this. covers the whole screen
let dialogTargetX = dialogX;
let dialogTargetY = dialogY;
- if (!opt.APP_GRID_FOLDER_CENTER) {
- const appDisplay = this._source._parentView;
- dialogTargetX = Math.round(sourceCenterX - this.child.width / 2);
- dialogTargetY = Math.round(sourceCenterY - this.child.height / 2);
+ const appDisplay = this._source._parentView;
+ const [appDisplayX, appDisplayY] = this._source._parentView.get_transformed_position();
- // keep the dialog in appDisplay area if possible
- dialogTargetX = Math.clamp(
- dialogTargetX,
- this.x + appDisplay.x,
- this.x + appDisplay.x + appDisplay.width - this.child.width
- );
+ if (!opt.APP_GRID_FOLDER_CENTER) {
+ dialogTargetX = sourceCenterX - this.child.width / 2;
+ dialogTargetY = sourceCenterY - this.child.height / 2;
- dialogTargetY = Math.clamp(
- dialogTargetY,
- this.y + appDisplay.y,
- this.y + appDisplay.y + appDisplay.height - this.child.height
- );
- // or at least in the monitor area
- const monitor = global.display.get_monitor_geometry(global.display.get_primary_monitor());
+ // keep the dialog in appDisplay area if possible
dialogTargetX = Math.clamp(
dialogTargetX,
- this.x + monitor.x,
- this.x + monitor.x + monitor.width - this.child.width
+ appDisplayX,
+ appDisplayX + appDisplay.width - this.child.width
);
dialogTargetY = Math.clamp(
dialogTargetY,
- this.y + monitor.y,
- this.y + monitor.y + monitor.height - this.child.height
+ appDisplayY,
+ appDisplayY + appDisplay.height - this.child.height
);
+ } else {
+ const searchEntryHeight = opt.SHOW_SEARCH_ENTRY ? Main.overview._overview.controls._searchEntryBin.height : 0;
+ dialogTargetX = appDisplayX + appDisplay.width / 2 - this.child.width / 2;
+ dialogTargetY = appDisplayY - searchEntryHeight + ((appDisplay.height + searchEntryHeight) / 2 - this.child.height / 2) / 2;
}
- const dialogOffsetX = -dialogX + dialogTargetX;
- const dialogOffsetY = -dialogY + dialogTargetY;
+
+ const dialogOffsetX = Math.round(dialogTargetX - dialogX);
+ const dialogOffsetY = Math.round(dialogTargetY - dialogY);
this.child.set({
translation_x: sourceX - dialogX,
@@ -1188,12 +1528,6 @@ const AppFolderDialog = {
opacity: 0,
});
- this.ease({
- background_color: DIALOG_SHADE_NORMAL,
- duration: FOLDER_DIALOG_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
-
this.child.ease({
translation_x: dialogOffsetX,
translation_y: dialogOffsetY,
@@ -1202,17 +1536,22 @@ const AppFolderDialog = {
opacity: 255,
duration: FOLDER_DIALOG_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => {
- // if the folder grid was build with the estimated icon item size because the real size wasn't available
- // rebuild it with the real size now, after the folder was realized
- if (this._needsUpdateSize) {
- this._updateFolderSize();
- this._view._redisplay();
- this._needsUpdateSize = false;
- }
- },
});
+ appDisplay.ease({
+ opacity: 0,
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+
+ if (opt.SHOW_SEARCH_ENTRY) {
+ Main.overview.searchEntry.ease({
+ opacity: 0,
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
this._needsZoomAndFade = false;
if (this._sourceMappedId === 0) {
@@ -1230,17 +1569,20 @@ const AppFolderDialog = {
return;
}
+ // if the dialog was shown silently, skip animation
+ if (this.scale_y < 1) {
+ this._needsZoomAndFade = false;
+ this.hide();
+ this._popdownCallbacks.forEach(func => func());
+ this._popdownCallbacks = [];
+ return;
+ }
+
let [sourceX, sourceY] =
this._source.get_transformed_position();
let [dialogX, dialogY] =
this.child.get_transformed_position();
- this.ease({
- background_color: Clutter.Color.from_pixel(0x00000000),
- duration: FOLDER_DIALOG_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
-
this.child.ease({
translation_x: sourceX - dialogX + this.child.translation_x,
translation_y: sourceY - dialogY + this.child.translation_y,
@@ -1264,11 +1606,35 @@ const AppFolderDialog = {
},
});
+ const appDisplay = this._source._parentView;
+ appDisplay.ease({
+ opacity: 255,
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+
+ if (opt.SHOW_SEARCH_ENTRY) {
+ Main.overview.searchEntry.ease({
+ opacity: 255,
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
this._needsZoomAndFade = false;
},
_setLighterBackground(lighter) {
- const backgroundColor = lighter
+ if (this._isOpen) {
+ const appDisplay = this._source._parentView;
+ appDisplay.ease({
+ opacity: lighter ? 20 : 0,
+ duration: FOLDER_DIALOG_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
+ /* const backgroundColor = lighter
? DIALOG_SHADE_HIGHLIGHT
: DIALOG_SHADE_NORMAL;
@@ -1276,91 +1642,10 @@ const AppFolderDialog = {
backgroundColor,
duration: FOLDER_DIALOG_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
+ }); */
},
};
-// just make app grid to update all invalid positions that may be result of grid/icon size change
-function _updateIconPositions() {
- const appDisplay = Main.overview._overview._controls._appDisplay;
- const icons = [...appDisplay._orderedItems];
- for (let i = 0; i < icons.length; i++)
- appDisplay._moveItem(icons[i], -1, -1);
-}
-
-function _removeIcons() {
- const appDisplay = Main.overview._overview._controls._appDisplay;
- const icons = [...appDisplay._orderedItems];
- for (let i = 0; i < icons.length; i++) {
- const icon = icons[i];
- if (icon._dialog)
- Main.layoutManager.overviewGroup.remove_child(icon._dialog);
- appDisplay._removeItem(icon);
- icon.destroy();
- }
- appDisplay._folderIcons = [];
-}
-
-function _resetAppGrid(settings) {
- const appDisplay = Main.overview._overview._controls._appDisplay;
- // reset the grid only if called directly without args or if all folders where removed by using reset button in Settings window
- // otherwise this function is called every time a user moves icon to another position as a settings callback
- if (settings) {
- const currentValue = JSON.stringify(global.settings.get_value('app-picker-layout').deep_unpack());
- const emptyValue = JSON.stringify([]);
- const customLayout = currentValue !== emptyValue;
- // appDisplay._customLayout = customLayout;
- if (customLayout)
- return;
- else
- opt._appGridNeedsRedisplay = true;
- }
-
- // force update icon size using adaptToSize(). the page size cannot be the same as the current one
- appDisplay._grid.layoutManager._pageWidth += 1;
- appDisplay._grid.layoutManager.adaptToSize(appDisplay._grid.layoutManager._pageWidth - 1, appDisplay._grid.layoutManager._pageHeight);
- _removeIcons();
- appDisplay._redisplay();
- // force appDisplay to move all icons to proper positions and update all properties
- GLib.idle_add(0, () => {
- _updateIconPositions();
- if (appDisplay._sortOrderedItemsAlphabetically) {
- appDisplay._sortOrderedItemsAlphabetically();
- appDisplay._grid.layoutManager._pageWidth += 1;
- appDisplay._grid.layoutManager.adaptToSize(appDisplay._grid.layoutManager._pageWidth - 1, appDisplay._grid.layoutManager._pageHeight);
- appDisplay._setLinearPositions(appDisplay._orderedItems);
- } else {
- appDisplay._removeItem(appDisplay._orderedItems[0]);
- appDisplay._redisplay();
- }
-
- appDisplay._redisplay();
- });
-}
-
-function _getWindowApp(metaWin) {
- const tracker = Shell.WindowTracker.get_default();
- return tracker.get_window_app(metaWin);
-}
-
-function _getAppLastUsedWindow(app) {
- let recentWin;
- global.display.get_tab_list(Meta.TabList.NORMAL_ALL, null).forEach(metaWin => {
- const winApp = _getWindowApp(metaWin);
- if (!recentWin && winApp === app)
- recentWin = metaWin;
- });
- return recentWin;
-}
-
-function _getAppRecentWorkspace(app) {
- const recentWin = _getAppLastUsedWindow(app);
- if (recentWin)
- return recentWin.get_workspace();
-
- return null;
-}
-
const AppIcon = {
after__init() {
// update the app label behavior
@@ -1377,7 +1662,7 @@ const AppIcon = {
return source !== this &&
(source instanceof this.constructor) &&
(view instanceof AppDisplay.AppDisplay &&
- !opt.APP_GRID_ORDER);
+ !opt.APP_GRID_USAGE);
},
};
@@ -1427,7 +1712,7 @@ const AppViewItemCommon = {
// support active preview icons
acceptDrop(source, _actor, x) {
- if (opt.APP_GRID_ORDER)
+ if (opt.APP_GRID_USAGE)
return DND.DragMotionResult.NO_DROP;
this._setHoveringByDnd(false);
@@ -1449,26 +1734,18 @@ const AppViewItemCommon = {
};
-const ActiveFolderIcon = GObject.registerClass(
-class ActiveFolderIcon extends AppDisplay.AppIcon {
- _init(app) {
- super._init(app, {
- setSizeManually: true,
- showLabel: false,
- });
- }
-
+const ActiveFolderIcon = {
handleDragOver() {
return DND.DragMotionResult.CONTINUE;
- }
+ },
acceptDrop() {
return false;
- }
+ },
_onDragEnd() {
this._dragging = false;
this.undoScaleAndFade();
Main.overview.endItemDrag(this._sourceItem.icon);
- }
-});
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/appFavorites.js b/extensions/44/vertical-workspaces/lib/appFavorites.js
new file mode 100644
index 0000000..3efb68c
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/appFavorites.js
@@ -0,0 +1,79 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * appFavorites.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const AppFavorites = imports.ui.appFavorites;
+
+let Me;
+let opt;
+
+var AppFavoritesModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('appFavoritesModule');
+
+ // if notifications are enabled no override is needed
+ reset = reset || !this.moduleEnabled || opt.SHOW_FAV_NOTIFICATION;
+
+ // don't touch original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation) {
+ this.moduleEnabled = false;
+ console.debug(' AppFavoritesModule - Keeping untouched');
+ }
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ // use actual instance instead of prototype
+ this._overrides.addOverride('AppFavorites', AppFavorites.getAppFavorites(), AppFavoritesCommon);
+
+ console.debug(' AppFavoritesModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ console.debug(' AppFavoritesModule - Deactivated');
+ }
+};
+
+const AppFavoritesCommon = {
+ addFavoriteAtPos(appId, pos) {
+ this._addFavorite(appId, pos);
+ },
+
+ removeFavorite(appId) {
+ this._removeFavorite(appId);
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/dash.js b/extensions/44/vertical-workspaces/lib/dash.js
new file mode 100644
index 0000000..17d43ea
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/dash.js
@@ -0,0 +1,1506 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * dash.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022-2023
+ * @license GPL-3.0
+ * modified dash module of https://github.com/RensAlthuis/vertical-overview extension
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+const GLib = imports.gi.GLib;
+const Meta = imports.gi.Meta;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const AltTab = imports.ui.altTab;
+const AppFavorites = imports.ui.appFavorites;
+const AppDisplay = imports.ui.appDisplay;
+const AppMenu = imports.ui.appMenu;
+const BoxPointer = imports.ui.boxpointer;
+const Dash = imports.ui.dash;
+const DND = imports.ui.dnd;
+const IconGrid = imports.ui.iconGrid;
+const Main = imports.ui.main;
+const PopupMenu = imports.ui.popupMenu;
+
+let Me;
+let opt;
+// gettext
+let _;
+
+let _moduleEnabled;
+let _timeouts;
+
+// added values to achieve a better ability to scale down according to available space
+var BaseIconSizes = [16, 24, 32, 40, 44, 48, 56, 64, 72, 80, 96, 112, 128];
+
+const DASH_ITEM_LABEL_SHOW_TIME = 150;
+
+var DashModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _ = Me.gettext;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ this._originalWorkId = null;
+ this._customWorkId = null;
+ this._showAppsIconBtnPressId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ _ = null;
+ }
+
+ update(reset) {
+ this._removeTimeouts();
+
+ this.moduleEnabled = opt.get('dashModule');
+ const conflict = !!(Me.Util.getEnabledExtensions('dash-to-dock').length ||
+ Me.Util.getEnabledExtensions('ubuntu-dock').length ||
+ Me.Util.getEnabledExtensions('dash-to-panel').length);
+
+ if (conflict && !reset)
+ console.warn(`[${Me.metadata.name}] Warning: "Dash" module disabled due to potential conflict with another extension`);
+
+ reset = reset || !this.moduleEnabled || conflict;
+ this._conflict = conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' DashModule - Keeping untouched');
+ }
+
+ updateStyle(dash) {
+ if (opt.DASH_BG_LIGHT)
+ dash._background.add_style_class_name('dash-background-light');
+ else
+ dash._background.remove_style_class_name('dash-background-light');
+
+ dash._background.opacity = opt.DASH_BG_OPACITY;
+ let radius = opt.DASH_BG_RADIUS;
+ if (radius) {
+ let style;
+ switch (opt.DASH_POSITION) {
+ case 1:
+ style = opt.DASH_BG_GS3_STYLE ? `border-radius: ${radius}px 0 0 ${radius}px;` : `border-radius: ${radius}px;`;
+ break;
+ case 3:
+ style = opt.DASH_BG_GS3_STYLE ? `border-radius: 0 ${radius}px ${radius}px 0;` : `border-radius: ${radius}px;`;
+ break;
+ default:
+ style = `border-radius: ${radius}px;`;
+ }
+ dash._background.set_style(style);
+ } else {
+ dash._background.set_style('');
+ }
+ }
+
+ _activateModule() {
+ _moduleEnabled = true;
+ _timeouts = {};
+ const dash = Main.overview._overview._controls.layoutManager._dash;
+
+ if (!this._originalWorkId)
+ this._originalWorkId = dash._workId;
+
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._resetStyle(dash);
+ this.updateStyle(dash);
+
+ this._overrides.addOverride('DashItemContainer', Dash.DashItemContainer.prototype, DashItemContainerCommon);
+ this._overrides.addOverride('DashCommon', Dash.Dash.prototype, DashCommon);
+ this._overrides.addOverride('AppIcon', AppDisplay.AppIcon.prototype, AppIconCommon);
+ this._overrides.addOverride('DashIcon', Dash.DashIcon.prototype, DashIconCommon);
+ this._overrides.addOverride('AppMenu', AppMenu.AppMenu.prototype, AppMenuCommon);
+
+ if (opt.DASH_VERTICAL) {
+ dash.add_style_class_name('vertical');
+ this._setOrientation(Clutter.Orientation.VERTICAL);
+ } else {
+ this._setOrientation(Clutter.Orientation.HORIZONTAL);
+ }
+
+ if (!this._customWorkId)
+ this._customWorkId = Main.initializeDeferredWork(dash._box, dash._redisplay.bind(dash));
+ dash._workId = this._customWorkId;
+
+ this._updateSearchWindowsIcon();
+ this._updateRecentFilesIcon();
+ this._updateExtensionsIcon();
+ this._moveDashAppGridIcon();
+ this._connectShowAppsIcon();
+
+ dash.visible = opt.DASH_VISIBLE;
+ dash._background.add_style_class_name('dash-background-reduced');
+ dash._queueRedisplay();
+
+ if (opt.DASH_ISOLATE_WS && !this._wmSwitchWsConId) {
+ this._wmSwitchWsConId = global.windowManager.connect('switch-workspace', () => dash._queueRedisplay());
+ this._newWindowConId = global.display.connect_after('window-created', () => dash._queueRedisplay());
+ }
+
+ console.debug(' DashModule - Activated');
+ }
+
+ _disableModule() {
+ const dash = Main.overview._overview._controls.layoutManager._dash;
+ this._resetStyle(dash);
+
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ dash._workId = this._originalWorkId;
+
+ if (this._wmSwitchWsConId) {
+ global.windowManager.disconnect(this._wmSwitchWsConId);
+ this._wmSwitchWsConId = 0;
+ }
+ if (this._newWindowConId) {
+ global.windowManager.disconnect(this._newWindowConId);
+ this._newWindowConId = 0;
+ }
+
+ const reset = true;
+ this._setOrientation(Clutter.Orientation.HORIZONTAL);
+ this._moveDashAppGridIcon(reset);
+ this._connectShowAppsIcon(reset);
+ this._updateSearchWindowsIcon(false);
+ this._updateRecentFilesIcon(false);
+ this._updateExtensionsIcon(false);
+ dash.visible = !this._conflict;
+ dash._background.opacity = 255;
+
+ _moduleEnabled = false;
+ console.debug(' DashModule - Disabled');
+ }
+
+ _resetStyle(dash) {
+ dash.remove_style_class_name('vertical');
+ dash.remove_style_class_name('vertical-gs3-left');
+ dash.remove_style_class_name('vertical-gs3-right');
+ dash.remove_style_class_name('vertical-left');
+ dash.remove_style_class_name('vertical-right');
+ dash._background.remove_style_class_name('dash-background-light');
+ dash._background.remove_style_class_name('dash-background-reduced');
+ }
+
+ _removeTimeouts() {
+ if (_timeouts) {
+ Object.values(_timeouts).forEach(t => {
+ if (t)
+ GLib.source_remove(t);
+ });
+ _timeouts = null;
+ }
+ }
+
+ _setOrientation(orientation, dash) {
+ dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
+
+ dash._box.layout_manager.orientation = orientation;
+ dash._dashContainer.layout_manager.orientation = orientation;
+ dash._dashContainer.y_expand = !orientation;
+ dash._dashContainer.x_expand = !!orientation;
+ dash.x_align = orientation ? Clutter.ActorAlign.START : Clutter.ActorAlign.CENTER;
+ dash.y_align = orientation ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.FILL;
+
+ let sizerBox = dash._background.get_children()[0];
+ sizerBox.clear_constraints();
+ sizerBox.add_constraint(new Clutter.BindConstraint({
+ source: dash._showAppsIcon.icon,
+ coordinate: orientation ? Clutter.BindCoordinate.WIDTH : Clutter.BindCoordinate.HEIGHT,
+ }));
+ sizerBox.add_constraint(new Clutter.BindConstraint({
+ source: dash._dashContainer,
+ coordinate: orientation ? Clutter.BindCoordinate.HEIGHT : Clutter.BindCoordinate.WIDTH,
+ }));
+ dash._box.remove_all_children();
+ dash._separator = null;
+ dash._queueRedisplay();
+ dash._adjustIconSize();
+
+ if (orientation && opt.DASH_BG_GS3_STYLE) {
+ if (opt.DASH_LEFT)
+ dash.add_style_class_name('vertical-gs3-left');
+ else if (opt.DASH_RIGHT)
+ dash.add_style_class_name('vertical-gs3-right');
+ } else {
+ dash.remove_style_class_name('vertical-gs3-left');
+ dash.remove_style_class_name('vertical-gs3-right');
+ }
+ }
+
+ _moveDashAppGridIcon(reset = false, dash) {
+ // move dash app grid icon to the front
+ dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
+
+ const appIconPosition = opt.get('showAppsIconPosition');
+ dash._showAppsIcon.remove_style_class_name('show-apps-icon-vertical-hide');
+ dash._showAppsIcon.remove_style_class_name('show-apps-icon-horizontal-hide');
+ dash._showAppsIcon.opacity = 255;
+ if (!reset && appIconPosition === 0) // 0 - start
+ dash._dashContainer.set_child_at_index(dash._showAppsIcon, 0);
+ if (reset || appIconPosition === 1) { // 1 - end
+ const index = dash._dashContainer.get_children().length - 1;
+ dash._dashContainer.set_child_at_index(dash._showAppsIcon, index);
+ }
+ if (!reset && appIconPosition === 2) { // 2 - hide
+ const style = opt.DASH_VERTICAL ? 'show-apps-icon-vertical-hide' : 'show-apps-icon-horizontal-hide';
+ dash._showAppsIcon.add_style_class_name(style);
+ // for some reason even if the icon height in vertical mode should be set to 0 by the style, it stays visible in full size returning height 1px
+ dash._showAppsIcon.opacity = 0;
+ }
+ }
+
+ _connectShowAppsIcon(reset = false, dash) {
+ dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
+ if (!reset) {
+ if (this._showAppsIconBtnPressId || Me.Util.dashIsDashToDock()) {
+ // button is already connected || dash is Dash to Dock
+ return;
+ }
+ dash._showAppsIcon.reactive = true;
+ this._showAppsIconBtnPressId = dash._showAppsIcon.connect('button-press-event', (actor, event) => {
+ const button = event.get_button();
+ if (button === Clutter.BUTTON_MIDDLE)
+ Me.Util.openPreferences();
+ else if (button === Clutter.BUTTON_SECONDARY)
+ Me.Util.activateSearchProvider(Me.WSP_PREFIX);
+ else
+ return Clutter.EVENT_PROPAGATE;
+ return Clutter.EVENT_STOP;
+ });
+ } else if (this._showAppsIconBtnPressId) {
+ dash._showAppsIcon.disconnect(this._showAppsIconBtnPressId);
+ this._showAppsIconBtnPressId = 0;
+ dash._showAppsIcon.reactive = false;
+ }
+ }
+
+ _updateSearchWindowsIcon(show = opt.SHOW_WINDOWS_ICON, dash) {
+ dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
+ const dashContainer = dash._dashContainer;
+
+ if (dash._showWindowsIcon) {
+ dashContainer.remove_child(dash._showWindowsIcon);
+ if (dash._showWindowsIconClickedId) {
+ dash._showWindowsIcon.toggleButton.disconnect(dash._showWindowsIconClickedId);
+ dash._showWindowsIconClickedId = 0;
+ }
+ delete dash._showWindowsIconClickedId;
+ if (dash._showWindowsIcon)
+ dash._showWindowsIcon.destroy();
+ delete dash._showWindowsIcon;
+ }
+
+ if (!show || !opt.get('windowSearchProviderModule'))
+ return;
+
+ if (!dash._showWindowsIcon) {
+ dash._showWindowsIcon = new Dash.DashItemContainer();
+ new Me.Util.Overrides().addOverride('showWindowsIcon', dash._showWindowsIcon, ShowWindowsIcon);
+ dash._showWindowsIcon._afterInit();
+ dash._showWindowsIcon.show(false);
+ dashContainer.add_child(dash._showWindowsIcon);
+ dash._hookUpLabel(dash._showWindowsIcon);
+ }
+
+ dash._showWindowsIcon.icon.setIconSize(dash.iconSize);
+ if (opt.SHOW_WINDOWS_ICON === 1) {
+ dashContainer.set_child_at_index(dash._showWindowsIcon, 0);
+ } else if (opt.SHOW_WINDOWS_ICON === 2) {
+ const index = dashContainer.get_children().length - 1;
+ dashContainer.set_child_at_index(dash._showWindowsIcon, index);
+ }
+
+ Main.overview._overview._controls.layoutManager._dash._adjustIconSize();
+
+ if (dash._showWindowsIcon && !dash._showWindowsIconClickedId) {
+ dash._showWindowsIconClickedId = dash._showWindowsIcon.toggleButton.connect('clicked', () => {
+ Me.Util.activateSearchProvider(Me.WSP_PREFIX);
+ });
+ }
+ }
+
+ _updateRecentFilesIcon(show = opt.SHOW_RECENT_FILES_ICON, dash) {
+ dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
+ const dashContainer = dash._dashContainer;
+
+ if (dash._recentFilesIcon) {
+ dashContainer.remove_child(dash._recentFilesIcon);
+ if (dash._recentFilesIconClickedId) {
+ dash._recentFilesIcon.toggleButton.disconnect(dash._recentFilesIconClickedId);
+ dash._recentFilesIconClickedId = 0;
+ }
+ delete dash._recentFilesIconClickedId;
+ if (dash._recentFilesIcon)
+ dash._recentFilesIcon.destroy();
+ delete dash._recentFilesIcon;
+ }
+
+ if (!show || !opt.get('recentFilesSearchProviderModule'))
+ return;
+
+ if (!dash._recentFilesIcon) {
+ dash._recentFilesIcon = new Dash.DashItemContainer();
+ new Me.Util.Overrides().addOverride('recentFilesIcon', dash._recentFilesIcon, ShowRecentFilesIcon);
+ dash._recentFilesIcon._afterInit();
+ dash._recentFilesIcon.show(false);
+ dashContainer.add_child(dash._recentFilesIcon);
+ dash._hookUpLabel(dash._recentFilesIcon);
+ }
+
+ dash._recentFilesIcon.icon.setIconSize(dash.iconSize);
+ if (opt.SHOW_RECENT_FILES_ICON === 1) {
+ dashContainer.set_child_at_index(dash._recentFilesIcon, 0);
+ } else if (opt.SHOW_RECENT_FILES_ICON === 2) {
+ const index = dashContainer.get_children().length - 1;
+ dashContainer.set_child_at_index(dash._recentFilesIcon, index);
+ }
+
+ Main.overview._overview._controls.layoutManager._dash._adjustIconSize();
+
+ if (dash._recentFilesIcon && !dash._recentFilesIconClickedId) {
+ dash._recentFilesIconClickedId = dash._recentFilesIcon.toggleButton.connect('clicked', () => {
+ Me.Util.activateSearchProvider(Me.RFSP_PREFIX);
+ });
+ }
+ }
+
+ _updateExtensionsIcon(show = opt.SHOW_EXTENSIONS_ICON, dash) {
+ dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
+ const dashContainer = dash._dashContainer;
+
+ if (dash._extensionsIcon) {
+ dashContainer.remove_child(dash._extensionsIcon);
+ if (dash._extensionsIconClickedId) {
+ dash._extensionsIcon.toggleButton.disconnect(dash._extensionsIconClickedId);
+ dash._extensionsIconClickedId = 0;
+ }
+ delete dash._extensionsIconClickedId;
+ if (dash._extensionsIcon)
+ dash._extensionsIcon.destroy();
+ delete dash._extensionsIcon;
+ }
+
+ if (!show || !opt.get('extensionsSearchProviderModule'))
+ return;
+
+ if (!dash._extensionsIcon) {
+ dash._extensionsIcon = new Dash.DashItemContainer();
+ new Me.Util.Overrides().addOverride('extensionsIcon', dash._extensionsIcon, ShowExtensionsIcon);
+ dash._extensionsIcon._afterInit();
+ dash._extensionsIcon.show(false);
+ dashContainer.add_child(dash._extensionsIcon);
+ dash._hookUpLabel(dash._extensionsIcon);
+ }
+
+ dash._extensionsIcon.icon.setIconSize(dash.iconSize);
+ if (opt.SHOW_EXTENSIONS_ICON === 1) {
+ dashContainer.set_child_at_index(dash._extensionsIcon, 0);
+ } else if (opt.SHOW_EXTENSIONS_ICON === 2) {
+ const index = dashContainer.get_children().length - 1;
+ dashContainer.set_child_at_index(dash._extensionsIcon, index);
+ }
+
+ Main.overview._overview._controls.layoutManager._dash._adjustIconSize();
+
+ if (dash._extensionsIcon && !dash._extensionsIconClickedId) {
+ dash._extensionsIconClickedId = dash._extensionsIcon.toggleButton.connect('clicked', () => {
+ Me.Util.activateSearchProvider(Me.ESP_PREFIX);
+ });
+ }
+ }
+};
+
+const DashItemContainerCommon = {
+ // move labels according dash position
+ showLabel() {
+ if (!this._labelText)
+ return;
+
+ const windows = this.child.app?.get_windows();
+ const recentWindowTitle = windows && windows.length ? windows[0].get_title() : '';
+ const windowCount = this.child.app?.get_windows().length;
+ let labelSuffix = '';
+ if (windowCount > 1)
+ labelSuffix = ` (${windowCount})`;
+ if (recentWindowTitle && recentWindowTitle !== this._labelText)
+ labelSuffix += `\n ${recentWindowTitle}`;
+
+
+ this.label.set_text(this._labelText + labelSuffix);
+
+ this.label.opacity = 0;
+ this.label.show();
+
+ let [stageX, stageY] = this.get_transformed_position();
+
+ const itemWidth = this.allocation.get_width();
+ const itemHeight = this.allocation.get_height();
+
+ const labelWidth = this.label.get_width();
+ const labelHeight = this.label.get_height();
+ let xOffset = Math.floor((itemWidth - labelWidth) / 2);
+ let x = Math.clamp(stageX + xOffset, 0, global.stage.width - labelWidth);
+ const primaryMonitor = global.display.get_monitor_geometry(global.display.get_primary_monitor());
+ x = Math.clamp(x, primaryMonitor.x, primaryMonitor.x + primaryMonitor.width - labelWidth);
+
+ let node = this.label.get_theme_node();
+ let y;
+
+ if (opt.DASH_TOP) {
+ const yOffset = 0.75 * itemHeight + 3 * node.get_length('-y-offset');
+ y = stageY + yOffset;
+ } else if (opt.DASH_BOTTOM) {
+ const yOffset = node.get_length('-y-offset');
+ y = stageY - this.label.height - yOffset;
+ } else if (opt.DASH_RIGHT) {
+ const yOffset = Math.floor((itemHeight - labelHeight) / 2);
+ xOffset = 4;
+
+ x = stageX - xOffset - this.label.width;
+ y = Math.clamp(stageY + yOffset, 0, global.stage.height - labelHeight);
+ } else if (opt.DASH_LEFT) {
+ const yOffset = Math.floor((itemHeight - labelHeight) / 2);
+ xOffset = 4;
+
+ x = stageX + this.width + xOffset;
+ y = Math.clamp(stageY + yOffset, 0, global.stage.height - labelHeight);
+ }
+
+ this.label.set_position(x, y);
+ this.label.ease({
+ opacity: 255,
+ duration: DASH_ITEM_LABEL_SHOW_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+
+ this.label.set_position(x, y);
+ this.label.ease({
+ opacity: 255,
+ duration: DASH_ITEM_LABEL_SHOW_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ },
+};
+
+const DashCommon = {
+ _redisplay() {
+ // After disabling V-Shell queueRedisplay() may call this function
+ // In that case redirect the call to the current _redisplay()
+ if (!_moduleEnabled) {
+ this._redisplay();
+ return;
+ }
+
+ let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
+
+ let running = this._appSystem.get_running();
+
+ if (opt.DASH_ISOLATE_WS) {
+ const currentWs = global.workspace_manager.get_active_workspace();
+ running = running.filter(app => {
+ return app.get_windows().filter(w => w.get_workspace() === currentWs).length;
+ });
+ this._box.get_children().forEach(a => a.child?._updateRunningStyle());
+ }
+
+ let children = this._box.get_children().filter(actor => {
+ return actor.child &&
+ actor.child._delegate &&
+ actor.child._delegate.app;
+ });
+ // Apps currently in the dash
+ let oldApps = children.map(actor => actor.child._delegate.app);
+ // Apps supposed to be in the dash
+ let newApps = [];
+
+ for (let id in favorites)
+ newApps.push(favorites[id]);
+
+ for (let i = 0; i < running.length; i++) {
+ let app = running[i];
+ if (app.get_id() in favorites)
+ continue;
+ newApps.push(app);
+ }
+
+ // Figure out the actual changes to the list of items; we iterate
+ // over both the list of items currently in the dash and the list
+ // of items expected there, and collect additions and removals.
+ // Moves are both an addition and a removal, where the order of
+ // the operations depends on whether we encounter the position
+ // where the item has been added first or the one from where it
+ // was removed.
+ // There is an assumption that only one item is moved at a given
+ // time; when moving several items at once, everything will still
+ // end up at the right position, but there might be additional
+ // additions/removals (e.g. it might remove all the launchers
+ // and add them back in the new order even if a smaller set of
+ // additions and removals is possible).
+ // If above assumptions turns out to be a problem, we might need
+ // to use a more sophisticated algorithm, e.g. Longest Common
+ // Subsequence as used by diff.
+ let addedItems = [];
+ let removedActors = [];
+
+ let newIndex = 0;
+ let oldIndex = 0;
+ while (newIndex < newApps.length || oldIndex < oldApps.length) {
+ let oldApp = oldApps.length > oldIndex ? oldApps[oldIndex] : null;
+ let newApp = newApps.length > newIndex ? newApps[newIndex] : null;
+
+ // No change at oldIndex/newIndex
+ if (oldApp === newApp) {
+ oldIndex++;
+ newIndex++;
+ continue;
+ }
+
+ // App removed at oldIndex
+ if (oldApp && !newApps.includes(oldApp)) {
+ removedActors.push(children[oldIndex]);
+ oldIndex++;
+ continue;
+ }
+
+ // App added at newIndex
+ if (newApp && !oldApps.includes(newApp)) {
+ addedItems.push({
+ app: newApp,
+ item: this._createAppItem(newApp),
+ pos: newIndex,
+ });
+ newIndex++;
+ continue;
+ }
+
+ // App moved
+ let nextApp = newApps.length > newIndex + 1
+ ? newApps[newIndex + 1] : null;
+ let insertHere = nextApp && nextApp === oldApp;
+ let alreadyRemoved = removedActors.reduce((result, actor) => {
+ let removedApp = actor.child._delegate.app;
+ return result || removedApp === newApp;
+ }, false);
+
+ if (insertHere || alreadyRemoved) {
+ let newItem = this._createAppItem(newApp);
+ addedItems.push({
+ app: newApp,
+ item: newItem,
+ pos: newIndex + removedActors.length,
+ });
+ newIndex++;
+ } else {
+ removedActors.push(children[oldIndex]);
+ oldIndex++;
+ }
+ }
+
+ for (let i = 0; i < addedItems.length; i++) {
+ this._box.insert_child_at_index(
+ addedItems[i].item,
+ addedItems[i].pos);
+ }
+
+ for (let i = 0; i < removedActors.length; i++) {
+ let item = removedActors[i];
+
+ // Don't animate item removal when the overview is transitioning
+ // or hidden
+ if (Main.overview.visible && !Main.overview.animationInProgress)
+ item.animateOutAndDestroy();
+ else
+ item.destroy();
+ }
+
+ this._adjustIconSize();
+
+ // Skip animations on first run when adding the initial set
+ // of items, to avoid all items zooming in at once
+
+ let animate = this._shownInitially && Main.overview.visible &&
+ !Main.overview.animationInProgress;
+
+ if (!this._shownInitially)
+ this._shownInitially = true;
+
+ for (let i = 0; i < addedItems.length; i++)
+ addedItems[i].item.show(animate);
+
+ // Update separator
+ const nFavorites = Object.keys(favorites).length;
+ const nIcons = children.length + addedItems.length - removedActors.length;
+ if (nFavorites > 0 && nFavorites < nIcons) {
+ // destroy the horizontal separator if it exists.
+ // this is incredibly janky, but I can't think of a better way atm.
+ if (this._separator && this._separator.height !== 1) {
+ this._separator.destroy();
+ this._separator = null;
+ }
+
+ if (!this._separator) {
+ this._separator = new St.Widget({
+ style_class: 'dash-separator',
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.CENTER,
+ width: opt.DASH_VERTICAL ? this.iconSize : 1,
+ height: opt.DASH_VERTICAL ? 1 : this.iconSize,
+ });
+ this._box.add_child(this._separator);
+ }
+
+ // FIXME: separator placement is broken (also in original dash)
+ let pos = nFavorites + this._animatingPlaceholdersCount;
+ if (this._dragPlaceholder)
+ pos++;
+ this._box.set_child_at_index(this._separator, pos);
+ } else if (this._separator) {
+ this._separator.destroy();
+ this._separator = null;
+ }
+ // Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
+ // Without it, StBoxLayout may use a stale size cache
+ this._box.queue_relayout();
+ },
+
+ _createAppItem(app) {
+ let appIcon = new Dash.DashIcon(app);
+
+ let indicator = appIcon._dot;
+ if (opt.DASH_VERTICAL) {
+ indicator.x_align = opt.DASH_LEFT ? Clutter.ActorAlign.START : Clutter.ActorAlign.END;
+ indicator.y_align = Clutter.ActorAlign.CENTER;
+ } else {
+ indicator.x_align = Clutter.ActorAlign.CENTER;
+ indicator.y_align = Clutter.ActorAlign.END;
+ }
+
+ appIcon.connect('menu-state-changed',
+ (o, opened) => {
+ this._itemMenuStateChanged(item, opened);
+ });
+
+ let item = new Dash.DashItemContainer();
+ item.setChild(appIcon);
+
+ // Override default AppIcon label_actor, now the
+ // accessible_name is set at DashItemContainer.setLabelText
+ appIcon.label_actor = null;
+ item.setLabelText(app.get_name());
+
+ appIcon.icon.setIconSize(this.iconSize);
+ this._hookUpLabel(item, appIcon);
+
+ return item;
+ },
+
+ // use custom BaseIconSizes and add support for custom icons
+ _adjustIconSize() {
+ // if a user launches multiple apps at once, this function may be called again before the previous call has finished
+ // as a result, new icons will not reach their full size, or will be missing, if adding a new icon and changing the dash size due to lack of space at the same time
+ if (this._adjustingInProgress)
+ return;
+
+ // For the icon size, we only consider children which are "proper"
+ // icons (i.e. ignoring drag placeholders) and which are not
+ // animating out (which means they will be destroyed at the end of
+ // the animation)
+ let iconChildren = this._box.get_children().filter(actor => {
+ return actor.child &&
+ actor.child._delegate &&
+ actor.child._delegate.icon &&
+ !actor.animatingOut;
+ });
+
+ // add new custom icons to the list
+ if (this._showAppsIcon.visible)
+ iconChildren.push(this._showAppsIcon);
+
+ if (this._showWindowsIcon)
+ iconChildren.push(this._showWindowsIcon);
+
+ if (this._recentFilesIcon)
+ iconChildren.push(this._recentFilesIcon);
+
+ if (this._extensionsIcon)
+ iconChildren.push(this._extensionsIcon);
+
+ if (!iconChildren.length)
+ return;
+
+ if (this._maxWidth === -1 || this._maxHeight === -1)
+ return;
+
+ const dashHorizontal = !opt.DASH_VERTICAL;
+
+ const themeNode = this.get_theme_node();
+ const maxAllocation = new Clutter.ActorBox({
+ x1: 0,
+ y1: 0,
+ x2: dashHorizontal ? this._maxWidth : 42, // not whatever
+ y2: dashHorizontal ? 42 : this._maxHeight,
+ });
+
+ let maxContent = themeNode.get_content_box(maxAllocation);
+
+ let spacing = themeNode.get_length('spacing');
+
+ let firstButton = iconChildren[0].child;
+ let firstIcon = firstButton._delegate.icon;
+
+ if (!firstIcon.icon)
+ return;
+
+ // Enforce valid spacings during the size request
+ firstIcon.icon.ensure_style();
+ const [, , iconWidth, iconHeight] = firstIcon.icon.get_preferred_size();
+ const [, , buttonWidth, buttonHeight] = firstButton.get_preferred_size();
+ let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
+
+ let availWidth, availHeight, maxIconSize;
+ if (dashHorizontal) {
+ availWidth = maxContent.x2 - maxContent.x1;
+ // Subtract icon padding and box spacing from the available width
+ availWidth -= iconChildren.length * (buttonWidth - iconWidth) +
+ (iconChildren.length - 1) * spacing +
+ 2 * this._background.get_theme_node().get_horizontal_padding();
+
+ availHeight = this._maxHeight;
+ availHeight -= this.margin_top + this.margin_bottom;
+ availHeight -= this._background.get_theme_node().get_vertical_padding();
+ availHeight -= themeNode.get_vertical_padding();
+ availHeight -= buttonHeight - iconHeight;
+
+ maxIconSize = Math.min(availWidth / iconChildren.length, availHeight, opt.MAX_ICON_SIZE * scaleFactor);
+ } else {
+ availWidth = this._maxWidth;
+ availWidth -= this._background.get_theme_node().get_horizontal_padding();
+ availWidth -= themeNode.get_horizontal_padding();
+ availWidth -= buttonWidth - iconWidth;
+
+ availHeight = maxContent.y2 - maxContent.y1;
+ availHeight -= iconChildren.length * (buttonHeight - iconHeight) +
+ (iconChildren.length - 1) * spacing +
+ 2 * this._background.get_theme_node().get_vertical_padding();
+
+ maxIconSize = Math.min(availWidth, availHeight / iconChildren.length, opt.MAX_ICON_SIZE * scaleFactor);
+ }
+
+ let iconSizes = BaseIconSizes.map(s => s * scaleFactor);
+
+ let newIconSize = BaseIconSizes[0];
+ for (let i = 0; i < iconSizes.length; i++) {
+ if (iconSizes[i] <= maxIconSize)
+ newIconSize = BaseIconSizes[i];
+ }
+
+ if (newIconSize === this.iconSize)
+ return;
+
+ // set the in-progress state here after all the possible cancels
+ this._adjustingInProgress = true;
+
+ let oldIconSize = this.iconSize;
+ this.iconSize = newIconSize;
+ this.emit('icon-size-changed');
+
+ let scale = oldIconSize / newIconSize;
+ for (let i = 0; i < iconChildren.length; i++) {
+ let icon = iconChildren[i].child._delegate.icon;
+
+ // Set the new size immediately, to keep the icons' sizes
+ // in sync with this.iconSize
+ icon.setIconSize(this.iconSize);
+
+ // Don't animate the icon size change when the overview
+ // is transitioning, not visible or when initially filling
+ // the dash
+ if (!Main.overview.visible || Main.overview.animationInProgress ||
+ !this._shownInitially)
+ continue;
+
+ let [targetWidth, targetHeight] = icon.icon.get_size();
+
+ // Scale the icon's texture to the previous size and
+ // tween to the new size
+ icon.icon.set_size(icon.icon.width * scale,
+ icon.icon.height * scale);
+
+ icon.icon.ease({
+ width: targetWidth,
+ height: targetHeight,
+ duration: Dash.DASH_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
+ if (this._separator) {
+ this._separator.ease({
+ width: dashHorizontal ? 1 : this.iconSize,
+ height: dashHorizontal ? this.iconSize : 1,
+ duration: Dash.DASH_ANIMATION_TIME,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
+ this._adjustingInProgress = false;
+ },
+
+ handleDragOver(source, actor, x, y, _time) {
+ let app = Dash.getAppFromSource(source);
+
+ // Don't allow favoriting of transient apps
+ if (app === null || app.is_window_backed())
+ return DND.DragMotionResult.NO_DROP;
+ if (!global.settings.is_writable('favorite-apps'))
+ return DND.DragMotionResult.NO_DROP;
+ let favorites = AppFavorites.getAppFavorites().getFavorites();
+ let numFavorites = favorites.length;
+
+ let favPos = favorites.indexOf(app);
+
+ let children = this._box.get_children();
+ let numChildren = children.length;
+ let boxSize = opt.DASH_VERTICAL ? this._box.height : this._box.width;
+
+ // Keep the placeholder out of the index calculation; assuming that
+ // the remove target has the same size as "normal" items, we don't
+ // need to do the same adjustment there.
+ if (this._dragPlaceholder) {
+ boxSize -= opt.DASH_VERTICAL ? this._dragPlaceholder.height : this._dragPlaceholder.width;
+ numChildren--;
+ }
+
+ // Same with the separator
+ if (this._separator) {
+ boxSize -= opt.DASH_VERTICAL ? this._separator.height : this._separator.width;
+ numChildren--;
+ }
+
+ let pos;
+ if (this._emptyDropTarget)
+ pos = 0; // always insert at the start when dash is empty
+ else if (this.text_direction === Clutter.TextDirection.RTL)
+ pos = numChildren - Math.floor((opt.DASH_VERTICAL ? y : x) * numChildren / boxSize);
+ else
+ pos = Math.floor((opt.DASH_VERTICAL ? y : x) * numChildren / boxSize);
+
+ // Put the placeholder after the last favorite if we are not
+ // in the favorites zone
+ if (pos > numFavorites)
+ pos = numFavorites;
+
+ if (pos !== this._dragPlaceholderPos && this._animatingPlaceholdersCount === 0) {
+ this._dragPlaceholderPos = pos;
+
+ // Don't allow positioning before or after self
+ if (favPos !== -1 && (pos === favPos || pos === favPos + 1)) {
+ this._clearDragPlaceholder();
+ return DND.DragMotionResult.CONTINUE;
+ }
+
+ // If the placeholder already exists, we just move
+ // it, but if we are adding it, expand its size in
+ // an animation
+ let fadeIn;
+ if (this._dragPlaceholder) {
+ this._dragPlaceholder.destroy();
+ fadeIn = false;
+ } else {
+ fadeIn = true;
+ }
+
+ this._dragPlaceholder = new Dash.DragPlaceholderItem();
+ this._dragPlaceholder.child.set_width(this.iconSize / (opt.DASH_VERTICAL ? 2 : 1));
+ this._dragPlaceholder.child.set_height(this.iconSize / (opt.DASH_VERTICAL ? 1 : 2));
+ this._box.insert_child_at_index(
+ this._dragPlaceholder,
+ this._dragPlaceholderPos);
+ this._dragPlaceholder.show(fadeIn);
+ }
+
+ if (!this._dragPlaceholder)
+ return DND.DragMotionResult.NO_DROP;
+
+ let srcIsFavorite = favPos !== -1;
+
+ if (srcIsFavorite)
+ return DND.DragMotionResult.MOVE_DROP;
+
+ return DND.DragMotionResult.COPY_DROP;
+ },
+};
+
+const DashIconCommon = {
+ after__init() {
+ if (opt.DASH_ICON_SCROLL && !Me.Util.dashNotDefault()) {
+ this._scrollConId = this.connect('scroll-event', DashExtensions.onScrollEvent.bind(this));
+ this._leaveConId = this.connect('leave-event', DashExtensions.onLeaveEvent.bind(this));
+ }
+ },
+
+ popupMenu() {
+ const side = opt.DASH_VERTICAL ? St.Side.LEFT : St.Side.BOTTOM;
+ AppIconCommon.popupMenu.bind(this)(side);
+ },
+
+ _updateRunningStyle() {
+ const currentWs = global.workspace_manager.get_active_workspace();
+ const show = opt.DASH_ISOLATE_WS
+ ? this.app.get_windows().filter(w => w.get_workspace() === currentWs).length
+ : this.app.state !== Shell.AppState.STOPPED;
+
+ if (show)
+ this._dot.show();
+ else
+ this._dot.hide();
+ },
+};
+
+const DashExtensions = {
+ onScrollEvent(source, event) {
+ if ((this.app && !opt.DASH_ICON_SCROLL) || (this._isSearchWindowsIcon && !opt.SEARCH_WINDOWS_ICON_SCROLL)) {
+ if (this._scrollConId) {
+ this.disconnect(this._scrollConId);
+ this._scrollConId = 0;
+ }
+ if (this._leaveConId) {
+ this.disconnect(this._leaveConId);
+ this._leaveConId = 0;
+ }
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ if (Main.overview._overview.controls._stateAdjustment.value > 1)
+ return Clutter.EVENT_PROPAGATE;
+
+ let direction = Me.Util.getScrollDirection(event);
+ if (direction === Clutter.ScrollDirection.UP)
+ direction = 1;
+ else if (direction === Clutter.ScrollDirection.DOWN)
+ direction = -1;
+ else
+ return Clutter.EVENT_STOP;
+
+ // avoid uncontrollable switching if smooth scroll wheel or trackpad is used
+ if (this._lastScroll && Date.now() - this._lastScroll < 160)
+ return Clutter.EVENT_STOP;
+
+ this._lastScroll = Date.now();
+
+ DashExtensions.switchWindow.bind(this)(direction);
+ return Clutter.EVENT_STOP;
+ },
+
+ onLeaveEvent() {
+ if (!this._selectedMetaWin || this.has_pointer || this.toggleButton?.has_pointer)
+ return;
+
+ this._selectedPreview._activateSelected = false;
+ this._selectedMetaWin = null;
+ this._scrolledWindows = null;
+ DashExtensions.showWindowPreview.bind(this)(null);
+ },
+
+
+ switchWindow(direction) {
+ if (!this._scrolledWindows) {
+ this._initialSelection = true;
+ // source is app icon
+ if (this.app) {
+ this._scrolledWindows = this.app.get_windows();
+ if (opt.DASH_ISOLATE_WS) {
+ const currentWs = global.workspaceManager.get_active_workspace();
+ this._scrolledWindows = this._scrolledWindows.filter(w => w.get_workspace() === currentWs);
+ }
+
+ const wsList = [];
+ this._scrolledWindows.forEach(w => {
+ const ws = w.get_workspace();
+ if (!wsList.includes(ws))
+ wsList.push(ws);
+ });
+
+ // sort windows by workspaces in MRU order
+ this._scrolledWindows.sort((a, b) => wsList.indexOf(a.get_workspace()) > wsList.indexOf(b.get_workspace()));
+ // source is Search Windows icon
+ } else if (this._isSearchWindowsIcon) {
+ if (opt.SEARCH_WINDOWS_ICON_SCROLL === 1) // all windows
+ this._scrolledWindows = AltTab.getWindows(null);
+ else
+ this._scrolledWindows = AltTab.getWindows(global.workspace_manager.get_active_workspace());
+ }
+ }
+
+ let windows = this._scrolledWindows;
+
+ if (!windows.length)
+ return;
+
+ // if window selection is in the process, the previewed window must be the current one
+ let currentWin = this._selectedMetaWin ? this._selectedMetaWin : windows[0];
+
+ const currentIdx = windows.indexOf(currentWin);
+ let targetIdx = currentIdx;
+ const focusWindow = AltTab.getWindows(null)[0];
+ const appFocused = this._scrolledWindows[0] === focusWindow && this._scrolledWindows[0].get_workspace() === global.workspace_manager.get_active_workspace();
+ // only if the app has focus, immediately switch to the previous window
+ // otherwise just set the current window above others
+ if (!this._initialSelection || appFocused)
+ targetIdx += direction;
+ else
+ this._initialSelection = false;
+
+ if (targetIdx > windows.length - 1)
+ targetIdx = 0;
+ else if (targetIdx < 0)
+ targetIdx = windows.length - 1;
+
+ const metaWin = windows[targetIdx];
+ DashExtensions.showWindowPreview.bind(this)(metaWin);
+ this._selectedMetaWin = metaWin;
+ },
+
+ showWindowPreview(metaWin) {
+ const views = Main.overview._overview.controls._workspacesDisplay._workspacesViews;
+ const viewsIter = [views[0]];
+ // secondary monitors use different structure
+ views.forEach(v => {
+ if (v._workspacesView)
+ viewsIter.push(v._workspacesView);
+ });
+
+ viewsIter.forEach(view => {
+ // if workspaces are on primary monitor only
+ if (!view || !view._workspaces)
+ return;
+
+ view._workspaces.forEach(ws => {
+ ws._windows.forEach(windowPreview => {
+ // metaWin === null resets opacity
+ let opacity = metaWin ? 50 : 255;
+ windowPreview._activateSelected = false;
+
+ // minimized windows are invisible if windows are not exposed (WORKSPACE_MODE === 0)
+ if (!windowPreview.opacity)
+ windowPreview.opacity = 255;
+
+ // app windows set to lower opacity, so they can be recognized
+ if (this._scrolledWindows && this._scrolledWindows.includes(windowPreview.metaWindow)) {
+ if (opt.DASH_ICON_SCROLL === 2)
+ opacity = 254;
+ }
+ if (windowPreview.metaWindow === metaWin) {
+ if (metaWin && metaWin.get_workspace() !== global.workspace_manager.get_active_workspace()) {
+ Main.wm.actionMoveWorkspace(metaWin.get_workspace());
+ if (_timeouts.wsSwitcherAnimation)
+ GLib.source_remove(_timeouts.wsSwitcherAnimation);
+ // setting window preview above siblings before workspace switcher animation has no effect
+ // we need to set the window above after the ws preview become visible on the screen
+ // the default switcher animation time is 250, 200 ms delay should be enough
+ _timeouts.wsSwitcherAnimation = GLib.timeout_add(0, 200 * St.Settings.get().slow_down_factor, () => {
+ windowPreview.get_parent().set_child_above_sibling(windowPreview, null);
+ _timeouts.wsSwitcherAnimation = 0;
+ return GLib.SOURCE_REMOVE;
+ });
+ } else {
+ windowPreview.get_parent().set_child_above_sibling(windowPreview, null);
+ }
+
+ opacity = 255;
+ this._selectedPreview = windowPreview;
+ windowPreview._activateSelected = true;
+ }
+
+ // if windows are exposed, highlight selected using opacity
+ if ((opt.OVERVIEW_MODE && opt.WORKSPACE_MODE) || !opt.OVERVIEW_MODE) {
+ if (metaWin && opacity === 255)
+ windowPreview.showOverlay(true);
+ else
+ windowPreview.hideOverlay(true);
+ windowPreview.ease({
+ duration: 200,
+ opacity,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+ });
+ });
+ });
+ },
+};
+
+const AppIconCommon = {
+ after__init() {
+ if (this._updateRunningDotStyle)
+ this._updateRunningDotStyle();
+ },
+
+ _updateRunningDotStyle() {
+ if (opt.RUNNING_DOT_STYLE)
+ this._dot.add_style_class_name('app-well-app-running-dot-custom');
+ else
+ this._dot.remove_style_class_name('app-well-app-running-dot-custom');
+ },
+
+ activate(button) {
+ const event = Clutter.get_current_event();
+ const state = event ? event.get_state() : 0;
+ const isMiddleButton = button && button === Clutter.BUTTON_MIDDLE;
+ const isCtrlPressed = Me.Util.isCtrlPressed(state);
+ const isShiftPressed = Me.Util.isShiftPressed(state);
+
+ const currentWS = global.workspace_manager.get_active_workspace();
+ const appRecentWorkspace = this._getAppRecentWorkspace(this.app);
+ // this feature shouldn't affect search results, dash icons don't have labels, so we use them as a condition
+ const showWidowsBeforeActivation = opt.DASH_CLICK_ACTION === 1 && !this.icon.label;
+
+ let targetWindowOnCurrentWs = false;
+ if (opt.DASH_FOLLOW_RECENT_WIN) {
+ targetWindowOnCurrentWs = appRecentWorkspace === currentWS;
+ } else {
+ this.app.get_windows().forEach(
+ w => {
+ targetWindowOnCurrentWs = targetWindowOnCurrentWs || (w.get_workspace() === currentWS);
+ }
+ );
+ }
+
+ const openNewWindow = this.app.can_open_new_window() &&
+ this.app.state === Shell.AppState.RUNNING &&
+ (((isCtrlPressed || isMiddleButton) && !opt.DASH_CLICK_OPEN_NEW_WIN) ||
+ (opt.DASH_CLICK_OPEN_NEW_WIN && !this._selectedMetaWin && !isMiddleButton) ||
+ ((opt.DASH_CLICK_PREFER_WORKSPACE || opt.DASH_ISOLATE_WS) && !targetWindowOnCurrentWs));
+
+ if ((this.app.state === Shell.AppState.STOPPED || openNewWindow) && !isShiftPressed)
+ this.animateLaunch();
+
+ if (openNewWindow) {
+ this.app.open_new_window(-1);
+ // if DASH_CLICK_ACTION == "SHOW_WINS_BEFORE", the app has more than one window and has no window on the current workspace,
+ // don't activate the app immediately, only move the overview to the workspace with the app's recent window
+ } else if (showWidowsBeforeActivation && !isShiftPressed && this.app.get_n_windows() > 1 && !targetWindowOnCurrentWs/* && !(opt.OVERVIEW_MODE && !opt.WORKSPACE_MODE)*/) {
+
+ Main.wm.actionMoveWorkspace(appRecentWorkspace);
+ Main.overview.dash.showAppsButton.checked = false;
+ return;
+ } else if (this._selectedMetaWin) {
+ this._selectedMetaWin.activate(global.get_current_time());
+ } else if (showWidowsBeforeActivation && opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE && !isShiftPressed && this.app.get_n_windows() > 1) {
+ // expose windows
+ Main.overview._overview._controls._thumbnailsBox._activateThumbnailAtPoint(0, 0, global.get_current_time(), true);
+ return;
+ } else if (((opt.DASH_SHIFT_CLICK_MV && isShiftPressed) || ((opt.DASH_CLICK_PREFER_WORKSPACE || opt.DASH_ISOLATE_WS) && !openNewWindow)) && this.app.get_windows().length) {
+ this._moveAppToCurrentWorkspace();
+ if (opt.DASH_ISOLATE_WS) {
+ this.app.activate();
+ // hide the overview after the window is re-created
+ GLib.idle_add(GLib.PRIORITY_LOW, () => Main.overview.hide());
+ }
+ return;
+ } else if (isShiftPressed) {
+ return;
+ } else {
+ this.app.activate();
+ }
+
+ Main.overview.hide();
+ },
+
+ _moveAppToCurrentWorkspace() {
+ this.app.get_windows().forEach(w => w.change_workspace(global.workspace_manager.get_active_workspace()));
+ },
+
+ popupMenu(side = St.Side.LEFT) {
+ this.setForcedHighlight(true);
+ this._removeMenuTimeout();
+ this.fake_release();
+
+ if (!this._getWindowsOnCurrentWs) {
+ this._getWindowsOnCurrentWs = function () {
+ const winList = [];
+ this.app.get_windows().forEach(w => {
+ if (w.get_workspace() === global.workspace_manager.get_active_workspace())
+ winList.push(w);
+ });
+ return winList;
+ };
+
+ this._windowsOnOtherWs = function () {
+ return (this.app.get_windows().length - this._getWindowsOnCurrentWs().length) > 0;
+ };
+ }
+
+ if (!this._menu) {
+ this._menu = new AppMenu.AppMenu(this, side, {
+ favoritesSection: true,
+ showSingleWindows: true,
+ });
+
+ this._menu.setApp(this.app);
+ this._openSigId = this._menu.connect('open-state-changed', (menu, isPoppedUp) => {
+ if (!isPoppedUp)
+ this._onMenuPoppedDown();
+ });
+ // Main.overview.connectObject('hiding',
+ this._hidingSigId = Main.overview.connect('hiding',
+ () => this._menu.close(), this);
+
+ Main.uiGroup.add_actor(this._menu.actor);
+ this._menuManager.addMenu(this._menu);
+ }
+
+ // once the menu is created, it stays unchanged and we need to modify our items based on current situation
+ if (this._addedMenuItems && this._addedMenuItems.length)
+ this._addedMenuItems.forEach(i => i.destroy());
+
+
+ const popupItems = [];
+
+ const separator = new PopupMenu.PopupSeparatorMenuItem();
+ this._menu.addMenuItem(separator);
+
+ if (this.app.get_n_windows()) {
+ // if (/* opt.APP_MENU_FORCE_QUIT*/true) {}
+ popupItems.push([_('Force Quit'), () => {
+ this.app.get_windows()[0].kill();
+ }]);
+
+ // if (opt.APP_MENU_CLOSE_WS) {}
+ const nWin = this._getWindowsOnCurrentWs().length;
+ if (nWin) {
+ popupItems.push([_(`Close ${nWin} Windows on Current Workspace`), () => {
+ const windows = this._getWindowsOnCurrentWs();
+ let time = global.get_current_time();
+ for (let win of windows) {
+ // increase time by 1 ms for each window to avoid errors from GS
+ win.delete(time++);
+ }
+ }]);
+ }
+
+ popupItems.push([_('Move App to Current Workspace ( Shift + Click )'), this._moveAppToCurrentWorkspace]);
+ if (opt.WINDOW_THUMBNAIL_ENABLED) {
+ popupItems.push([_('Create Window Thumbnail - PIP'), () => {
+ Me.Modules.winTmbModule.createThumbnail(this.app.get_windows()[0]);
+ }]);
+ }
+ }
+
+ this._addedMenuItems = [];
+ this._addedMenuItems.push(separator);
+ popupItems.forEach(i => {
+ let item = new PopupMenu.PopupMenuItem(i[0]);
+ this._menu.addMenuItem(item);
+ item.connect('activate', i[1].bind(this));
+ if (i[1] === this._moveAppToCurrentWorkspace && !this._windowsOnOtherWs())
+ item.setSensitive(false);
+ this._addedMenuItems.push(item);
+ });
+
+ this.emit('menu-state-changed', true);
+
+ this._menu.open(BoxPointer.PopupAnimation.FULL);
+ this._menuManager.ignoreRelease();
+ this.emit('sync-tooltip');
+
+ return false;
+ },
+
+ _getWindowApp(metaWin) {
+ const tracker = Shell.WindowTracker.get_default();
+ return tracker.get_window_app(metaWin);
+ },
+
+ _getAppLastUsedWindow(app) {
+ let recentWin;
+ global.display.get_tab_list(Meta.TabList.NORMAL_ALL, null).forEach(metaWin => {
+ const winApp = this._getWindowApp(metaWin);
+ if (!recentWin && winApp === app)
+ recentWin = metaWin;
+ });
+ return recentWin;
+ },
+
+ _getAppRecentWorkspace(app) {
+ const recentWin = this._getAppLastUsedWindow(app);
+ if (recentWin)
+ return recentWin.get_workspace();
+
+ return null;
+ },
+};
+
+const ShowWindowsIcon = {
+ _afterInit() {
+ this._isSearchWindowsIcon = true;
+ this._labelText = _('Search Open Windows (Hotkey: Space)');
+ this.toggleButton = new St.Button({
+ style_class: 'show-apps',
+ track_hover: true,
+ can_focus: true,
+ toggle_mode: false,
+ });
+
+ this._iconActor = null;
+ this.icon = new IconGrid.BaseIcon(this.labelText, {
+ setSizeManually: true,
+ showLabel: false,
+ createIcon: this._createIcon.bind(this),
+ });
+ this.icon.y_align = Clutter.ActorAlign.CENTER;
+
+ this.toggleButton.add_actor(this.icon);
+ this.toggleButton._delegate = this;
+
+ this.setChild(this.toggleButton);
+
+ if (opt.SEARCH_WINDOWS_ICON_SCROLL) {
+ this.reactive = true;
+ this._scrollConId = this.connect('scroll-event', DashExtensions.onScrollEvent.bind(this));
+ this._leaveConId = this.connect('leave-event', DashExtensions.onLeaveEvent.bind(this));
+ }
+ },
+
+ _createIcon(size) {
+ this._iconActor = new St.Icon({
+ icon_name: 'focus-windows-symbolic',
+ icon_size: size,
+ style_class: 'show-apps-icon',
+ track_hover: true,
+ });
+ return this._iconActor;
+ },
+};
+
+const ShowRecentFilesIcon = {
+ _afterInit() {
+ this._labelText = _('Search Recent Files (Hotkey: Ctrl + Space)');
+ this.toggleButton = new St.Button({
+ style_class: 'show-apps',
+ track_hover: true,
+ can_focus: true,
+ toggle_mode: false,
+ });
+
+ this._iconActor = null;
+ this.icon = new IconGrid.BaseIcon(this.labelText, {
+ setSizeManually: true,
+ showLabel: false,
+ createIcon: this._createIcon.bind(this),
+ });
+ this.icon.y_align = Clutter.ActorAlign.CENTER;
+
+ this.toggleButton.add_actor(this.icon);
+ this.toggleButton._delegate = this;
+
+ this.setChild(this.toggleButton);
+ },
+
+ _createIcon(size) {
+ this._iconActor = new St.Icon({
+ icon_name: 'document-open-recent-symbolic',
+ icon_size: size,
+ style_class: 'show-apps-icon',
+ track_hover: true,
+ });
+ return this._iconActor;
+ },
+};
+
+const ShowExtensionsIcon = {
+ _afterInit() {
+ this._labelText = _('Search Extensions (Hotkey: Ctrl + Shift + Space)');
+ this.toggleButton = new St.Button({
+ style_class: 'show-apps',
+ track_hover: true,
+ can_focus: true,
+ toggle_mode: false,
+ });
+
+ this._iconActor = null;
+ this.icon = new IconGrid.BaseIcon(this.labelText, {
+ setSizeManually: true,
+ showLabel: false,
+ createIcon: this._createIcon.bind(this),
+ });
+ this.icon.y_align = Clutter.ActorAlign.CENTER;
+
+ this.toggleButton.add_actor(this.icon);
+ this.toggleButton._delegate = this;
+
+ this.setChild(this.toggleButton);
+ },
+
+ _createIcon(size) {
+ this._iconActor = new St.Icon({
+ icon_name: 'application-x-addon-symbolic',
+ icon_size: size,
+ style_class: 'show-apps-icon',
+ track_hover: true,
+ });
+ return this._iconActor;
+ },
+};
+
+const AppMenuCommon = {
+ _updateWindowsSection() {
+ if (global.compositor) {
+ if (this._updateWindowsLaterId) {
+ const laters = global.compositor.get_laters();
+ laters.remove(this._updateWindowsLaterId);
+ }
+ } else if (this._updateWindowsLaterId) {
+ Meta.later_remove(this._updateWindowsLaterId);
+ }
+
+ this._updateWindowsLaterId = 0;
+
+ this._windowSection.removeAll();
+ this._openWindowsHeader.hide();
+
+ if (!this._app)
+ return;
+
+ const minWindows = this._showSingleWindows ? 1 : 2;
+ const currentWs = global.workspaceManager.get_active_workspace();
+ const isolateWs = opt.DASH_ISOLATE_WS && !Main.overview.dash.showAppsButton.checked;
+ const windows = this._app.get_windows().filter(w => !w.skip_taskbar && (isolateWs ? w.get_workspace() === currentWs : true));
+ if (windows.length < minWindows)
+ return;
+
+ this._openWindowsHeader.show();
+
+ windows.forEach(window => {
+ const title = window.title || this._app.get_name();
+ const item = this._windowSection.addAction(title, event => {
+ Main.activateWindow(window, event.get_time());
+ });
+ window.connectObject('notify::title', () => {
+ item.label.text = window.title || this._app.get_name();
+ }, item);
+ });
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/extensionsSearchProvider.js b/extensions/44/vertical-workspaces/lib/extensionsSearchProvider.js
new file mode 100644
index 0000000..5d0f28a
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/extensionsSearchProvider.js
@@ -0,0 +1,423 @@
+/**
+* V-Shell (Vertical Workspaces)
+ * extensionsSearchProvider.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ */
+
+'use strict';
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const St = imports.gi.St;
+const Shell = imports.gi.Shell;
+const Clutter = imports.gi.Clutter;
+const GObject = imports.gi.GObject;
+
+const Main = imports.ui.main;
+
+const ExtensionState = {
+ 1: 'ENABLED',
+ 2: 'DISABLED',
+ 3: 'ERROR',
+ 4: 'INCOMPATIBLE',
+ 5: 'DOWNLOADING',
+ 6: 'INITIALIZED',
+ 7: 'DISABLING',
+ 8: 'ENABLING',
+};
+
+let Me;
+let opt;
+// gettext
+let _;
+let _toggleTimeout;
+
+// prefix helps to eliminate results from other search providers
+// so it needs to be something less common
+// needs to be accessible from vw module
+const PREFIX = 'eq//';
+
+var ExtensionsSearchProviderModule = class {
+ // export for other modules
+ static _PREFIX = PREFIX;
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _ = Me.gettext;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._extensionsSearchProvider = null;
+ this._enableTimeoutId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ _ = null;
+ }
+
+ update(reset) {
+ if (_toggleTimeout)
+ GLib.source_remove(_toggleTimeout);
+
+ this.moduleEnabled = opt.get('extensionsSearchProviderModule');
+
+ reset = reset || !this.moduleEnabled;
+
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' ExtensionsSearchProviderModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ // delay because Fedora had problem to register a new provider soon after Shell restarts
+ this._enableTimeoutId = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT,
+ 2000,
+ () => {
+ if (!this._extensionsSearchProvider) {
+ this._extensionsSearchProvider = new extensionsSearchProvider(opt);
+ this._getOverviewSearchResult()._registerProvider(this._extensionsSearchProvider);
+ }
+ this._enableTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ console.debug(' ExtensionsSearchProviderModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._enableTimeoutId) {
+ GLib.source_remove(this._enableTimeoutId);
+ this._enableTimeoutId = 0;
+ }
+
+ if (this._extensionsSearchProvider) {
+ this._getOverviewSearchResult()._unregisterProvider(this._extensionsSearchProvider);
+ this._extensionsSearchProvider = null;
+ }
+
+ console.debug(' ExtensionsSearchProviderModule - Disabled');
+ }
+
+ _getOverviewSearchResult() {
+ return Main.overview._overview.controls._searchController._searchResults;
+ }
+};
+
+class extensionsSearchProvider {
+ constructor() {
+ this.id = 'extensions';
+ const appSystem = Shell.AppSystem.get_default();
+ let appInfo = appSystem.lookup_app('com.matjakeman.ExtensionManager.desktop')?.get_app_info();
+ if (!appInfo)
+ appInfo = appSystem.lookup_app('org.gnome.Extensions.desktop')?.get_app_info();
+ if (!appInfo)
+ appInfo = Gio.AppInfo.create_from_commandline('/usr/bin/gnome-extensions-app', 'Extensions', null);
+ appInfo.get_description = () => _('Search extensions');
+ appInfo.get_name = () => _('Extensions');
+ appInfo.get_id = () => 'org.gnome.Extensions.desktop';
+ appInfo.get_icon = () => Gio.icon_new_for_string('application-x-addon');
+ appInfo.should_show = () => true;
+
+ this.appInfo = appInfo;
+ this.canLaunchSearch = true;
+ this.isRemoteProvider = false;
+ }
+
+ getInitialResultSet(terms, callback /* , cancellable = null*/) {
+ // In GS 43 callback arg has been removed
+ /* if (Me.shellVersion >= 43)
+ cancellable = callback; */
+
+ const extensions = {};
+ Main.extensionManager._extensions.forEach(
+ e => {
+ extensions[e.uuid] = e;
+ }
+ );
+ this.extensions = extensions;
+
+ if (Me.shellVersion >= 43)
+ return new Promise(resolve => resolve(this._getResultSet(terms)));
+ else
+ callback(this._getResultSet(terms));
+
+ return null;
+ }
+
+ _getResultSet(terms) {
+ // do not modify original terms
+ let termsCopy = [...terms];
+ // search for terms without prefix
+ termsCopy[0] = termsCopy[0].replace(PREFIX, '');
+
+ const candidates = this.extensions;
+ const _terms = [].concat(termsCopy);
+
+ const term = _terms.join(' ');
+
+ const results = [];
+ let m;
+ for (let id in candidates) {
+ const extension = this.extensions[id];
+ const text = extension.metadata.name + (extension.state === 1 ? 'enabled' : '') + ([6, 2].includes(extension.state) ? 'disabled' : '');
+ if (opt.SEARCH_FUZZY)
+ m = Me.Util.fuzzyMatch(term, text);
+ else
+ m = Me.Util.strictMatch(term, text);
+
+ if (m !== -1)
+ results.push({ weight: m, id });
+ }
+
+ // sort alphabetically
+ results.sort((a, b) => this.extensions[a.id].metadata.name.localeCompare(this.extensions[b.id].metadata.name));
+ // enabled first
+ // results.sort((a, b) => this.extensions[a.id].state !== 1 && this.extensions[b.id].state === 1);
+ // incompatible last
+ results.sort((a, b) => this.extensions[a.id].state === 4 && this.extensions[b.id].state !== 4);
+
+ this.resultIds = results.map(item => item.id);
+ return this.resultIds;
+ }
+
+ getResultMetas(resultIds, callback = null) {
+ const metas = resultIds.map(id => this.getResultMeta(id));
+ if (Me.shellVersion >= 43)
+ return new Promise(resolve => resolve(metas));
+ else if (callback)
+ callback(metas);
+ return null;
+ }
+
+ getResultMeta(resultId) {
+ const result = this.extensions[resultId];
+
+ const versionName = result.metadata['version-name'] ?? '';
+ let version = result.metadata['version'] ?? '';
+ version = versionName && version ? `/${version}` : version;
+ const versionStr = `${versionName}${version}`;
+
+ return {
+ 'id': resultId,
+ 'name': `${result.metadata.name}`,
+ 'version': versionStr,
+ 'description': versionStr, // description will be updated in result object
+ 'createIcon': size => {
+ let icon = this.getIcon(result, size);
+ return icon;
+ },
+ };
+ }
+
+ getIcon(extension, size) {
+ let opacity = 0;
+ let iconName = 'process-stop-symbolic';
+
+ switch (extension.state) {
+ case 1:
+ if (extension.hasUpdate)
+ iconName = 'software-update-available'; // 'software-update-available-symbolic';
+ else
+ iconName = 'object-select';// 'object-select-symbolic';
+
+ opacity = 255;
+ break;
+ case 3:
+ if (Main.extensionManager._enabledExtensions.includes(extension.uuid))
+ iconName = 'emblem-ok-symbolic';
+ else
+ iconName = 'dialog-error';
+ opacity = 100;
+ break;
+ case 4:
+ iconName = 'software-update-urgent'; // 'software-update-urgent-symbolic';
+ opacity = 100;
+ break;
+ }
+
+ if (extension.hasUpdate) {
+ iconName = 'software-update-available'; // 'software-update-available-symbolic';
+ opacity = 100;
+ }
+
+ const icon = new St.Icon({ icon_name: iconName, icon_size: size });
+ icon.set({
+ reactive: true,
+ opacity,
+ });
+
+ return icon;
+ }
+
+ createResultObject(meta) {
+ return new ListSearchResult(this, meta, this.extensions[meta.id]);
+ }
+
+ launchSearch(terms, timeStamp) {
+ this.appInfo.launch([], global.create_app_launch_context(timeStamp, -1), null);
+ }
+
+ activateResult(resultId/* terms, timeStamp*/) {
+ const extension = this.extensions[resultId];
+ if (Me.Util.isShiftPressed())
+ this._toggleExtension(extension);
+ else if (extension.hasPrefs)
+ Me.Util.openPreferences(extension.metadata);
+ }
+
+ filterResults(results /* , maxResults*/) {
+ // return results.slice(0, maxResults);
+ return results;
+ }
+
+ getSubsearchResultSet(previousResults, terms, callback) {
+ if (Me.shellVersion < 43) {
+ this.getSubsearchResultSet42(terms, callback);
+ return null;
+ }
+ return this.getInitialResultSet(terms);
+ }
+
+ getSubsearchResultSet42(terms, callback) {
+ callback(this._getResultSet(terms));
+ }
+}
+
+const ListSearchResult = GObject.registerClass(
+class ListSearchResult extends St.Button {
+ _init(provider, metaInfo, extension) {
+ this.provider = provider;
+ this.metaInfo = metaInfo;
+ this.extension = extension;
+
+ super._init({
+ reactive: true,
+ can_focus: true,
+ track_hover: true,
+ });
+
+ this.style_class = 'list-search-result';
+
+ let content = new St.BoxLayout({
+ style_class: 'list-search-result-content',
+ vertical: false,
+ x_align: Clutter.ActorAlign.START,
+ x_expand: true,
+ y_expand: true,
+ });
+ this.set_child(content);
+
+ let titleBox = new St.BoxLayout({
+ style_class: 'list-search-result-title',
+ y_align: Clutter.ActorAlign.CENTER,
+ });
+
+ content.add_child(titleBox);
+
+ // An icon for, or thumbnail of, content
+ let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
+ let iconBox = new St.Button();
+ iconBox.set_child(icon);
+ titleBox.add(iconBox);
+ iconBox.set_style('border: 1px solid rgba(200,200,200,0.2); padding: 2px; border-radius: 8px;');
+ this._iconBox = iconBox;
+ this.icon = icon;
+
+ iconBox.connect('clicked', () => {
+ this._toggleExtension();
+ return Clutter.EVENT_STOP;
+ });
+
+ let title = new St.Label({
+ text: this.metaInfo['name'],
+ y_align: Clutter.ActorAlign.CENTER,
+ opacity: extension.hasPrefs ? 255 : 150,
+ });
+ titleBox.add_child(title);
+
+ this.label_actor = title;
+
+ this._descriptionLabel = new St.Label({
+ style_class: 'list-search-result-description',
+ y_align: Clutter.ActorAlign.CENTER,
+ });
+ content.add_child(this._descriptionLabel);
+
+ this._highlightTerms();
+
+ this.connect('destroy', () => {
+ if (_toggleTimeout) {
+ GLib.source_remove(_toggleTimeout);
+ _toggleTimeout = 0;
+ }
+ });
+ }
+
+ _toggleExtension() {
+ const state = this.extension.state;
+ if (![1, 2, 6, 3].includes(state) || this.extension.metadata.uuid.includes('vertical-workspaces'))
+ return;
+
+ if ([2, 6].includes(state))
+ Main.extensionManager.enableExtension(this.extension.uuid);
+ else if ([1, 3].includes(state))
+ Main.extensionManager.disableExtension(this.extension.uuid);
+
+ if (_toggleTimeout)
+ GLib.source_remove(_toggleTimeout);
+
+ _toggleTimeout = GLib.timeout_add(GLib.PRIORITY_LOW, 200,
+ () => {
+ if ([7, 8].includes(this.extension.state))
+ return GLib.SOURCE_CONTINUE;
+
+ this.icon?.destroy();
+ this.icon = this.metaInfo['createIcon'](this.ICON_SIZE);
+ this._iconBox.set_child(this.icon);
+ this._highlightTerms();
+
+ _toggleTimeout = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ }
+
+ get ICON_SIZE() {
+ return 24;
+ }
+
+ _highlightTerms() {
+ const extension = this.extension;
+ const state = extension.state === 4 ? ExtensionState[this.extension.state] : '';
+ const error = extension.state === 3 ? ` ERROR: ${this.extension.error}` : '';
+ const update = extension.hasUpdate ? ' | UPDATE PENDING' : '';
+ const text = `${this.metaInfo.version} ${state}${error}${update}`;
+ let markup = text;// this.metaInfo['description'].split('\n')[0];
+ this._descriptionLabel.clutter_text.set_markup(markup);
+ }
+
+ vfunc_clicked() {
+ this.activate();
+ }
+
+ activate() {
+ this.provider.activateResult(this.metaInfo.id);
+
+ if (this.metaInfo.clipboardText) {
+ St.Clipboard.get_default().set_text(
+ St.ClipboardType.CLIPBOARD, this.metaInfo.clipboardText);
+ }
+ Main.overview.toggle();
+ }
+});
diff --git a/extensions/vertical-workspaces/lib/iconGrid.js b/extensions/44/vertical-workspaces/lib/iconGrid.js
index 1aa980e..1f7516b 100644
--- a/extensions/vertical-workspaces/lib/iconGrid.js
+++ b/extensions/44/vertical-workspaces/lib/iconGrid.js
@@ -9,11 +9,13 @@
*/
'use strict';
-const { GLib, St, Meta } = imports.gi;
+
+const St = imports.gi.St;
+
const IconGrid = imports.ui.iconGrid;
-const Me = imports.misc.extensionUtils.getCurrentExtension();
-const _Util = Me.imports.lib.util;
-const shellVersion = _Util.shellVersion;
+
+let Me;
+let opt;
// added sizes for better scaling
const IconSize = {
@@ -29,47 +31,58 @@ const IconSize = {
LARGE: 96,
80: 80,
64: 64,
- 48: 48,
- TINY: 32,
+ TINY: 48,
};
const PAGE_WIDTH_CORRECTION = 100;
-let opt;
-let _overrides;
-let _firstRun = true;
-
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('appDisplayModule', true);
- reset = reset || !moduleEnabled;
+var IconGridModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
- // don't even touch this module if disabled
- if (_firstRun && reset)
- return;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
- _firstRun = false;
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
- if (_overrides)
- _overrides.removeAll();
+ update(reset) {
+ this.moduleEnabled = opt.get('appDisplayModule');
+ // if notifications are enabled no override is needed
+ reset = reset || !this.moduleEnabled;
+
+ // don't touch original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ }
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
- if (reset) {
- _overrides = null;
- opt = null;
- return;
+ if (Me.shellVersion < 43 && IconGridCommon._findBestModeForSize) {
+ IconGridCommon['findBestModeForSize'] = IconGridCommon._findBestModeForSize;
+ delete IconGridCommon['_findBestModeForSize'];
+ }
+ this._overrides.addOverride('IconGrid', IconGrid.IconGrid.prototype, IconGridCommon);
+ this._overrides.addOverride('IconGridLayout', IconGrid.IconGridLayout.prototype, IconGridLayoutCommon);
}
- _overrides = new _Util.Overrides();
-
- if (shellVersion < 43 && IconGridCommon._findBestModeForSize) {
- IconGridCommon['findBestModeForSize'] = IconGridCommon._findBestModeForSize;
- IconGridCommon['_findBestModeForSize'] = undefined;
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
}
- _overrides.addOverride('IconGrid', IconGrid.IconGrid.prototype, IconGridCommon);
- _overrides.addOverride('IconGridLayout', IconGrid.IconGridLayout.prototype, IconGridLayoutCommon);
-}
-// workaround - silence page -2 error on gnome 43 while cleaning app grid
+};
const IconGridCommon = {
getItemsAtPage(page) {
@@ -87,7 +100,7 @@ const IconGridCommon = {
return;
const { pagePadding } = this.layout_manager;
const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
- const iconPadding = 53 * scaleFactor;
+ const iconPadding = 51 * scaleFactor;
// provided width is usually about 100px wider in horizontal orientation with prev/next page indicators
const pageIndicatorCompensation = opt.ORIENTATION ? 0 : PAGE_WIDTH_CORRECTION;
@@ -99,8 +112,13 @@ const IconGridCommon = {
this.layoutManager._gridWidth = width;
this.layoutManager._gridHeight = height;
+ width -= 80; // compensation for default padding
+ height -= 80;
+
const spacing = opt.APP_GRID_SPACING;
- const iconSize = (opt.APP_GRID_ICON_SIZE > 0 ? opt.APP_GRID_ICON_SIZE : opt.APP_GRID_ICON_SIZE_DEFAULT) * scaleFactor;
+ // set the icon size as fixed to avoid changes in size later
+ const iconSize = opt.APP_GRID_ICON_SIZE > 0 ? opt.APP_GRID_ICON_SIZE : opt.APP_GRID_ICON_SIZE_DEFAULT;
+ const itemSize = iconSize * scaleFactor + iconPadding;
// if this._gridModes.length === 1, custom grid should be used
// if (iconSize > 0 && this._gridModes.length > 1) {
let columns = opt.APP_GRID_COLUMNS;
@@ -109,17 +127,20 @@ const IconGridCommon = {
let unusedSpaceH = -1;
let unusedSpaceV = -1;
if (!columns) {
- columns = Math.floor(width / (iconSize + iconPadding)) + 1;
+ // calculate #columns + 1 without spacing
+ columns = Math.floor(width / itemSize) + 1;
+ // check if columns with spacing fits the available width
+ // and reduce the number until it fits
while (unusedSpaceH < 0) {
columns -= 1;
- unusedSpaceH = width - columns * (iconSize + iconPadding) - (columns - 1) * spacing;
+ unusedSpaceH = width - columns * itemSize - (columns - 1) * spacing;
}
}
if (!rows) {
- rows = Math.floor(height / (iconSize + iconPadding)) + 1;
+ rows = Math.floor(height / itemSize) + 1;
while (unusedSpaceV < 0) {
rows -= 1;
- unusedSpaceV = height - rows * (iconSize + iconPadding) - (rows - 1) * spacing;
+ unusedSpaceV = height - rows * itemSize - ((rows - 1) * spacing);
}
}
@@ -135,9 +156,16 @@ const IconGridLayoutCommon = {
const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
const nColumns = this.columnsPerPage;
const nRows = this.rowsPerPage;
+
+ // if grid is not defined return default icon size
+ if (nColumns < 1 && nRows < 1) {
+ return this._isFolder
+ ? opt.APP_GRID_FOLDER_ICON_SIZE_DEFAULT : opt.APP_GRID_ICON_SIZE_DEFAULT;
+ }
+
const columnSpacingPerPage = opt.APP_GRID_SPACING * (nColumns - 1);
const rowSpacingPerPage = opt.APP_GRID_SPACING * (nRows - 1);
- const iconPadding = 53 * scaleFactor;
+ const iconPadding = 55 * scaleFactor;
const paddingH = this._isFolder ? this.pagePadding.left + this.pagePadding.right : 0;
const paddingV = this._isFolder ? this.pagePadding.top + this.pagePadding.bottom : 0;
@@ -156,10 +184,14 @@ const IconGridLayoutCommon = {
return opt.APP_GRID_ICON_SIZE_DEFAULT;*/
let iconSizes = Object.values(IconSize).sort((a, b) => b - a);
-
- // limit max icon size for folders, the whole range is for the main grid with active folders
- if (this._isFolder)
+ // limit max icon size for folders and fully adaptive folder grids, the whole range is for the main grid with active folders
+ if (this._isFolder && opt.APP_GRID_FOLDER_ADAPTIVE && opt.APP_GRID_FOLDER_ICON_SIZE < 0)
+ iconSizes = iconSizes.slice(iconSizes.indexOf(opt.APP_GRID_FOLDER_ICON_SIZE_DEFAULT), -1);
+ else if (this._isFolder)
iconSizes = iconSizes.slice(iconSizes.indexOf(IconSize.LARGE), -1);
+ else if (opt.APP_GRID_ADAPTIVE && opt.APP_GRID_ICON_SIZE < 0)
+ iconSizes = iconSizes.slice(iconSizes.indexOf(opt.APP_GRID_ICON_SIZE_DEFAULT), -1);
+
let sizeInvalid = false;
for (const size of iconSizes) {
@@ -167,10 +199,9 @@ const IconGridLayoutCommon = {
if (firstItem) {
firstItem.icon.setIconSize(size);
- const [firstItemWidth, firstItemHeight] =
- firstItem.get_preferred_size();
+ const [firstItemWidth] = firstItem.get_preferred_size();
- const itemSize = Math.max(firstItemWidth, firstItemHeight);
+ const itemSize = firstItemWidth;
if (itemSize < size)
sizeInvalid = true;
@@ -199,7 +230,7 @@ const IconGridLayoutCommon = {
removeItem(item) {
if (!this._items.has(item)) {
- log(`Item ${item} is not part of the IconGridLayout`);
+ console.error(`Item ${item} is not part of the IconGridLayout`);
return;
// throw new Error(`Item ${item} is not part of the IconGridLayout`);
}
@@ -215,13 +246,13 @@ const IconGridLayoutCommon = {
addItem(item, page = -1, index = -1) {
if (this._items.has(item)) {
- log(`iconGrid: Item ${item} already added to IconGridLayout`);
+ console.error(`iconGrid: Item ${item} already added to IconGridLayout`);
return;
// throw new Error(`Item ${item} already added to IconGridLayout`);
}
if (page > this._pages.length) {
- log(`iconGrid: Cannot add ${item} to page ${page}`);
+ console.error(`iconGrid: Cannot add ${item} to page ${page}`);
page = -1;
index = -1;
// throw new Error(`Cannot add ${item} to page ${page}`);
@@ -240,7 +271,7 @@ const IconGridLayoutCommon = {
moveItem(item, newPage, newPosition) {
if (!this._items.has(item)) {
- log(`iconGrid: Item ${item} is not part of the IconGridLayout`);
+ console.error(`iconGrid: Item ${item} is not part of the IconGridLayout`);
return;
// throw new Error(`Item ${item} is not part of the IconGridLayout`);
}
diff --git a/extensions/vertical-workspaces/lib/layout.js b/extensions/44/vertical-workspaces/lib/layout.js
index f6562fd..6e72645 100644
--- a/extensions/vertical-workspaces/lib/layout.js
+++ b/extensions/44/vertical-workspaces/lib/layout.js
@@ -10,67 +10,107 @@
'use strict';
-const { Meta, GLib, Shell, Clutter, GObject } = imports.gi;
+const GLib = imports.gi.GLib;
+const Meta = imports.gi.Meta;
+const Gio = imports.gi.Gio;
-const Main = imports.ui.main;
const Layout = imports.ui.layout;
-const Ripples = imports.ui.ripples;
-const DND = imports.ui.dnd;
+const Main = imports.ui.main;
-const Me = imports.misc.extensionUtils.getCurrentExtension();
-const _Util = Me.imports.lib.util;
+let Me;
+let opt;
-let _overrides;
let _timeouts;
-let opt;
-let _firstRun = true;
-let _originalUpdateHotCorners;
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('layoutModule', true);
- const conflict = _Util.getEnabledExtensions('custom-hot-corners').length ||
- _Util.getEnabledExtensions('dash-to-panel').length;
- reset = reset || !moduleEnabled;
+var LayoutModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _timeouts = {};
- // don't even touch this module if disabled or in conflict
- if (_firstRun && (reset || conflict))
- return;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ this._originalUpdateHotCorners = null;
+ }
- _firstRun = false;
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this._removeTimeouts();
+
+ this.moduleEnabled = opt.get('layoutModule');
+ const conflict = Me.Util.getEnabledExtensions('custom-hot-corners').length ||
+ Me.Util.getEnabledExtensions('dash-to-panel').length;
- if (!_originalUpdateHotCorners)
- _originalUpdateHotCorners = Layout.LayoutManager.prototype._updateHotCorners;
+ if (conflict && !reset)
+ console.warn(`[${Me.metadata.name}] Warning: "Layout" module disabled due to potential conflict with another extension`);
- if (_overrides)
- _overrides.removeAll();
+ reset = reset || !this.moduleEnabled || conflict;
- if (_timeouts) {
- Object.values(_timeouts).forEach(t => {
- if (t)
- GLib.source_remove(t);
- });
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' LayoutModule - Keeping untouched');
}
- if (reset) {
- _overrides = null;
- opt = null;
- _timeouts = null;
- Main.layoutManager._updateHotCorners = _originalUpdateHotCorners;
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ _timeouts = {};
+
+ this._overrides.addOverride('LayoutManager', Main.layoutManager, LayoutManagerCommon);
+ this._overrides.addOverride('HotCorner', Layout.HotCorner.prototype, HotCornerCommon);
+
+ Main.layoutManager._updatePanelBarrier();
Main.layoutManager._updateHotCorners();
- return;
+
+ if (!this._hotCornersEnabledConId) {
+ this._interfaceSettings = new Gio.Settings({
+ schema_id: 'org.gnome.desktop.interface',
+ });
+ this._hotCornersEnabledConId = this._interfaceSettings.connect('changed::enable-hot-corners',
+ () => Main.layoutManager._updateHotCorners());
+ }
+
+ console.debug(' LayoutModule - Activated');
}
- _timeouts = {};
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
- _overrides = new _Util.Overrides();
- _overrides.addOverride('LayoutManager', Layout.LayoutManager.prototype, LayoutManagerCommon);
+ Main.layoutManager._updateHotCorners();
- Main.layoutManager._updateHotCorners = LayoutManagerCommon._updateHotCorners.bind(Main.layoutManager);
+ if (this._hotCornersEnabledConId) {
+ this._interfaceSettings.disconnect(this._hotCornersEnabledConId);
+ this._hotCornersEnabledConId = 0;
+ this._interfaceSettings = null;
+ }
- Main.layoutManager._updatePanelBarrier();
- Main.layoutManager._updateHotCorners();
-}
+ console.debug(' LayoutModule - Disabled');
+ }
+
+ _removeTimeouts() {
+ if (_timeouts) {
+ Object.values(_timeouts).forEach(t => {
+ if (t)
+ GLib.source_remove(t);
+ });
+ _timeouts = null;
+ }
+ }
+};
const LayoutManagerCommon = {
_updatePanelBarrier() {
@@ -84,7 +124,7 @@ const LayoutManagerCommon = {
this._leftPanelBarrier = null;
}
- if (!this.primaryMonitor || !opt)
+ if (!this.primaryMonitor || !opt || Me.Util.getEnabledExtensions('hidetopbar'))
return;
if (this.panelBox.height) {
@@ -113,6 +153,7 @@ const LayoutManagerCommon = {
// avoid errors if called from foreign override
if (!opt)
return;
+
// destroy old hot corners
this.hotCorners.forEach(corner => corner?.destroy());
this.hotCorners = [];
@@ -122,7 +163,7 @@ const LayoutManagerCommon = {
return;
}
- let size = this.panelBox.height;
+ let size = this.panelBox.height ? this.panelBox.height : 27;
// position 0 - default, 1-TL, 2-TR, 3-BL, 4-BR
const position = opt.HOT_CORNER_POSITION;
@@ -181,8 +222,8 @@ const LayoutManagerCommon = {
}
if (haveCorner) {
- let corner = new HotCorner(this, monitor, cornerX, cornerY);
- corner.setBarrierSize(size);
+ let corner = new Layout.HotCorner(this, monitor, cornerX, cornerY);
+ corner.setBarrierSize(size, false);
this.hotCorners.push(corner);
} else {
this.hotCorners.push(null);
@@ -193,11 +234,8 @@ const LayoutManagerCommon = {
},
};
-var HotCorner = GObject.registerClass(
-class HotCorner extends Layout.HotCorner {
- _init(layoutManager, monitor, x, y) {
- super._init(layoutManager, monitor, x, y);
-
+const HotCornerCommon = {
+ after__init() {
let angle = 0;
switch (opt.HOT_CORNER_POSITION) {
case 2:
@@ -214,9 +252,14 @@ class HotCorner extends Layout.HotCorner {
this._ripples._ripple1.rotation_angle_z = angle;
this._ripples._ripple2.rotation_angle_z = angle;
this._ripples._ripple3.rotation_angle_z = angle;
- }
+ },
+
+ setBarrierSize(size, notMyCall = true) {
+ // ignore calls from the original _updateHotCorners() callback to avoid building barriers outside screen
+ if (notMyCall && size > 0) {
+ return;
+ }
- setBarrierSize(size) {
if (this._verticalBarrier) {
this._pressureBarrier.removeBarrier(this._verticalBarrier);
this._verticalBarrier.destroy();
@@ -232,8 +275,8 @@ class HotCorner extends Layout.HotCorner {
if (size > 0) {
const primaryMonitor = global.display.get_primary_monitor();
const monitor = this._monitor;
- const extendV = opt && opt.HOT_CORNER_EDGE && opt.DASH_VERTICAL && monitor.index === primaryMonitor;
- const extendH = opt && opt.HOT_CORNER_EDGE && !opt.DASH_VERTICAL && monitor.index === primaryMonitor;
+ const extendV = opt && opt.HOT_CORNER_ACTION && opt.HOT_CORNER_EDGE && opt.DASH_VERTICAL && monitor.index === primaryMonitor;
+ const extendH = opt && opt.HOT_CORNER_ACTION && opt.HOT_CORNER_EDGE && !opt.DASH_VERTICAL && monitor.index === primaryMonitor;
if (opt.HOT_CORNER_POSITION <= 1) {
this._verticalBarrier = new Meta.Barrier({
@@ -284,25 +327,52 @@ class HotCorner extends Layout.HotCorner {
this._pressureBarrier.addBarrier(this._verticalBarrier);
this._pressureBarrier.addBarrier(this._horizontalBarrier);
}
- }
+ },
_toggleOverview() {
if (!opt.HOT_CORNER_ACTION || (!opt.HOT_CORNER_FULLSCREEN && this._monitor.inFullscreen && !Main.overview.visible))
return;
if (Main.overview.shouldToggleByCornerOrButton()) {
- if ((opt.HOT_CORNER_ACTION === 1 && !_Util.isCtrlPressed()) || (opt.HOT_CORNER_ACTION === 2 && _Util.isCtrlPressed()))
+ if (Main.overview._shown) {
this._toggleWindowPicker(true);
- else if ((opt.HOT_CORNER_ACTION === 2 && !_Util.isCtrlPressed()) || (opt.HOT_CORNER_ACTION === 1 && _Util.isCtrlPressed()) || (opt.HOT_CORNER_ACTION === 3 && _Util.isCtrlPressed()))
+ } else if ((opt.HOT_CORNER_ACTION === 2 && !Me.Util.isCtrlPressed()) || ([3, 4, 5, 6].includes(opt.HOT_CORNER_ACTION) && Me.Util.isCtrlPressed())) {
+ // Default overview
+ opt.OVERVIEW_MODE = 0;
+ opt.OVERVIEW_MODE2 = false;
+ opt.WORKSPACE_MODE = 1;
+ this._toggleWindowPicker(true, true);
+ } else if (opt.HOT_CORNER_ACTION === 1) {
+ Main.overview.resetOverviewMode();
+ this._toggleWindowPicker(true, true);
+ } else if ((opt.HOT_CORNER_ACTION === 3 && !Me.Util.isCtrlPressed()) || (opt.HOT_CORNER_ACTION === 2 && Me.Util.isCtrlPressed()) || (opt.HOT_CORNER_ACTION === 6 && Me.Util.isCtrlPressed())) {
+ // Applications
this._toggleApplications(true);
- else if (opt.HOT_CORNER_ACTION === 3 && !_Util.isCtrlPressed())
+ } else if (opt.HOT_CORNER_ACTION === 4 && !Me.Util.isCtrlPressed()) {
+ // Overview - static ws preview
+ opt.OVERVIEW_MODE = 1;
+ opt.OVERVIEW_MODE2 = false;
+ opt.WORKSPACE_MODE = 0;
+ this._toggleWindowPicker(true, true);
+ } else if (opt.HOT_CORNER_ACTION === 5 && !Me.Util.isCtrlPressed()) {
+ // Overview - static ws
+ opt.OVERVIEW_MODE = 2;
+ opt.OVERVIEW_MODE2 = true;
+ opt.WORKSPACE_MODE = 0;
+ this._toggleWindowPicker(true, true);
+ } else if (opt.HOT_CORNER_ACTION === 6 && !Me.Util.isCtrlPressed()) {
+ // Window search provider
+ opt.OVERVIEW_MODE = 2;
+ opt.OVERVIEW_MODE2 = true;
+ opt.WORKSPACE_MODE = 0;
this._toggleWindowSearchProvider();
+ }
if (opt.HOT_CORNER_RIPPLES && Main.overview.animationInProgress)
this._ripples.playAnimation(this._x, this._y);
}
- }
+ },
- _toggleWindowPicker(leaveOverview = false) {
+ _toggleWindowPicker(leaveOverview = false, customOverviewMode = false) {
if (Main.overview._shown && (leaveOverview || !Main.overview.dash.showAppsButton.checked)) {
Main.overview.hide();
} else if (Main.overview.dash.showAppsButton.checked) {
@@ -320,17 +390,17 @@ class HotCorner extends Layout.HotCorner {
// delay cannot be too short
200,
() => {
- Main.overview.show();
+ Main.overview.show(1, customOverviewMode);
_timeouts.releaseKeyboardTimeoutId = 0;
return GLib.SOURCE_REMOVE;
}
);
} else {
- Main.overview.show();
+ Main.overview.show(1, customOverviewMode);
}
}
- }
+ },
_toggleApplications(leaveOverview = false) {
if ((leaveOverview && Main.overview._shown) || Main.overview.dash.showAppsButton.checked) {
@@ -360,12 +430,15 @@ class HotCorner extends Layout.HotCorner {
Main.overview.show(2); // 2 for App Grid
}
}
- }
+ },
_toggleWindowSearchProvider() {
if (!Main.overview._overview._controls._searchController._searchActive) {
- this._toggleWindowPicker();
- const prefix = 'wq// ';
+ opt.OVERVIEW_MODE = 2;
+ opt.OVERVIEW_MODE2 = true;
+ opt.WORKSPACE_MODE = 0;
+ this._toggleWindowPicker(false, true);
+ const prefix = Me.WSP_PREFIX;
const position = prefix.length;
const searchEntry = Main.overview.searchEntry;
searchEntry.set_text(prefix);
@@ -376,5 +449,5 @@ class HotCorner extends Layout.HotCorner {
// Main.overview.searchEntry.text = '';
Main.overview.hide();
}
- }
-});
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/messageTray.js b/extensions/44/vertical-workspaces/lib/messageTray.js
new file mode 100644
index 0000000..ef7a51b
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/messageTray.js
@@ -0,0 +1,91 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * messageTray.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+
+const Main = imports.ui.main;
+
+let Me;
+let opt;
+
+var MessageTrayModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('messageTrayModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' MessageTrayModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ this._setNotificationPosition(opt.NOTIFICATION_POSITION);
+
+ console.debug(' MessageTrayModule - Activated');
+ }
+
+ _disableModule() {
+ this._setNotificationPosition(1);
+
+ console.debug(' MessageTrayModule - Disabled');
+ }
+
+ _setNotificationPosition(position) {
+ switch (position) {
+ case 0:
+ Main.messageTray._bannerBin.x_align = Clutter.ActorAlign.START;
+ Main.messageTray._bannerBin.y_align = Clutter.ActorAlign.START;
+ break;
+ case 1:
+ Main.messageTray._bannerBin.x_align = Clutter.ActorAlign.CENTER;
+ Main.messageTray._bannerBin.y_align = Clutter.ActorAlign.START;
+ break;
+ case 2:
+ Main.messageTray._bannerBin.x_align = Clutter.ActorAlign.END;
+ Main.messageTray._bannerBin.y_align = Clutter.ActorAlign.START;
+ break;
+ case 3:
+ Main.messageTray._bannerBin.x_align = Clutter.ActorAlign.START;
+ Main.messageTray._bannerBin.y_align = Clutter.ActorAlign.END;
+ break;
+ case 4:
+ Main.messageTray._bannerBin.x_align = Clutter.ActorAlign.CENTER;
+ Main.messageTray._bannerBin.y_align = Clutter.ActorAlign.END;
+ break;
+ case 5:
+ Main.messageTray._bannerBin.x_align = Clutter.ActorAlign.END;
+ Main.messageTray._bannerBin.y_align = Clutter.ActorAlign.END;
+ break;
+ }
+ }
+};
diff --git a/extensions/vertical-workspaces/lib/optionsFactory.js b/extensions/44/vertical-workspaces/lib/optionsFactory.js
index da62dd1..df6c970 100644
--- a/extensions/vertical-workspaces/lib/optionsFactory.js
+++ b/extensions/44/vertical-workspaces/lib/optionsFactory.js
@@ -9,41 +9,35 @@
'use strict';
-const { Gtk, Gio, GObject } = imports.gi;
+const Adw = imports.gi.Adw;
+const Gtk = imports.gi.Gtk;
+const Gio = imports.gi.Gio;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-const Settings = Me.imports.lib.settings;
-
-const shellVersion = Settings.shellVersion;
+let Me;
// gettext
-const _ = Settings._;
+let _; // = Settings._;
-const ProfileNames = [
- _('GNOME 3'),
- _('GNOME 40+ - Bottom Hot Edge'),
- _('Hot Corner Centric - Top Left Hot Corner'),
- _('Dock Overview - Bottom Hot Edge'),
-];
+function init(me) {
+ Me = me;
+ _ = Me.gettext;
+}
-// libadwaita is available starting with GNOME Shell 42.
-let Adw = null;
-try {
- Adw = imports.gi.Adw;
-} catch (e) {}
+function cleanGlobals() {
+ Me = null;
+ _ = null;
+}
function _newImageFromIconName(name) {
return Gtk.Image.new_from_icon_name(name);
}
var ItemFactory = class ItemFactory {
- constructor(gOptions) {
- this._gOptions = gOptions;
- this._settings = this._gOptions._gsettings;
+ constructor() {
+ this._settings = Me.Opt._gsettings;
}
- getRowWidget(text, caption, widget, variable, options = []) {
+ getRowWidget(text, caption, widget, variable, options = [], dependsOn) {
let item = [];
let label;
if (widget) {
@@ -81,8 +75,8 @@ var ItemFactory = class ItemFactory {
let key;
- if (variable && this._gOptions.options[variable]) {
- const opt = this._gOptions.options[variable];
+ if (variable && Me.Opt.options[variable]) {
+ const opt = Me.Opt.options[variable];
key = opt[1];
}
@@ -95,6 +89,11 @@ var ItemFactory = class ItemFactory {
this._connectComboBox(widget, key, variable, options);
else if (widget._isDropDown)
this._connectDropDown(widget, key, variable, options);
+
+ if (dependsOn) {
+ const dKey = Me.Opt.options[dependsOn][1];
+ this._settings.bind(dKey, widget, 'sensitive', Gio.SettingsBindFlags.GET);
+ }
}
return item;
@@ -111,7 +110,7 @@ var ItemFactory = class ItemFactory {
_connectComboBox(widget, key, variable, options) {
let model = widget.get_model();
widget._comboMap = {};
- const currentValue = this._gOptions.get(variable);
+ const currentValue = Me.Opt.get(variable);
for (const [label, value] of options) {
let iter;
model.set(iter = model.append(), [0, 1], [label, value]);
@@ -120,8 +119,8 @@ var ItemFactory = class ItemFactory {
widget._comboMap[value] = iter;
}
- this._gOptions.connect(`changed::${key}`, () => {
- widget.set_active_iter(widget._comboMap[this._gOptions.get(variable, true)]);
+ Me.Opt.connect(`changed::${key}`, () => {
+ widget.set_active_iter(widget._comboMap[Me.Opt.get(variable, true)]);
});
widget.connect('changed', () => {
const [success, iter] = widget.get_active_iter();
@@ -129,17 +128,17 @@ var ItemFactory = class ItemFactory {
if (!success)
return;
- this._gOptions.set(variable, model.get_value(iter, 1));
+ Me.Opt.set(variable, model.get_value(iter, 1));
});
}
_connectDropDown(widget, key, variable, options) {
const model = widget.get_model();
- const currentValue = this._gOptions.get(variable);
+ const currentValue = Me.Opt.get(variable);
for (let i = 0; i < options.length; i++) {
const text = options[i][0];
const id = options[i][1];
- model.append(new DropDownItem({ text, id }));
+ model.append(new DropDownItemVW({ text, id }));
if (id === currentValue)
widget.set_selected(i);
}
@@ -157,11 +156,11 @@ var ItemFactory = class ItemFactory {
widget.connect('notify::selected-item', dropDown => {
const item = dropDown.get_selected_item();
- this._gOptions.set(variable, item.id);
+ Me.Opt.set(variable, item.id);
});
- this._gOptions.connect(`changed::${key}`, () => {
- const newId = this._gOptions.get(variable, true);
+ Me.Opt.connect(`changed::${key}`, () => {
+ const newId = Me.Opt.get(variable, true);
for (let i = 0; i < options.length; i++) {
const id = options[i][1];
if (id === newId)
@@ -214,7 +213,7 @@ var ItemFactory = class ItemFactory {
newDropDown() {
const dropDown = new Gtk.DropDown({
model: new Gio.ListStore({
- item_type: DropDownItem,
+ item_type: DropDownItemVW,
}),
halign: Gtk.Align.END,
valign: Gtk.Align.CENTER,
@@ -255,11 +254,11 @@ var ItemFactory = class ItemFactory {
newLinkButton(uri) {
const linkBtn = new Gtk.LinkButton({
- label: shellVersion < 42 ? 'Click Me!' : '',
uri,
halign: Gtk.Align.END,
valign: Gtk.Align.CENTER,
hexpand: true,
+ icon_name: 'emblem-symbolic-link',
});
return linkBtn;
}
@@ -298,18 +297,23 @@ var ItemFactory = class ItemFactory {
entry.set_text(opt.get(`profileName${profileIndex}`));
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, 'edit-clear-symbolic');
entry.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, true);
- entry.connect('icon-press', e => e.set_text(''));
- entry.connect('changed', e => opt.set(`profileName${profileIndex}`, e.get_text()));
const resetProfile = this.newButton();
resetProfile.set({
tooltip_text: _('Reset profile to defaults'),
- icon_name: 'edit-delete-symbolic',
+ icon_name: 'document-revert-symbolic',
hexpand: false,
css_classes: ['destructive-action'],
});
function setName() {
+ const ProfileNames = [
+ _('GNOME 3'),
+ _('GNOME 40+ - Bottom Hot Edge'),
+ _('Hot Corner Centric - Top Left Hot Corner'),
+ _('Dock Overview - Bottom Hot Edge'),
+ ];
+
let name = opt.get(`profileName${profileIndex}`, true);
if (!name)
name = ProfileNames[profileIndex - 1];
@@ -317,6 +321,10 @@ var ItemFactory = class ItemFactory {
}
setName();
+
+ entry.connect('icon-press', e => e.set_text(''));
+ entry.connect('changed', e => opt.set(`profileName${profileIndex}`, e.get_text()));
+
resetProfile.connect('clicked', () => {
reset(profileIndex);
setName();
@@ -366,7 +374,7 @@ var ItemFactory = class ItemFactory {
valign: Gtk.Align.CENTER,
hexpand: true,
css_classes: ['destructive-action'],
- icon_name: 'edit-delete-symbolic',
+ icon_name: 'document-revert-symbolic',
});
btn.connect('clicked', () => {
@@ -382,7 +390,7 @@ var ItemFactory = class ItemFactory {
var AdwPrefs = class {
constructor(gOptions) {
- this._gOptions = gOptions;
+ Me.Opt = gOptions;
}
getFilledWindow(window, pages) {
@@ -457,158 +465,9 @@ var AdwPrefs = class {
}
};
-var LegacyPrefs = class {
- constructor(gOptions) {
- this._gOptions = gOptions;
- }
-
- getPrefsWidget(pages) {
- const prefsWidget = new Gtk.Box({
- orientation: Gtk.Orientation.VERTICAL,
- });
- const stack = new Gtk.Stack({
- hexpand: true,
- });
- const stackSwitcher = new Gtk.StackSwitcher({
- halign: Gtk.Align.CENTER,
- hexpand: true,
- });
-
- const context = stackSwitcher.get_style_context();
- context.add_class('caption');
-
- stackSwitcher.set_stack(stack);
- stack.set_transition_duration(300);
- stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT);
-
- const pageProperties = {
- hscrollbar_policy: Gtk.PolicyType.NEVER,
- vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
- vexpand: true,
- hexpand: true,
- visible: true,
- };
-
- const pagesBtns = [];
-
- for (let page of pages) {
- const name = page.name;
- const title = page.title;
- const iconName = page.iconName;
- const optionList = page.optionList;
-
- stack.add_named(this._getLegacyPage(optionList, pageProperties), name);
- pagesBtns.push(
- [new Gtk.Label({ label: title }), _newImageFromIconName(iconName, Gtk.IconSize.BUTTON)]
- );
- }
-
- let stBtn = stackSwitcher.get_first_child ? stackSwitcher.get_first_child() : null;
- for (let i = 0; i < pagesBtns.length; i++) {
- const box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 6, visible: true });
- const icon = pagesBtns[i][1];
- icon.margin_start = 30;
- icon.margin_end = 30;
- box.append(icon);
- box.append(pagesBtns[i][0]);
- if (stackSwitcher.get_children) {
- stBtn = stackSwitcher.get_children()[i];
- stBtn.add(box);
- } else {
- stBtn.set_child(box);
- stBtn.visible = true;
- stBtn = stBtn.get_next_sibling();
- }
- }
-
- if (stack.show_all)
- stack.show_all();
- if (stackSwitcher.show_all)
- stackSwitcher.show_all();
-
- prefsWidget.append(stack);
-
- if (prefsWidget.show_all)
- prefsWidget.show_all();
-
- prefsWidget._stackSwitcher = stackSwitcher;
-
- return prefsWidget;
- }
-
- _getLegacyPage(optionList, pageProperties) {
- const page = new Gtk.ScrolledWindow(pageProperties);
- const mainBox = new Gtk.Box({
- orientation: Gtk.Orientation.VERTICAL,
- spacing: 5,
- homogeneous: false,
- margin_start: 30,
- margin_end: 30,
- margin_top: 12,
- margin_bottom: 12,
- });
-
- let context = page.get_style_context();
- context.add_class('background');
-
- let frame;
- let frameBox;
- for (let item of optionList) {
- // label can be plain text for Section Title
- // or GtkBox for Option
- const option = item[0];
- const widget = item[1];
-
- if (!widget) {
- const lbl = new Gtk.Label({
- label: option,
- xalign: 0,
- margin_bottom: 4,
- });
-
- context = lbl.get_style_context();
- context.add_class('heading');
-
- mainBox.append(lbl);
-
- frame = new Gtk.Frame({
- margin_bottom: 16,
- });
-
- frameBox = new Gtk.ListBox({
- selection_mode: null,
- });
-
- mainBox.append(frame);
- frame.set_child(frameBox);
- continue;
- }
-
- const grid = new Gtk.Grid({
- column_homogeneous: false,
- column_spacing: 20,
- margin_start: 8,
- margin_end: 8,
- margin_top: 8,
- margin_bottom: 8,
- hexpand: true,
- });
-
- grid.attach(option, 0, 0, 5, 1);
-
- if (widget)
- grid.attach(widget, 5, 0, 2, 1);
-
- frameBox.append(grid);
- }
- page.set_child(mainBox);
-
- return page;
- }
-};
-
-const DropDownItem = GObject.registerClass({
- GTypeName: 'DropdownItem',
+const { GObject } = imports.gi;
+const DropDownItemVW = GObject.registerClass({
+ GTypeName: 'DropDownItemVW',
Properties: {
'text': GObject.ParamSpec.string(
'text',
@@ -622,10 +481,11 @@ const DropDownItem = GObject.registerClass({
'Id',
'Item id stored in settings',
GObject.ParamFlags.READWRITE,
- 0, 100, 0
+ // min, max, default
+ -2147483648, 2147483647, 0
),
},
-}, class DropDownItem extends GObject.Object {
+}, class DropDownItemVW extends GObject.Object {
get text() {
return this._text;
}
@@ -641,5 +501,4 @@ const DropDownItem = GObject.registerClass({
set id(id) {
this._id = id;
}
-}
-);
+});
diff --git a/extensions/44/vertical-workspaces/lib/osdWindow.js b/extensions/44/vertical-workspaces/lib/osdWindow.js
new file mode 100644
index 0000000..4699ddf
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/osdWindow.js
@@ -0,0 +1,118 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * osdWindow.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+
+const Main = imports.ui.main;
+const OsdWindow = imports.ui.osdWindow;
+
+let Me;
+let opt;
+
+let OsdPositions;
+
+var OsdWindowModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+
+ OsdPositions = {
+ 1: {
+ x_align: Clutter.ActorAlign.START,
+ y_align: Clutter.ActorAlign.START,
+ },
+ 2: {
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.START,
+ },
+ 3: {
+ x_align: Clutter.ActorAlign.END,
+ y_align: Clutter.ActorAlign.START,
+ },
+ 4: {
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.CENTER,
+ },
+ 5: {
+ x_align: Clutter.ActorAlign.START,
+ y_align: Clutter.ActorAlign.END,
+ },
+ 6: {
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.END,
+ },
+ 7: {
+ x_align: Clutter.ActorAlign.END,
+ y_align: Clutter.ActorAlign.END,
+ },
+ };
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ OsdPositions = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('osdWindowModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' OsdWindowModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._overrides.addOverride('osdWindow', OsdWindow.OsdWindow.prototype, OsdWindowCommon);
+ console.debug(' OsdWindowModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+ this._updateExistingOsdWindows(6);
+
+ console.debug(' WorkspaceSwitcherPopupModule - Disabled');
+ }
+
+ _updateExistingOsdWindows(position) {
+ position = position ? position : opt.OSD_POSITION;
+ Main.osdWindowManager._osdWindows.forEach(osd => {
+ osd.set(OsdPositions[position]);
+ });
+ }
+};
+
+const OsdWindowCommon = {
+ after_show() {
+ if (!opt.OSD_POSITION)
+ this.opacity = 0;
+ this.set(OsdPositions[opt.OSD_POSITION]);
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/overlayKey.js b/extensions/44/vertical-workspaces/lib/overlayKey.js
new file mode 100644
index 0000000..815abaa
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/overlayKey.js
@@ -0,0 +1,168 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * overlayKey.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Meta = imports.gi.Meta;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+const Overview = imports.ui.overview;
+
+let Me;
+let opt;
+
+var OverlayKeyModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._originalOverlayKeyHandlerId = 0;
+ this._overlayKeyHandlerId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('overlayKeyModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' OverlayKeyModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._originalOverlayKeyHandlerId) {
+ this._originalOverlayKeyHandlerId = GObject.signal_handler_find(global.display, { signalId: 'overlay-key' });
+ if (this._originalOverlayKeyHandlerId !== null) {
+ global.display.block_signal_handler(this._originalOverlayKeyHandlerId);
+ this._connectOverlayKey();
+ }
+ }
+ console.debug(' OverlayKeyModule - Activated');
+ }
+
+ _disableModule() {
+ this._restoreOverlayKeyHandler();
+
+ console.debug(' OverlayKeyModule - Disabled');
+ }
+
+ _restoreOverlayKeyHandler() {
+ // Disconnect modified overlay key handler
+ if (this._overlayKeyHandlerId) {
+ global.display.disconnect(this._overlayKeyHandlerId);
+ this._overlayKeyHandlerId = 0;
+ }
+
+ // Unblock original overlay key handler
+ if (this._originalOverlayKeyHandlerId) {
+ global.display.unblock_signal_handler(this._originalOverlayKeyHandlerId);
+ this._originalOverlayKeyHandlerId = 0;
+ }
+ }
+
+ _connectOverlayKey() {
+ if (this._overlayKeyHandlerId)
+ return;
+
+ this._overlayKeyHandlerId = global.display.connect('overlay-key', this._onOverlayKeyPressed.bind(Main.overview._overview.controls));
+ }
+
+ _onOverlayKeyPressed() {
+ if (this._a11ySettings.get_boolean('stickykeys-enable'))
+ return;
+
+ const { initialState, finalState, transitioning } =
+ this._stateAdjustment.getStateTransitionParams();
+
+ const time = GLib.get_monotonic_time() / 1000;
+ const timeDiff = time - this._lastOverlayKeyTime;
+ this._lastOverlayKeyTime = time;
+
+ const shouldShift = St.Settings.get().enable_animations
+ ? transitioning && finalState > initialState
+ : Main.overview.visible && timeDiff < Overview.ANIMATION_TIME;
+
+ const mode = opt.OVERLAY_KEY_SECONDARY;
+ if (shouldShift) {
+ Me.Util.activateSearchProvider('');
+ if (mode === 1) {
+ this._shiftState(Meta.MotionDirection.UP);
+ } else if (mode === 2) {
+ Me.Util.activateSearchProvider(Me.WSP_PREFIX);
+ } else if (mode === 3) {
+ // Changing the overview mode automatically changes the overview transition
+ opt.OVERVIEW_MODE = 0;
+ opt.OVERVIEW_MODE2 = false;
+ opt.WORKSPACE_MODE = 1;
+ }
+ } else {
+ if (Main.overview._shown) {
+ Main.overview.hide();
+ return;
+ }
+ switch (opt.OVERLAY_KEY_PRIMARY) {
+ case 0: // Disabled
+ return;
+ case 1: // Follow global overview mode
+ Main.overview.resetOverviewMode();
+ break;
+ case 2: // Default overview
+ opt.OVERVIEW_MODE = 0;
+ opt.OVERVIEW_MODE2 = false;
+ opt.WORKSPACE_MODE = 1;
+ break;
+ case 3: // Default overview
+ if (Main.overview._shown)
+ Main.overview.hide();
+ else
+ Main.overview.show(2);
+ return;
+ case 4: // Static WS preview
+ opt.OVERVIEW_MODE = 1;
+ opt.OVERVIEW_MODE2 = false;
+ if (!Main.overview._shown)
+ opt.WORKSPACE_MODE = 0;
+ break;
+ case 5: // Static WS
+ opt.OVERVIEW_MODE = 2;
+ opt.OVERVIEW_MODE2 = true;
+ opt.WORKSPACE_MODE = 0;
+ break;
+ case 6: // Window Search
+ opt.OVERVIEW_MODE = 2;
+ opt.OVERVIEW_MODE2 = true;
+ if (!Main.overview._shown)
+ opt.WORKSPACE_MODE = 0;
+ break;
+ }
+ const customOverviewMode = !Main.overview._shown;
+ Main.overview.toggle(customOverviewMode);
+ if (opt.OVERLAY_KEY_PRIMARY === 6)
+ Me.Util.activateSearchProvider(Me.WSP_PREFIX);
+ }
+ }
+};
diff --git a/extensions/44/vertical-workspaces/lib/overview.js b/extensions/44/vertical-workspaces/lib/overview.js
new file mode 100644
index 0000000..833fc58
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/overview.js
@@ -0,0 +1,165 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * overview.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Main = imports.ui.main;
+const Overview = imports.ui.overview;
+const OverviewControls = imports.ui.overviewControls;
+
+let Me;
+let opt;
+
+var OverviewModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = true;
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' OverviewModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._overrides.addOverride('Overview', Overview.Overview.prototype, OverviewCommon);
+ console.debug(' OverviewModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ console.debug(' OverviewModule - Disabled');
+ }
+};
+
+const OverviewCommon = {
+ show(state = OverviewControls.ControlsState.WINDOW_PICKER, customOverviewMode) {
+ if (!customOverviewMode)
+ this.resetOverviewMode();
+
+ if (state === OverviewControls.ControlsState.HIDDEN)
+ throw new Error('Invalid state, use hide() to hide');
+
+ if (this.isDummy)
+ return;
+ if (this._shown)
+ return;
+ this._shown = true;
+
+ if (!this._syncGrab())
+ return;
+
+ Main.layoutManager.showOverview();
+ this._animateVisible(state);
+ },
+
+ toggle(customOverviewMode) {
+ if (this.isDummy)
+ return;
+
+ if (this._visible)
+ this.hide();
+ else
+ this.show(OverviewControls.ControlsState.WINDOW_PICKER, customOverviewMode);
+ },
+
+ resetOverviewMode() {
+ // reset Overview Mode do default
+ opt.OVERVIEW_MODE = opt.get('overviewMode');
+ opt.OVERVIEW_MODE2 = opt.OVERVIEW_MODE === 2;
+ opt.WORKSPACE_MODE = opt.OVERVIEW_MODE > 0 ? 0 : 1;
+ },
+
+ _showDone() {
+ this._animationInProgress = false;
+ this._coverPane.hide();
+
+ if (Me.shellVersion < 44)
+ this.emit('shown');
+ else if (this._shownState !== 'SHOWN')
+ this._changeShownState('SHOWN');
+
+ // Handle any calls to hide* while we were showing
+ if (!this._shown)
+ this._animateNotVisible();
+
+ // if user activates overview during startup animation, transition needs to be shifted to the state 2 here
+ const controls = this._overview._controls;
+ if (controls._searchController._searchActive && controls._stateAdjustment.value === 1) {
+ if (opt.SEARCH_VIEW_ANIMATION)
+ controls._onSearchChanged();
+ else if (!opt.OVERVIEW_MODE2)
+ controls._stateAdjustment.value = 2;
+ }
+
+ this._syncGrab();
+ },
+
+ // Workaround - should probably be fixed elsewhere in the upstream code
+ // If a new window is opened from the overview
+ // and is realized before the overview animation is complete,
+ // the new window will not get focus
+ after__hideDone() {
+ if (!opt.FIX_NEW_WINDOW_FOCUS)
+ return;
+
+ const workspace = global.workspace_manager.get_active_workspace();
+ const recentDesktopWin = global.display.get_tab_list(1, workspace)[0];
+ let recentNormalWin = null;
+ const tabList = global.display.get_tab_list(0, workspace);
+
+ for (let i = 0; i < tabList.length; i++) {
+ if (tabList[i].minimized === false) {
+ recentNormalWin = tabList[i];
+ break;
+ }
+ }
+
+ let recentWin = recentNormalWin;
+ if (recentNormalWin && recentDesktopWin) {
+ recentWin = recentNormalWin.get_user_time() > recentDesktopWin.get_user_time()
+ ? recentNormalWin
+ : recentDesktopWin;
+ }
+
+ const focusedWin = global.display.focus_window;
+
+ if (recentWin && focusedWin !== recentWin)
+ recentWin.activate(global.get_current_time());
+ },
+};
+
diff --git a/extensions/vertical-workspaces/lib/overviewControls.js b/extensions/44/vertical-workspaces/lib/overviewControls.js
index 4959b83..7528682 100644
--- a/extensions/vertical-workspaces/lib/overviewControls.js
+++ b/extensions/44/vertical-workspaces/lib/overviewControls.js
@@ -10,90 +10,148 @@
'use strict';
-const { Clutter, GLib, GObject, St } = imports.gi;
+const Clutter = imports.gi.Clutter;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Meta = imports.gi.Meta;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const Background = imports.ui.background;
+const Layout = imports.ui.layout;
const Main = imports.ui.main;
-const Util = imports.misc.util;
+const Overview = imports.ui.overview;
const OverviewControls = imports.ui.overviewControls;
+const Workspace = imports.ui.workspace;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
+const WorkspacesView = imports.ui.workspacesView;
+const Util = imports.misc.util;
-const ControlsState = imports.ui.overviewControls.ControlsState;
-const FitMode = imports.ui.workspacesView.FitMode;
-
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-
-const _Util = Me.imports.lib.util;
-
-let _overrides;
+let Me;
let opt;
+// gettext
+let _;
+
+const ControlsState = OverviewControls.ControlsState;
+const FitMode = WorkspacesView.FitMode;
-const ANIMATION_TIME = imports.ui.overview.ANIMATION_TIME;
+const ANIMATION_TIME = Overview.ANIMATION_TIME;
const DASH_MAX_SIZE_RATIO = 0.25;
let _originalSearchControllerSigId;
let _searchControllerSigId;
let _timeouts;
-let _startupInitComplete = false;
-function update(reset = false) {
- if (_overrides)
- _overrides.removeAll();
+var OverviewControlsModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _ = Me.gettext;
- if (_timeouts) {
- Object.values(_timeouts).forEach(id => {
- if (id)
- GLib.source_remove(id);
- });
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
}
- _replaceOnSearchChanged(reset);
-
- if (reset) {
- _overrides = null;
+ cleanGlobals() {
+ Me = null;
opt = null;
- _timeouts = null;
- return;
+ _ = null;
}
- _timeouts = {};
+ update(reset) {
+ this._removeTimeouts();
+ this.moduleEnabled = true;
+ const conflict = false;
- opt = Me.imports.lib.settings.opt;
- _overrides = new _Util.Overrides();
+ reset = reset || !this.moduleEnabled || conflict;
- _overrides.addOverride('ControlsManager', OverviewControls.ControlsManager.prototype, ControlsManager);
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' OverviewControlsModule - Keeping untouched');
+ }
- if (opt.ORIENTATION === Clutter.Orientation.VERTICAL)
- _overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutVertical);
- else
- _overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutHorizontal);
-}
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ _timeouts = {};
+
+ this._replaceOnSearchChanged();
+
+ this._overrides.addOverride('ControlsManager', OverviewControls.ControlsManager.prototype, ControlsManagerCommon);
+
+ if (opt.ORIENTATION === Clutter.Orientation.VERTICAL)
+ this._overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutVertical);
+ else
+ this._overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutHorizontal);
+
+ // if DtD is enabled, we need to replace _prepareStartupAnimation() to minimize the mess in the overview
+ // const dashToDockEnabled = Me.Util.getEnabledExtensions('dash-to-dock').length ||
+ // Me.Util.getEnabledExtensions('ubuntu-dock').length;
+ // if (dashToDockEnabled)
+ this._overrides.addOverride('LayoutManagerDtD', Layout.LayoutManager.prototype, LayoutManager);
+
+ console.debug(' OverviewControlsModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ const reset = true;
+ this._replaceOnSearchChanged(reset);
+ Main.overview._overview._controls._appDisplay.opacity = 255;
-function _replaceOnSearchChanged(reset = false) {
- const searchController = Main.overview._overview.controls._searchController;
- if (reset) {
- if (_searchControllerSigId) {
- searchController.disconnect(_searchControllerSigId);
- _searchControllerSigId = 0;
+ console.debug(' OverviewControlsModule - Disabled');
+ }
+
+ _removeTimeouts() {
+ if (_timeouts) {
+ Object.values(_timeouts).forEach(t => {
+ if (t)
+ GLib.source_remove(t);
+ });
+ _timeouts = null;
}
- if (_originalSearchControllerSigId) {
- searchController.unblock_signal_handler(_originalSearchControllerSigId);
- _originalSearchControllerSigId = 0;
+ }
+
+ _replaceOnSearchChanged(reset) {
+ const searchController = Main.overview._overview.controls._searchController;
+ if (reset) {
+ if (_searchControllerSigId) {
+ searchController.disconnect(_searchControllerSigId);
+ _searchControllerSigId = 0;
+ }
+ if (_originalSearchControllerSigId) {
+ searchController.unblock_signal_handler(_originalSearchControllerSigId);
+ _originalSearchControllerSigId = 0;
+ }
+ Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_x = 0;
+ Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_y = 0;
+ Main.overview.searchEntry.visible = true;
+ Main.overview.searchEntry.opacity = 255;
+ } else {
+ // reconnect signal to use custom function (callbacks cannot be overridden in class prototype, they are already in memory as a copy for the given callback)
+ if (!_originalSearchControllerSigId)
+ _originalSearchControllerSigId = GObject.signal_handler_find(searchController, { signalId: 'notify', detail: 'search-active' });
+ if (_originalSearchControllerSigId)
+ searchController.block_signal_handler(_originalSearchControllerSigId);
+
+ if (!_searchControllerSigId)
+ _searchControllerSigId = searchController.connect('notify::search-active', ControlsManagerCommon._onSearchChanged.bind(Main.overview._overview.controls));
}
- Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_x = 0;
- Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_y = 0;
- Main.overview.searchEntry.visible = true;
- Main.overview.searchEntry.opacity = 255;
- } else {
- // reconnect signal to use custom function (callbacks cannot be overridden in class prototype, they are already in memory as a copy for the given callback)
- _originalSearchControllerSigId = GObject.signal_handler_find(searchController, { signalId: 'notify', detail: 'search-active' });
- if (_originalSearchControllerSigId)
- searchController.block_signal_handler(_originalSearchControllerSigId);
-
- _searchControllerSigId = searchController.connect('notify::search-active', ControlsManager._onSearchChanged.bind(Main.overview._overview.controls));
}
-}
+};
-const ControlsManager = {
+const ControlsManagerCommon = {
// this function is used as a callback by a signal handler, needs to be reconnected after modification as the original callback uses a copy of the original function
/* _update: function() {
...
@@ -105,16 +163,21 @@ const ControlsManager = {
},
_updateThumbnailsBox() {
+ const { currentState } = this._stateAdjustment.getStateTransitionParams();
const { shouldShow } = this._thumbnailsBox;
- const thumbnailsBoxVisible = shouldShow;
+ const thumbnailsBoxVisible = shouldShow &&
+ ((currentState < ControlsState.APP_GRID && opt.SHOW_WS_TMB) ||
+ (currentState > ControlsState.WINDOW_PICKER && opt.SHOW_WS_TMB_APPGRID) ||
+ (currentState > ControlsState.WINDOW_PICKER && this._searchController.searchActive && opt.SHOW_WS_TMB)
+ );
this._thumbnailsBox.visible = thumbnailsBoxVisible;
// this call should be directly in _update(), but it's used as a callback function and it would require to reconnect the signal
- this._updateWorkspacesDisplay();
+ this._updateOverview();
},
// this function is pure addition to the original code and handles wsDisp transition to APP_GRID view
- _updateWorkspacesDisplay() {
+ _updateOverview() {
this._workspacesDisplay.translation_x = 0;
this._workspacesDisplay.translation_y = 0;
this._workspacesDisplay.scale_x = 1;
@@ -167,18 +230,21 @@ const ControlsManager = {
ws._background.opacity = opacity;
}
+ if (opt.WORKSPACE_MODE)
+ Workspace.WINDOW_PREVIEW_MAXIMUM_SCALE = 0.95;
+
// if ws preview background is disabled, animate tmb box and dash
const tmbBox = this._thumbnailsBox;
const dash = this.dash;
const searchEntryBin = this._searchEntryBin;
// this dash transition collides with startup animation and freezes GS for good, needs to be delayed (first Main.overview 'hiding' event enables it)
- const skipDash = _Util.dashNotDefault();
+ const skipDash = Me.Util.dashNotDefault();
// OVERVIEW_MODE 2 should animate dash and wsTmbBox only if WORKSPACE_MODE === 0 (windows not spread)
const animateOverviewMode2 = opt.OVERVIEW_MODE2 && !(finalState === 1 && opt.WORKSPACE_MODE);
if (!Main.layoutManager._startingUp && ((!opt.SHOW_WS_PREVIEW_BG && !opt.OVERVIEW_MODE2) || animateOverviewMode2)) {
if (!tmbBox._translationOriginal || Math.abs(tmbBox._translationOriginal[0]) > 500) { // swipe gesture can call this calculation before tmbBox is finalized, giving nonsense width
- const [tmbTranslationX, tmbTranslationY, dashTranslationX, dashTranslationY, searchTranslationY] = _Util.getOverviewTranslations(opt, dash, tmbBox, searchEntryBin);
+ const [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY] = this._getOverviewTranslations(dash, tmbBox, searchEntryBin);
tmbBox._translationOriginal = [tmbTranslationX, tmbTranslationY];
dash._translationOriginal = [dashTranslationX, dashTranslationY];
searchEntryBin._translationOriginal = searchTranslationY;
@@ -229,7 +295,7 @@ const ControlsManager = {
// set searchEntry above appDisplay
this.set_child_above_sibling(this._searchEntryBin, null);
// move dash above wsTmb for case that dash and wsTmb animate from the same side
- if (!_Util.dashNotDefault())
+ if (!Me.Util.dashNotDefault())
this.set_child_above_sibling(dash, null);
this.set_child_below_sibling(this._thumbnailsBox, null);
this.set_child_below_sibling(this._workspacesDisplay, null);
@@ -238,7 +304,7 @@ const ControlsManager = {
// set dash above workspace in the overview
this.set_child_above_sibling(this._thumbnailsBox, null);
this.set_child_above_sibling(this._searchEntryBin, null);
- if (!_Util.dashNotDefault())
+ if (!Me.Util.dashNotDefault())
this.set_child_above_sibling(this.dash, null);
this.dash._isAbove = true;
@@ -247,6 +313,7 @@ const ControlsManager = {
this.set_child_above_sibling(this._workspacesDisplay, null);
this.dash._isAbove = false;
}
+
},
// fix for upstream bug - appGrid.visible after transition from APP_GRID to HIDDEN
@@ -258,12 +325,6 @@ const ControlsManager = {
if (this.dash.showAppsButton.checked)
this._searchTransition = false;
- // update App Grid after settings changed
- // only if the App Grid is currently visible on the screen, the paging updates correctly
- if (currentState === ControlsState.APP_GRID && this._appDisplay.visible && opt._appGridNeedsRedisplay) {
- Me.imports.lib.appDisplay._updateAppGridProperties();
- opt._appGridNeedsRedisplay = false;
- }
// if !APP_GRID_ANIMATION, appGrid needs to be hidden in WINDOW_PICKER mode (1)
// but needs to be visible for transition from HIDDEN (0) to APP_GRID (2)
this._appDisplay.visible =
@@ -305,11 +366,19 @@ const ControlsManager = {
this._workspacesDisplay.reactive = true;
this._workspacesDisplay.setPrimaryWorkspaceVisible(true);
} else {
+ if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)
+ this._searchController._searchResults._statusText.add_style_class_name('search-statustext-om2');
+ else
+ this._searchController._searchResults._statusText.remove_style_class_name('search-statustext-om2');
this._searchController.show();
entry.visible = true;
entry.opacity = 255;
+ // avoid awkward ws scale animation during search activation
+ WorkspaceThumbnail.RESCALE_ANIMATION_TIME = 0;
}
+ if (opt.SHOW_BG_IN_OVERVIEW && this._bgManagers)
+ this._updateBackground(this._bgManagers[0]);
this._searchTransition = true;
this._searchController._searchResults.translation_x = 0;
@@ -317,34 +386,33 @@ const ControlsManager = {
this._searchController.opacity = 255;
this._searchController.visible = true;
- if (opt.SEARCH_VIEW_ANIMATION && !this.dash.showAppsButton.checked && ![4, 8].includes(opt.WS_TMB_POSITION) /* && !opt.OVERVIEW_MODE2*/) {
+ if (opt.SEARCH_VIEW_ANIMATION && ![4, 8].includes(opt.WS_TMB_POSITION) /* && !opt.OVERVIEW_MODE2*/) {
this._updateAppDisplayVisibility();
+ this.layoutManager._searchController._searchResults._statusBin.opacity = 1;
this._searchController.opacity = searchActive ? 255 : 0;
let translationX = 0;
let translationY = 0;
const geometry = global.display.get_monitor_geometry(global.display.get_primary_monitor());
- if (currentState < ControlsState.APP_GRID) {
- switch (opt.SEARCH_VIEW_ANIMATION) {
- case 1:
- // make it longer to cover the delay before results appears
- translationX = geometry.width;
- translationY = 0;
- break;
- case 2:
- translationX = -geometry.width;
- translationY = 0;
- break;
- case 3:
- translationX = 0;
- translationY = geometry.height;
- break;
- case 5:
- translationX = 0;
- translationY = -geometry.height;
- break;
- }
+ switch (opt.SEARCH_VIEW_ANIMATION) {
+ case 1:
+ // make it longer to cover the delay before results appears
+ translationX = geometry.width;
+ translationY = 0;
+ break;
+ case 2:
+ translationX = -geometry.width;
+ translationY = 0;
+ break;
+ case 3:
+ translationX = 0;
+ translationY = geometry.height;
+ break;
+ case 5:
+ translationX = 0;
+ translationY = -geometry.height;
+ break;
}
if (searchActive) {
@@ -363,6 +431,8 @@ const ControlsManager = {
onComplete: () => {
this._searchController.visible = searchActive;
this._searchTransition = false;
+ this.layoutManager._searchController._searchResults._statusBin.opacity = 255;
+ WorkspaceThumbnail.RESCALE_ANIMATION_TIME = 200;
},
});
@@ -372,7 +442,10 @@ const ControlsManager = {
opacity: searchActive || currentState < 2 ? 0 : 255,
duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => this._updateAppDisplayVisibility(),
+ onComplete: () => {
+ this._updateAppDisplayVisibility();
+ WorkspaceThumbnail.RESCALE_ANIMATION_TIME = 200;
+ },
});
// this._updateAppDisplayVisibility();
@@ -390,7 +463,7 @@ const ControlsManager = {
this._searchController.opacity = searchActive ? 0 : 255;
this._searchController.ease({
opacity: searchActive ? 255 : 0,
- duration: searchActive ? SIDE_CONTROLS_ANIMATION_TIME * 2 : 0,
+ duration: searchActive ? SIDE_CONTROLS_ANIMATION_TIME : 0,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => (this._searchController.visible = searchActive),
});
@@ -398,14 +471,16 @@ const ControlsManager = {
// reuse already tuned overview transition, just replace APP_GRID with the search view
if (!(opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) && !Main.overview._animationInProgress && finalState !== ControlsState.HIDDEN && !this.dash.showAppsButton.checked) {
- Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-om2');
+ Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-bg-om2');
+ Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-bg');
Main.overview.searchEntry.remove_style_class_name('search-entry-om2');
+ const duration = opt.SEARCH_VIEW_ANIMATION ? 150 : 0;
this._stateAdjustment.ease(searchActive ? ControlsState.APP_GRID : ControlsState.WINDOW_PICKER, {
// shorter animation time when entering search view can avoid stuttering in transition
// collecting search results take some time and the problematic part is the realization of the object on the screen
// if the ws animation ends before this event, the whole transition is smoother
// removing the ws transition (duration: 0) seems like the best solution here
- duration: searchActive || (opt.OVERVIEW_MODE && !opt.WORKSPACE_MODE) ? 80 : SIDE_CONTROLS_ANIMATION_TIME,
+ duration: searchActive ? duration : SIDE_CONTROLS_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this._workspacesDisplay.setPrimaryWorkspaceVisible(!searchActive);
@@ -413,18 +488,20 @@ const ControlsManager = {
});
} else if (opt.OVERVIEW_MODE2 && !(opt.WORKSPACE_MODE || this.dash.showAppsButton.checked)) {
// add background to search results and make searchEntry border thicker for better visibility
- Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-om2');
+ Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-bg');
+ Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-bg-om2');
Main.overview.searchEntry.add_style_class_name('search-entry-om2');
} else {
- Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-om2');
+ Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-bg');
+ Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-bg-om2');
Main.overview.searchEntry.remove_style_class_name('search-entry-om2');
}
},
async runStartupAnimation(callback) {
this._ignoreShowAppsButtonToggle = true;
- this._searchController.prepareToEnterOverview();
- this._workspacesDisplay.prepareToEnterOverview();
+
+ this.prepareToEnterOverview();
this._stateAdjustment.value = ControlsState.HIDDEN;
this._stateAdjustment.ease(ControlsState.WINDOW_PICKER, {
@@ -436,16 +513,20 @@ const ControlsManager = {
this._ignoreShowAppsButtonToggle = false;
// Set the opacity here to avoid a 1-frame flicker
- this.opacity = 0;
+ this.opacity = 1;
+ this._appDisplay.opacity = 1;
// We can't run the animation before the first allocation happens
await this.layout_manager.ensureAllocation();
- const { STARTUP_ANIMATION_TIME } = imports.ui.layout;
+ this._setBackground();
+ Main.panel.opacity = 255;
+
+ const { STARTUP_ANIMATION_TIME } = Layout;
// Opacity
this.ease({
- opacity: 255,
+ opacity: opt.STARTUP_STATE === 1 ? 0 : 255,
duration: STARTUP_ANIMATION_TIME,
mode: Clutter.AnimationMode.LINEAR,
onComplete: () => {
@@ -465,53 +546,24 @@ const ControlsManager = {
}
const searchEntryBin = this._searchEntryBin;
- const [tmbTranslationX, tmbTranslationY, dashTranslationX, dashTranslationY, searchTranslationY] =
- _Util.getOverviewTranslations(opt, dash, tmbBox, searchEntryBin);
+ const [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY] =
+ this._getOverviewTranslations(dash, tmbBox, searchEntryBin);
const onComplete = function () {
// running init callback again causes issues (multiple connections)
- if (!_startupInitComplete)
+ if (!Main.overview._startupInitComplete)
callback();
- _startupInitComplete = true;
-
- // force app grid to build before the first visible animation to remove possible stuttering
- this._appDisplay.opacity = 1;
-
- const [x, y] = this._appDisplay.get_position();
- const translationX = -x;
- const translationY = -y;
- this._appDisplay.translation_x = translationX;
- this._appDisplay.translation_y = translationY;
- GLib.idle_add(0, () => {
- this._appDisplay._removeItem(this._appDisplay._orderedItems[0]);
- this._appDisplay._redisplay();
- });
- // let the main loop realize previous changes before continuing
- _timeouts.startupAnim1 = GLib.timeout_add(
- GLib.PRIORITY_DEFAULT,
- 10,
- () => {
- GLib.idle_add(0, () => {
- this._appDisplay._removeItem(this._appDisplay._orderedItems[0]);
- this._appDisplay._redisplay();
- });
- this._appDisplay.translation_x = 0;
- this._appDisplay.translation_y = 0;
- this._appDisplay.visible = false;
- if (opt.STARTUP_STATE === 1) {
- Main.overview.hide();
- } else if (opt.STARTUP_STATE === 2) {
- this._appDisplay.opacity = 255;
- this.dash.showAppsButton.checked = true;
- }
- _timeouts.startupAnim1 = 0;
- return GLib.SOURCE_REMOVE;
- }
- );
+ const appDisplayModule = Me.Modules.appDisplayModule;
+ if (!appDisplayModule.moduleEnabled)
+ this._finishStartupSequence();
+ else
+ this._realizeAppDisplayAndFinishSequence();
+
+ Main.overview._startupInitComplete = true;
}.bind(this);
- if (dash.visible && !_Util.dashNotDefault()) {
+ if (dash.visible && !Me.Util.dashNotDefault()) {
dash.translation_x = dashTranslationX;
dash.translation_y = dashTranslationY;
dash.opacity = 255;
@@ -521,9 +573,7 @@ const ControlsManager = {
delay: STARTUP_ANIMATION_TIME / 2,
duration: STARTUP_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => {
- onComplete();
- },
+ onComplete,
});
} else {
// set dash opacity to make it visible if user enable it later
@@ -535,6 +585,7 @@ const ControlsManager = {
STARTUP_ANIMATION_TIME * 2 * St.Settings.get().slow_down_factor,
() => {
onComplete();
+ Main.overview._startupInitComplete = true;
_timeouts.startupAnim2 = 0;
return GLib.SOURCE_REMOVE;
}
@@ -571,7 +622,6 @@ const ControlsManager = {
if (view._monitorIndex !== global.display.get_primary_monitor() && view._thumbnails.visible) {
const secTmbBox = view._thumbnails;
- _Util.getOverviewTranslations(opt, dash, secTmbBox, searchEntryBin);
if (opt.SEC_WS_TMB_LEFT)
secTmbBox.translation_x = -(secTmbBox.width + 12); // compensate for padding
else if (opt.SEC_WS_TMB_RIGHT)
@@ -594,13 +644,129 @@ const ControlsManager = {
}
},
+ _realizeAppDisplayAndFinishSequence() {
+ const appDisplayModule = Me.Modules.appDisplayModule;
+ // realize app grid for smoother first animation
+ appDisplayModule._updateAppGrid(false, this._finishStartupSequence.bind(this));
+ },
+
+ _finishStartupSequence(priority = GLib.PRIORITY_LOW) {
+ if (!this._bgManagers)
+ this._setBackground();
+
+ _timeouts.finishStartup = GLib.idle_add(
+ priority, () => {
+ this._appDisplay.opacity = 255;
+ if (opt.STARTUP_STATE === 1) {
+ Main.overview.hide();
+ } else if (opt.STARTUP_STATE === 2) {
+ Main.overview.show(2); // just because of DtD, because we skipped startup animation
+ this.dash.showAppsButton.checked = true;
+ } else if (!opt.STARTUP_STATE && Me.Util.dashNotDefault()) {
+ Main.overview.show();
+ }
+
+ _timeouts.finishStartup = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+ },
+
+ setInitialTranslations() {
+ const dash = this.dash;
+ const tmbBox = this._thumbnailsBox;
+ const searchEntryBin = this._searchEntryBin;
+ const [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY] =
+ this._getOverviewTranslations(dash, tmbBox, searchEntryBin);
+ if (!Me.Util.dashNotDefault()) {
+ dash.translation_x = dashTranslationX;
+ dash.translation_y = dashTranslationY;
+ }
+ tmbBox.translation_x = tmbTranslationX;
+ tmbBox.translation_y = tmbTranslationY;
+ searchEntryBin.translation_y = searchTranslationY;
+ },
+
+ _getOverviewTranslations(dash, tmbBox, searchEntryBin) {
+ // const tmbBox = Main.overview._overview._controls._thumbnailsBox;
+ const animationsDisabled = !St.Settings.get().enable_animations || (opt.SHOW_WS_PREVIEW_BG && !opt.OVERVIEW_MODE2);
+ if (animationsDisabled)
+ return [0, 0, 0, 0, 0];
+
+ let searchTranslationY = 0;
+ if (searchEntryBin.visible) {
+ const offset = (dash.visible && (!opt.DASH_VERTICAL ? dash.height + 12 : 0)) +
+ (opt.WS_TMB_TOP ? tmbBox.height + 12 : 0);
+ searchTranslationY = -searchEntryBin.height - offset - 30;
+ }
+
+ let tmbTranslationX = 0;
+ let tmbTranslationY = 0;
+ let offset;
+ if (tmbBox.visible) {
+ const tmbWidth = tmbBox.width === Infinity ? 0 : tmbBox.width;
+ const tmbHeight = tmbBox.height === Infinity ? 0 : tmbBox.height;
+ switch (opt.WS_TMB_POSITION) {
+ case 3: // left
+ offset = 10 + (dash?.visible && opt.DASH_LEFT ? dash.width : 0);
+ tmbTranslationX = -tmbWidth - offset;
+ tmbTranslationY = 0;
+ break;
+ case 1: // right
+ offset = 10 + (dash?.visible && opt.DASH_RIGHT ? dash.width : 0);
+ tmbTranslationX = tmbWidth + offset;
+ tmbTranslationY = 0;
+ break;
+ case 0: // top
+ offset = 10 + (dash?.visible && opt.DASH_TOP ? dash.height : 0) + Main.panel.height;
+ tmbTranslationX = 0;
+ tmbTranslationY = -tmbHeight - offset;
+ break;
+ case 2: // bottom
+ offset = 10 + (dash?.visible && opt.DASH_BOTTOM ? dash.height : 0) + Main.panel.height; // just for case the panel is at bottom
+ tmbTranslationX = 0;
+ tmbTranslationY = tmbHeight + offset;
+ break;
+ }
+ }
+
+ let dashTranslationX = 0;
+ let dashTranslationY = 0;
+ let position = opt.DASH_POSITION;
+ // if DtD replaced the original Dash, read its position
+ if (Me.Util.dashIsDashToDock())
+ position = dash._position;
+
+ if (dash?.visible) {
+ const dashWidth = dash.width === Infinity ? 0 : dash.width;
+ const dashHeight = dash.height === Infinity ? 0 : dash.height;
+ switch (position) {
+ case 0: // top
+ dashTranslationX = 0;
+ dashTranslationY = -dashHeight - dash.margin_bottom - Main.panel.height;
+ break;
+ case 1: // right
+ dashTranslationX = dashWidth;
+ dashTranslationY = 0;
+ break;
+ case 2: // bottom
+ dashTranslationX = 0;
+ dashTranslationY = dashHeight + dash.margin_bottom + Main.panel.height;
+ break;
+ case 3: // left
+ dashTranslationX = -dashWidth;
+ dashTranslationY = 0;
+ break;
+ }
+ }
+
+ return [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY];
+ },
+
animateToOverview(state, callback) {
this._ignoreShowAppsButtonToggle = true;
this._searchTransition = false;
- this._searchController.prepareToEnterOverview();
- this._workspacesDisplay.prepareToEnterOverview();
-
this._stateAdjustment.value = ControlsState.HIDDEN;
// building window thumbnails takes some time and with many windows on the workspace
@@ -627,10 +793,151 @@ const ControlsManager = {
this._ignoreShowAppsButtonToggle = false;
},
+
+ _setBackground(reset = false) {
+ if (this._bgManagers) {
+ this._bgManagers.forEach(bg => {
+ Main.overview._overview._controls._stateAdjustment.disconnect(bg._fadeSignal);
+ bg.destroy();
+ });
+ }
+
+ // if (!SHOW_BG_IN_OVERVIEW && !SHOW_WS_PREVIEW_BG) the background is used for static transition from wallpaper to empty bg in the overview
+ if (reset || (!opt.SHOW_BG_IN_OVERVIEW && opt.SHOW_WS_PREVIEW_BG)) {
+ delete this._bgManagers;
+ return;
+ }
+
+ this._bgManagers = [];
+ for (const monitor of Main.layoutManager.monitors) {
+ const bgManager = new Background.BackgroundManager({
+ monitorIndex: monitor.index,
+ container: Main.layoutManager.overviewGroup,
+ vignette: true,
+ });
+
+ bgManager.backgroundActor.content.vignette_sharpness = 0;
+ bgManager.backgroundActor.content.brightness = 1;
+
+
+ bgManager._fadeSignal = Main.overview._overview._controls._stateAdjustment.connect('notify::value', v => {
+ this._updateBackground(bgManager, v.value, v);
+ });
+
+ if (monitor.index === global.display.get_primary_monitor()) {
+ bgManager._primary = true;
+ this._bgManagers.unshift(bgManager); // primary monitor first
+ } else {
+ bgManager._primary = false;
+ this._bgManagers.push(bgManager);
+ }
+ }
+ },
+
+ _updateBackground(bgManager, stateValue = 2, stateAdjustment = null) {
+ // Blur My Shell extension destroys all background actors in the overview and doesn't care about consequences
+ if (this._bgManagers[0] && !Main.layoutManager.overviewGroup.get_children().includes(this._bgManagers[0].backgroundActor)) {
+ Main.notifyError(`[${Me.metadata.name}]`, _('Overview background crashed!\nIf you are using Blur My Shell, disable overview blur in its settings and re-enable V-Shell Overview Background to avoid visual glitches.'));
+ // remove and disconnect our destroyed backgrounds to avoid more errors
+ this._setBackground(true);
+ return;
+ }
+
+ const finalState = stateAdjustment?.getStateTransitionParams().finalState;
+ if (!opt.SHOW_BG_IN_OVERVIEW && !opt.SHOW_WS_PREVIEW_BG) {
+ // if no bg shown in the overview, fade out the wallpaper
+ if (!(opt.OVERVIEW_MODE2 && opt.WORKSPACE_MODE && finalState === 1))
+ bgManager.backgroundActor.opacity = Util.lerp(255, 0, Math.min(stateValue, 1));
+ } else {
+ let VIGNETTE, BRIGHTNESS, bgValue;
+ if (opt.OVERVIEW_MODE2 && stateValue <= 1 && !opt.WORKSPACE_MODE) {
+ VIGNETTE = 0;
+ BRIGHTNESS = 1;
+ bgValue = stateValue;
+ } else {
+ VIGNETTE = 0.2;
+ BRIGHTNESS = opt.OVERVIEW_BG_BRIGHTNESS;
+ if (opt.OVERVIEW_MODE2 && stateValue > 1 && !opt.WORKSPACE_MODE)
+ bgValue = stateValue - 1;
+ else
+ bgValue = stateValue;
+ }
+
+ let blurEffect = bgManager.backgroundActor.get_effect('blur');
+ if (!blurEffect) {
+ blurEffect = new Shell.BlurEffect({
+ brightness: 1,
+ sigma: 0,
+ mode: Shell.BlurMode.ACTOR,
+ });
+ bgManager.backgroundActor.add_effect_with_name('blur', blurEffect);
+ }
+
+ const searchActive = Main.overview._overview.controls._searchController.searchActive;
+ if (searchActive)
+ BRIGHTNESS = opt.SEARCH_BG_BRIGHTNESS;
+
+ bgManager.backgroundActor.content.vignette_sharpness = VIGNETTE;
+ bgManager.backgroundActor.content.brightness = BRIGHTNESS;
+
+ let vignetteInit, brightnessInit;// , sigmaInit;
+ if (opt.SHOW_BG_IN_OVERVIEW && opt.SHOW_WS_PREVIEW_BG) {
+ vignetteInit = VIGNETTE;
+ brightnessInit = BRIGHTNESS;
+ // sigmaInit = opt.OVERVIEW_BG_BLUR_SIGMA;
+ } else {
+ vignetteInit = 0;
+ brightnessInit = 1;
+ // sigmaInit = 0;
+ }
+
+ if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) {
+ bgManager.backgroundActor.content.vignette_sharpness = Util.lerp(vignetteInit, VIGNETTE, bgValue);
+ bgManager.backgroundActor.content.brightness = Util.lerp(brightnessInit, BRIGHTNESS, bgValue);
+ } else {
+ bgManager.backgroundActor.content.vignette_sharpness = Util.lerp(vignetteInit, VIGNETTE, Math.min(stateValue, 1));
+ bgManager.backgroundActor.content.brightness = Util.lerp(brightnessInit, BRIGHTNESS, Math.min(stateValue, 1));
+ }
+
+ if (opt.OVERVIEW_BG_BLUR_SIGMA || opt.APP_GRID_BG_BLUR_SIGMA) {
+ // reduce number of steps of blur transition to improve performance
+ const step = opt.SMOOTH_BLUR_TRANSITIONS ? 0.05 : 0.2;
+ const progress = stateValue - (stateValue % step);
+ if (opt.SHOW_WS_PREVIEW_BG && stateValue < 1 && !searchActive) { // no need to animate transition, unless appGrid state is involved, static bg is covered by the ws preview bg
+ if (blurEffect.sigma !== opt.OVERVIEW_BG_BLUR_SIGMA)
+ blurEffect.sigma = opt.OVERVIEW_BG_BLUR_SIGMA;
+ } else if (stateValue < 1 && !searchActive && !(opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)) {
+ const sigma = Math.round(Util.lerp(0, opt.OVERVIEW_BG_BLUR_SIGMA, progress));
+ if (sigma !== blurEffect.sigma)
+ blurEffect.sigma = sigma;
+ } else if (stateValue < 1 && !searchActive && (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE && blurEffect.sigma)) {
+ const sigma = Math.round(Util.lerp(0, opt.OVERVIEW_BG_BLUR_SIGMA, progress));
+ if (sigma !== blurEffect.sigma)
+ blurEffect.sigma = sigma;
+ } else if (stateValue > 1 && !searchActive && (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE && finalState === 1)) {
+ const sigma = Math.round(Util.lerp(0, opt.OVERVIEW_BG_BLUR_SIGMA, progress % 1));
+ if (sigma !== blurEffect.sigma)
+ blurEffect.sigma = sigma;
+ } else if ((stateValue > 1 && bgManager._primary) || searchActive) {
+ const sigma = Math.round(Util.lerp(opt.OVERVIEW_BG_BLUR_SIGMA, opt.APP_GRID_BG_BLUR_SIGMA, progress % 1));
+ if (sigma !== blurEffect.sigma)
+ blurEffect.sigma = sigma;
+ } else if (stateValue === 1 && !(opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)) {
+ blurEffect.sigma = opt.OVERVIEW_BG_BLUR_SIGMA;
+ } else if (stateValue === 0 || (stateValue === 1 && (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE))) {
+ blurEffect.sigma = 0;
+ }
+ }
+ }
+ },
};
const ControlsManagerLayoutVertical = {
- _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsWidth, searchHeight, startY) {
+ _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsWidth, thumbnailsHeight, searchHeight, startY) {
+ // in case the function is called from the DtD
+ if (startY === undefined) {
+ workAreaBox = box;
+ }
const workspaceBox = box.copy();
let [width, height] = workspaceBox.get_size();
// const { x1: startX/* y1: startY*/ } = workAreaBox;
@@ -640,7 +947,7 @@ const ControlsManagerLayoutVertical = {
const dash = Main.overview.dash;
// including Dash to Dock and clones properties for compatibility
- if (_Util.dashIsDashToDock()) {
+ if (Me.Util.dashIsDashToDock()) {
// Dash to Dock also always affects workAreaBox
Main.layoutManager._trackedActors.forEach(actor => {
if (actor.affectsStruts && actor.actor.width === dash.width) {
@@ -678,7 +985,7 @@ const ControlsManagerLayoutVertical = {
case ControlsState.APP_GRID:
if (opt.WS_ANIMATION && opt.SHOW_WS_TMB && state === ControlsState.APP_GRID) {
workspaceBox.set_origin(...this._workspacesThumbnails.get_position());
- workspaceBox.set_size(...this._workspacesThumbnails.get_size());
+ workspaceBox.set_size(thumbnailsWidth, thumbnailsHeight);
} else if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) {
if (opt.START_Y_OFFSET) {
let [x, y] = workAreaBox.get_origin();
@@ -693,7 +1000,7 @@ const ControlsManagerLayoutVertical = {
height = opt.PANEL_POSITION_TOP ? height : height - Main.panel.height;
searchHeight = opt.SHOW_SEARCH_ENTRY ? searchHeight : 0;
wWidth = width -
- (opt.DASH_VERTICAL ? dash.width : 0) -
+ (opt.DASH_VERTICAL ? dashWidth : 0) -
thumbnailsWidth -
4 * spacing;
wHeight = height -
@@ -739,7 +1046,7 @@ const ControlsManagerLayoutVertical = {
}
const wsBoxX = /* startX + */xOffset;
- wsBoxY = Math.round(startY + yOffset);
+ wsBoxY = startY + yOffset;
workspaceBox.set_origin(Math.round(wsBoxX), Math.round(wsBoxY));
workspaceBox.set_size(Math.round(wWidth), Math.round(wHeight));
}
@@ -749,6 +1056,10 @@ const ControlsManagerLayoutVertical = {
},
_getAppDisplayBoxForState(state, box, workAreaBox, searchHeight, dashWidth, dashHeight, thumbnailsWidth, startY) {
+ // in case the function is called from the DtD
+ if (startY === undefined) {
+ workAreaBox = box;
+ }
const [width] = box.get_size();
const { x1: startX } = workAreaBox;
// const { y1: startY } = workAreaBox;
@@ -762,11 +1073,11 @@ const ControlsManagerLayoutVertical = {
const xOffsetR = (opt.WS_TMB_RIGHT ? thumbnailsWidth : 0) + (opt.DASH_RIGHT ? dashWidth : 0);
const yOffsetT = (opt.DASH_TOP ? dashHeight : 0) + (opt.SHOW_SEARCH_ENTRY ? searchHeight : 0);
const yOffsetB = opt.DASH_BOTTOM ? dashHeight : 0;
- const adWidth = opt.CENTER_APP_GRID ? width - 2 * Math.max(xOffsetL, xOffsetR) - 4 * spacing : width - xOffsetL - xOffsetR - 4 * spacing;
- const adHeight = height - yOffsetT - yOffsetB - 4 * spacing;
+ const adWidth = opt.CENTER_APP_GRID ? width - 2 * Math.max(xOffsetL, xOffsetR) - 2 * spacing : width - xOffsetL - xOffsetR - 2 * spacing;
+ const adHeight = height - yOffsetT - yOffsetB;
const appDisplayX = opt.CENTER_APP_GRID ? (width - adWidth) / 2 : xOffsetL + 2 * spacing;
- const appDisplayY = startY + yOffsetT + 2 * spacing;
+ const appDisplayY = startY + yOffsetT;
switch (state) {
case ControlsState.HIDDEN:
@@ -774,43 +1085,43 @@ const ControlsManagerLayoutVertical = {
// 1 - left, 2 - right, 3 - bottom, 5 - top
switch (opt.APP_GRID_ANIMATION) {
case 0:
- appDisplayBox.set_origin(appDisplayX, appDisplayY);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY));
break;
case 1:
- appDisplayBox.set_origin(startX + width, appDisplayY);
+ appDisplayBox.set_origin(Math.round(startX + width), Math.round(appDisplayY));
break;
case 2:
- appDisplayBox.set_origin(startX - adWidth, appDisplayY);
+ appDisplayBox.set_origin(Math.round(startX - adWidth), Math.round(appDisplayY));
break;
case 3:
- appDisplayBox.set_origin(appDisplayX, workAreaBox.y2);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y2));
break;
case 5:
- appDisplayBox.set_origin(appDisplayX, workAreaBox.y1 - adHeight);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y1 - adHeight));
break;
}
break;
case ControlsState.APP_GRID:
- appDisplayBox.set_origin(appDisplayX, appDisplayY);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY));
break;
}
- appDisplayBox.set_size(adWidth, adHeight);
+ appDisplayBox.set_size(Math.round(adWidth), Math.round(adHeight));
return appDisplayBox;
},
vfunc_allocate(container, box) {
- const childBox = new Clutter.ActorBox();
+ const transitionParams = this._stateAdjustment.getStateTransitionParams();
+ const childBox = new Clutter.ActorBox();
const { spacing } = this;
-
+ const halfSpacing = spacing / 2;
const monitor = Main.layoutManager.findMonitorForActor(this._container);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
const startX = workArea.x - monitor.x;
// if PANEL_OVERVIEW_ONLY, the affectStruts property is set to false to avoid stuttering
// therefore we need to add panel height to startY
let startY = workArea.y - monitor.y + opt.START_Y_OFFSET;
-
const workAreaBox = new Clutter.ActorBox();
workAreaBox.set_origin(startX, startY);
workAreaBox.set_size(workArea.width, workArea.height);
@@ -818,7 +1129,7 @@ const ControlsManagerLayoutVertical = {
box.x1 += startX;
let [width, height] = box.get_size();
// if panel is at bottom position,
- // compensate the height of the available box (the box size is calculated for top panel)
+ // compensate for the height of the available box (the box size is calculated for top panel)
height = opt.PANEL_POSITION_TOP ? height : height - Main.panel.height;
let availableHeight = height;
@@ -830,8 +1141,8 @@ const ControlsManagerLayoutVertical = {
// dash cloud be overridden by the Dash to Dock clone
const dash = Main.overview.dash;
- if (_Util.dashIsDashToDock()) {
- // if Dash to Dock replaced the default dash and its inteli-hide id disabled we need to compensate for affected startY
+ if (Me.Util.dashIsDashToDock()) {
+ // if Dash to Dock replaced the default dash and its inteli-hide is disabled we need to compensate for affected startY
if (!Main.overview.dash.get_parent()?.get_parent()?.get_parent()?._intellihideIsEnabled) {
if (Main.panel.y === monitor.y)
startY = Main.panel.height + spacing;
@@ -857,48 +1168,48 @@ const ControlsManagerLayoutVertical = {
}
}
- const transitionParams = this._stateAdjustment.getStateTransitionParams();
-
// Workspace Thumbnails
let wsTmbWidth = 0;
let wsTmbHeight = 0;
- if (this._workspacesThumbnails.visible) {
- // const { expandFraction } = this._workspacesThumbnails;
+ let maxWsTmbScale = opt.MAX_THUMBNAIL_SCALE;
+ if (opt.SHOW_WS_TMB) {
const dashHeightReservation = !opt.WS_TMB_FULL && !opt.DASH_VERTICAL ? dashHeight : 0;
- let maxScale = opt.MAX_THUMBNAIL_SCALE;
- if (!opt.MAX_THUMBNAIL_SCALE_STABLE) {
+ const searchActive = this._searchController.searchActive;
+ if (!opt.MAX_THUMBNAIL_SCALE_STABLE && !searchActive) {
const initState = transitionParams.initialState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE;
const finalState = transitionParams.finalState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE;
- maxScale = Util.lerp(initState, finalState, transitionParams.progress);
+ maxWsTmbScale = Util.lerp(initState, finalState, transitionParams.progress);
}
- wsTmbWidth = width * maxScale;
+ wsTmbWidth = width * maxWsTmbScale;
let totalTmbSpacing;
- [totalTmbSpacing, wsTmbHeight] = this._workspacesThumbnails.get_preferred_custom_height(wsTmbWidth);
+ [totalTmbSpacing, wsTmbHeight] = this._workspacesThumbnails.get_preferred_height(wsTmbWidth);
wsTmbHeight += totalTmbSpacing;
- const wsTmbHeightMax = height - dashHeightReservation;
+ const wsTmbHeightMax = opt.WS_TMB_FULL
+ ? height - spacing
+ : height - dashHeightReservation - 2 * spacing;
if (wsTmbHeight > wsTmbHeightMax) {
wsTmbHeight = wsTmbHeightMax;
- wsTmbWidth = this._workspacesThumbnails.get_preferred_custom_width(wsTmbHeight)[1];
+ wsTmbWidth = Math.round(this._workspacesThumbnails.get_preferred_width(wsTmbHeight)[1]);
}
let wsTmbX;
if (opt.WS_TMB_RIGHT)
- wsTmbX = Math.round(startX + width - (opt.DASH_RIGHT ? dashWidth : 0) - wsTmbWidth - spacing / 2);
+ wsTmbX = Math.round(startX + width - (opt.DASH_RIGHT ? dashWidth : 0) - wsTmbWidth /* - halfSpacing*/); // this halfSpacing is a part od dash style
else
- wsTmbX = Math.round((opt.DASH_LEFT ? dashWidth : 0) + spacing / 2);
+ wsTmbX = Math.round(opt.DASH_LEFT ? dashWidth : 0/* + halfSpacing*/); // this halfSpacing is a part od dash style
let wstOffset = (height - wsTmbHeight - (opt.DASH_VERTICAL ? 0 : dashHeightReservation)) / 2;
- wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * (wstOffset - spacing / 2);
+ wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * (wstOffset - halfSpacing);
let wsTmbY = Math.round(startY + (dashHeightReservation && opt.DASH_TOP ? dashHeight : 0) + wstOffset);
childBox.set_origin(wsTmbX, wsTmbY);
- childBox.set_size(Math.round(wsTmbWidth), Math.round(wsTmbHeight));
+ childBox.set_size(Math.max(wsTmbWidth, 1), Math.max(wsTmbHeight, 1));
this._workspacesThumbnails.allocate(childBox);
}
@@ -927,7 +1238,7 @@ const ControlsManagerLayoutVertical = {
if (!opt.DASH_VERTICAL) {
offset = (width - ((opt.WS_TMB_FULL || opt.CENTER_DASH_WS) && !this._xAlignCenter ? wsTmbWidth : 0) - dashWidth) / 2;
- offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2);
+ offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing);
dashX = offset;
if ((opt.WS_TMB_FULL || opt.CENTER_DASH_WS) && !this._xAlignCenter) {
@@ -944,7 +1255,7 @@ const ControlsManagerLayoutVertical = {
}
} else {
offset = (height - dashHeight) / 2;
- dashY = startY + (offset - opt.DASH_POSITION_ADJUSTMENT * offset);
+ dashY = startY + (offset - opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing));
}
childBox.set_origin(Math.round(startX + dashX), Math.round(dashY));
@@ -957,7 +1268,7 @@ const ControlsManagerLayoutVertical = {
let [searchHeight] = this._searchEntry.get_preferred_height(width - wsTmbWidth);
// Workspaces
- let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbWidth, searchHeight, startY];
+ let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbWidth, wsTmbHeight, searchHeight, startY];
// Update cached boxes
for (const state of Object.values(ControlsState)) {
@@ -983,7 +1294,7 @@ const ControlsManagerLayoutVertical = {
// Y position under top Dash
let searchEntryX, searchEntryY;
if (opt.DASH_TOP)
- searchEntryY = startY + dashHeight - spacing;
+ searchEntryY = startY + dashHeight;
else
searchEntryY = startY;
@@ -1005,7 +1316,11 @@ const ControlsManagerLayoutVertical = {
availableHeight -= searchHeight + spacing;
// if (this._appDisplay.visible)... ? Can cause problems
- params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbWidth, startY]; // send startY, can be corrected
+ // Calculate appDisplay always for AppGrid state WsTmb scale
+ let wsTmbWidthAppGrid = opt.MAX_THUMBNAIL_SCALE_APPGRID > 0
+ ? Math.round(wsTmbWidth / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE_APPGRID)
+ : Math.round(wsTmbWidth / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE);
+ params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbWidthAppGrid, startY]; // send startY, can be corrected
let appDisplayBox;
if (!transitionParams.transitioning) {
appDisplayBox =
@@ -1024,9 +1339,9 @@ const ControlsManagerLayoutVertical = {
if (opt.CENTER_SEARCH_VIEW) {
const dashW = (opt.DASH_VERTICAL ? dashWidth : 0) + spacing;
searchWidth = width - 2 * wsTmbWidth - 2 * dashW;
- childBox.set_origin(wsTmbWidth + dashW, startY + (opt.DASH_TOP ? dashHeight : spacing) + searchHeight);
+ childBox.set_origin(wsTmbWidth + dashW, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + searchHeight);
} else {
- childBox.set_origin(this._xAlignCenter ? wsTmbWidth + spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight : spacing) + searchHeight);
+ childBox.set_origin(this._xAlignCenter ? wsTmbWidth + spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + searchHeight);
}
childBox.set_size(searchWidth, availableHeight);
@@ -1037,7 +1352,11 @@ const ControlsManagerLayoutVertical = {
};
const ControlsManagerLayoutHorizontal = {
- _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsHeight, searchHeight, startY) {
+ _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsWidth, thumbnailsHeight, searchHeight, startY) {
+ // in case the function is called from the DtD
+ if (startY === undefined) {
+ workAreaBox = box;
+ }
const workspaceBox = box.copy();
let [width, height] = workspaceBox.get_size();
// let { x1: startX/* , y1: startY*/ } = workAreaBox;
@@ -1046,7 +1365,7 @@ const ControlsManagerLayoutHorizontal = {
const dash = Main.overview.dash;
// including Dash to Dock and clones properties for compatibility
- if (_Util.dashIsDashToDock()) {
+ if (Me.Util.dashIsDashToDock()) {
// Dash to Dock always affects workAreaBox
Main.layoutManager._trackedActors.forEach(actor => {
if (actor.affectsStruts && actor.actor.width === dash.width) {
@@ -1084,7 +1403,7 @@ const ControlsManagerLayoutHorizontal = {
case ControlsState.APP_GRID:
if (opt.WS_ANIMATION && opt.SHOW_WS_TMB && state === ControlsState.APP_GRID) {
workspaceBox.set_origin(...this._workspacesThumbnails.get_position());
- workspaceBox.set_size(...this._workspacesThumbnails.get_size());
+ workspaceBox.set_size(thumbnailsWidth, thumbnailsHeight);
} else if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) {
if (opt.START_Y_OFFSET) {
let [x, y] = workAreaBox.get_origin();
@@ -1146,7 +1465,7 @@ const ControlsManagerLayoutHorizontal = {
}
wsBoxX = /* startX + */xOffset;
- wsBoxY = Math.round(startY + yOffset);
+ wsBoxY = startY + yOffset;
workspaceBox.set_origin(Math.round(wsBoxX), Math.round(wsBoxY));
workspaceBox.set_size(Math.round(wWidth), Math.round(wHeight));
}
@@ -1156,6 +1475,10 @@ const ControlsManagerLayoutHorizontal = {
},
_getAppDisplayBoxForState(state, box, workAreaBox, searchHeight, dashWidth, dashHeight, thumbnailsHeight, startY) {
+ // in case the function is called from the DtD
+ if (startY === undefined) {
+ workAreaBox = box;
+ }
const [width] = box.get_size();
const { x1: startX } = workAreaBox;
// const { y1: startY } = workAreaBox;
@@ -1163,16 +1486,16 @@ const ControlsManagerLayoutHorizontal = {
const appDisplayBox = new Clutter.ActorBox();
const { spacing } = this;
- const yOffsetT = (opt.WS_TMB_TOP ? thumbnailsHeight : 0) + (opt.DASH_TOP ? dashHeight : 0) + (opt.SHOW_SEARCH_ENTRY ? searchHeight : 0) + 2 * spacing;
- const yOffsetB = (opt.WS_TMB_BOTTOM ? thumbnailsHeight : 0) + (opt.DASH_BOTTOM ? dashHeight : 0);
+ const yOffsetT = (opt.WS_TMB_TOP ? thumbnailsHeight + spacing : 0) + (opt.DASH_TOP ? dashHeight : 0) + (opt.SHOW_SEARCH_ENTRY ? searchHeight : 0);
+ const yOffsetB = (opt.WS_TMB_BOTTOM ? thumbnailsHeight + spacing : 0) + (opt.DASH_BOTTOM ? dashHeight : 0);
const xOffsetL = opt.DASH_LEFT ? dashWidth : 0;
const xOffsetR = opt.DASH_RIGHT ? dashWidth : 0;
- const hSpacing = xOffsetL + xOffsetR ? 2 * spacing : 0;
+ const hSpacing = xOffsetL + xOffsetR ? spacing : 0;
const adWidth = opt.CENTER_APP_GRID ? width - 2 * Math.max(xOffsetL, xOffsetR) - 2 * hSpacing : width - xOffsetL - xOffsetR - 2 * hSpacing;
- const adHeight = height - yOffsetT - yOffsetB - 4 * spacing;
+ const adHeight = height - yOffsetT - yOffsetB;
const appDisplayX = opt.CENTER_APP_GRID ? (width - adWidth) / 2 : xOffsetL + hSpacing;
- const appDisplayY = startY + yOffsetT + hSpacing;
+ const appDisplayY = startY + yOffsetT;
switch (state) {
case ControlsState.HIDDEN:
@@ -1180,36 +1503,36 @@ const ControlsManagerLayoutHorizontal = {
// 1 - left, 2 - right, 3 - bottom, 5 - top
switch (opt.APP_GRID_ANIMATION) {
case 0:
- appDisplayBox.set_origin(appDisplayX, appDisplayY);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY));
break;
case 1:
- appDisplayBox.set_origin(startX + width, appDisplayY);
+ appDisplayBox.set_origin(Math.round(startX + width), Math.round(appDisplayY));
break;
case 2:
- appDisplayBox.set_origin(startX - adWidth, appDisplayY);
+ appDisplayBox.set_origin(Math.round(startX - adWidth), Math.round(appDisplayY));
break;
case 3:
- appDisplayBox.set_origin(appDisplayX, workAreaBox.y2);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y2));
break;
case 5:
- appDisplayBox.set_origin(appDisplayX, workAreaBox.y1 - adHeight);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y1 - adHeight));
break;
}
break;
case ControlsState.APP_GRID:
- appDisplayBox.set_origin(appDisplayX, appDisplayY);
+ appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY));
break;
}
- appDisplayBox.set_size(adWidth, adHeight);
+ appDisplayBox.set_size(Math.round(adWidth), Math.round(adHeight));
return appDisplayBox;
},
vfunc_allocate(container, box) {
+ const transitionParams = this._stateAdjustment.getStateTransitionParams();
const childBox = new Clutter.ActorBox();
-
const { spacing } = this;
-
+ const halfSpacing = spacing / 2;
const monitor = Main.layoutManager.findMonitorForActor(this._container);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index);
const startX = workArea.x - monitor.x;
@@ -1235,7 +1558,7 @@ const ControlsManagerLayoutHorizontal = {
// dash cloud be overridden by the Dash to Dock clone
const dash = Main.overview.dash;
- if (_Util.dashIsDashToDock()) {
+ if (Me.Util.dashIsDashToDock()) {
// if Dash to Dock replaced the default dash and its inteli-hide is disabled we need to compensate for affected startY
if (!Main.overview.dash.get_parent()?.get_parent()?.get_parent()?._intellihideIsEnabled) {
// if (Main.panel.y === monitor.y)
@@ -1265,60 +1588,53 @@ const ControlsManagerLayoutHorizontal = {
let [searchHeight] = this._searchEntry.get_preferred_height(width);
- const transitionParams = this._stateAdjustment.getStateTransitionParams();
-
// Workspace Thumbnails
let wsTmbWidth = 0;
let wsTmbHeight = 0;
- if (this._workspacesThumbnails.visible) {
- // const { expandFraction } = this._workspacesThumbnails;
+ let maxWsTmbScale = opt.MAX_THUMBNAIL_SCALE;
+ if (opt.SHOW_WS_TMB) {
const dashWidthReservation = !opt.WS_TMB_FULL && opt.DASH_VERTICAL ? dashWidth : 0;
- let maxScale = opt.MAX_THUMBNAIL_SCALE;
- if (!opt.MAX_THUMBNAIL_SCALE_STABLE) {
+ const searchActive = this._searchController.searchActive;
+ if (!opt.MAX_THUMBNAIL_SCALE_STABLE && !searchActive) {
const initState = transitionParams.initialState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE;
const finalState = transitionParams.finalState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE;
- maxScale = Util.lerp(initState, finalState, transitionParams.progress);
+ maxWsTmbScale = Util.lerp(initState, finalState, transitionParams.progress);
}
- wsTmbHeight = height * maxScale;
+ wsTmbHeight = Math.round(height * maxWsTmbScale);
let totalTmbSpacing;
- [totalTmbSpacing, wsTmbWidth] = this._workspacesThumbnails.get_preferred_custom_width(wsTmbHeight);
+ [totalTmbSpacing, wsTmbWidth] = this._workspacesThumbnails.get_preferred_width(wsTmbHeight);
wsTmbWidth += totalTmbSpacing;
const wsTmbWidthMax = opt.WS_TMB_FULL
- ? width
- : width - (opt.DASH_VERTICAL ? 0 : dashWidthReservation);
+ ? width - spacing
+ : width - dashWidthReservation - 2 * spacing;
if (wsTmbWidth > wsTmbWidthMax) {
wsTmbWidth = wsTmbWidthMax;
- wsTmbHeight = this._workspacesThumbnails.get_preferred_custom_height(wsTmbWidth)[1];
+ wsTmbHeight = Math.round(this._workspacesThumbnails.get_preferred_height(wsTmbWidth)[1]);
}
let wsTmbY;
if (opt.WS_TMB_TOP)
- wsTmbY = Math.round(startY + /* searchHeight + */(opt.DASH_TOP ? dashHeight : spacing / 2));
+ wsTmbY = Math.round(startY + (opt.DASH_TOP ? dashHeight : halfSpacing));
else
- wsTmbY = Math.round(startY + height - (opt.DASH_BOTTOM ? dashHeight : 0) - wsTmbHeight);
+ wsTmbY = Math.round(startY + height - (opt.DASH_BOTTOM ? dashHeight : halfSpacing) - wsTmbHeight);
- let wstOffset = (width - wsTmbWidth) / 2;
- wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * (wstOffset - spacing / 2);
- let wsTmbX = Math.round(Math.clamp(
- startX + wstOffset,
- startX + (opt.DASH_LEFT ? dashWidthReservation : 0),
- width - wsTmbWidth - startX - (opt.DASH_RIGHT ? dashWidthReservation : 0)
- ));
+ let wstOffset = (width - wsTmbWidth - dashWidthReservation) / 2;
+ wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * wstOffset;
+ let wsTmbX = Math.round(startX + (opt.DASH_LEFT ? dashWidthReservation : 0) + wstOffset);
childBox.set_origin(wsTmbX, wsTmbY);
- childBox.set_size(Math.round(wsTmbWidth), Math.round(wsTmbHeight));
+ childBox.set_size(Math.max(wsTmbWidth, 1), Math.max(wsTmbHeight, 1));
this._workspacesThumbnails.allocate(childBox);
availableHeight -= wsTmbHeight + spacing;
}
-
if (this._dash.visible) {
if (opt.WS_TMB_FULL && opt.DASH_VERTICAL) {
const wMaxHeight = height - spacing - wsTmbHeight;
@@ -1339,25 +1655,24 @@ const ControlsManagerLayoutHorizontal = {
else
dashY = startY + height - dashHeight;
-
if (opt.DASH_VERTICAL) {
if (opt.WS_TMB_FULL) {
offset = (height - dashHeight - wsTmbHeight) / 2;
if (opt.WS_TMB_TOP) {
- offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2);
+ offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing);
dashY = startY + offset + wsTmbHeight;
} else {
- offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2);
+ offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing);
dashY = startY + offset;
}
} else {
offset = (height - dashHeight) / 2;
- offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2);
+ offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing);
dashY = startY + offset;
}
} else {
offset = (width - dashWidth) / 2;
- dashX = startX + (offset - opt.DASH_POSITION_ADJUSTMENT * (offset - spacing));
+ dashX = startX + (offset - opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing));
}
childBox.set_origin(Math.round(startX + dashX), Math.round(dashY));
@@ -1368,7 +1683,7 @@ const ControlsManagerLayoutHorizontal = {
availableHeight -= opt.DASH_VERTICAL ? 0 : dashHeight;
// Workspaces
- let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbHeight, searchHeight, startY];
+ let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbWidth, wsTmbHeight, searchHeight, startY];
// Update cached boxes
for (const state of Object.values(ControlsState)) {
@@ -1394,7 +1709,7 @@ const ControlsManagerLayoutHorizontal = {
// Y position under top Dash
let searchEntryX, searchEntryY;
if (opt.DASH_TOP)
- searchEntryY = startY + (opt.WS_TMB_TOP ? wsTmbHeight : 0) + dashHeight - spacing;
+ searchEntryY = startY + (opt.WS_TMB_TOP ? wsTmbHeight : 0) + dashHeight;
else
searchEntryY = startY + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0);
@@ -1416,7 +1731,11 @@ const ControlsManagerLayoutHorizontal = {
availableHeight -= searchHeight + spacing;
// if (this._appDisplay.visible)... ? Can cause problems
- params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbHeight, startY];
+ // Calculate appDisplay always for AppGrid state WsTmb scale
+ let wsTmbHeightAppGrid = opt.MAX_THUMBNAIL_SCALE_APPGRID > 0
+ ? Math.round(wsTmbHeight / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE_APPGRID)
+ : Math.round(wsTmbHeight / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE);
+ params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbHeightAppGrid, startY];
let appDisplayBox;
if (!transitionParams.transitioning) {
appDisplayBox =
@@ -1435,9 +1754,9 @@ const ControlsManagerLayoutHorizontal = {
if (opt.CENTER_SEARCH_VIEW) {
const dashW = (opt.DASH_VERTICAL ? dashWidth : 0) + spacing;
searchWidth = width - 2 * dashW;
- childBox.set_origin(dashW, startY + (opt.DASH_TOP ? dashHeight : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight);
+ childBox.set_origin(dashW, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight);
} else {
- childBox.set_origin(this._xAlignCenter ? spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight);
+ childBox.set_origin(this._xAlignCenter ? spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight);
}
childBox.set_size(searchWidth, availableHeight);
@@ -1462,3 +1781,21 @@ function _getFitModeForState(state) {
return FitMode.SINGLE;
}
}
+
+const LayoutManager = {
+ _startupAnimation() {
+ if (Me.Util.dashIsDashToDock() && !Meta.is_restart()) {
+ // DtD breaks overview on startup
+ // Skip animation to hide the mess
+ this._startupAnimationComplete();
+ const controlsManager = Main.overview._overview.controls;
+ controlsManager._finishStartupSequence.bind(controlsManager)();
+ } else if (Meta.is_restart()) {
+ this._startupAnimationComplete();
+ } else if (Main.sessionMode.isGreeter) {
+ this._startupAnimationGreeter();
+ } else {
+ this._startupAnimationSession();
+ }
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/panel.js b/extensions/44/vertical-workspaces/lib/panel.js
new file mode 100644
index 0000000..898407a
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/panel.js
@@ -0,0 +1,256 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * panel.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+
+const Main = imports.ui.main;
+const Overview = imports.ui.overview;
+const Panel = imports.ui.panel;
+
+let Me;
+let opt;
+
+const ANIMATION_TIME = Overview.ANIMATION_TIME;
+
+var PanelModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+
+ this._showingOverviewConId = 0;
+ this._hidingOverviewConId = 0;
+ this._styleChangedConId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('panelModule');
+ const conflict = Me.Util.getEnabledExtensions('dash-to-panel').length ||
+ Me.Util.getEnabledExtensions('hidetopbar').length;
+
+ if (conflict && !reset)
+ console.warn(`[${Me.metadata.name}] Warning: "Panel" module disabled due to potential conflict with another extension`);
+
+ reset = reset || !this.moduleEnabled || conflict || Main.sessionMode.isLocked;
+
+ // don't touch original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' PanelModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ const panelBox = Main.layoutManager.panelBox;
+
+ this._setPanelPosition();
+ this._updateStyleChangedConnection();
+
+ if (opt.PANEL_MODE === 0) {
+ this._updateOverviewConnection(true);
+ this._reparentPanel(false);
+ panelBox.translation_y = 0;
+ Main.panel.opacity = 255;
+ this._setPanelStructs(true);
+ } else if (opt.PANEL_MODE === 1) {
+ if (opt.SHOW_WS_PREVIEW_BG) {
+ this._reparentPanel(true);
+ if (opt.OVERVIEW_MODE2) {
+ // in OM2 if the panel has been moved to the overviewGroup move panel above all
+ Main.layoutManager.overviewGroup.set_child_above_sibling(panelBox, null);
+ this._updateOverviewConnection();
+ } else {
+ // otherwise move the panel below overviewGroup so it can get below workspacesDisplay
+ Main.layoutManager.overviewGroup.set_child_below_sibling(panelBox, Main.overview._overview);
+ this._updateOverviewConnection(true);
+ }
+ this._showPanel(true);
+ } else {
+ // if ws preview bg is disabled, panel can stay in uiGroup
+ this._reparentPanel(false);
+ this._showPanel(false);
+ this._updateOverviewConnection();
+ }
+ // _connectPanel();
+ } else if (opt.PANEL_MODE === 2) {
+ this._updateOverviewConnection(true);
+ this._reparentPanel(false);
+ this._showPanel(false);
+ // _connectPanel();
+ }
+ this._setPanelStructs(opt.PANEL_MODE === 0);
+ Main.layoutManager._updateHotCorners();
+
+ this._overrides.addOverride('ActivitiesButton', Panel.ActivitiesButton.prototype, ActivitiesButton);
+
+ console.debug(' PanelModule - Activated');
+ }
+
+ _disableModule() {
+ const reset = true;
+ this._setPanelPosition(reset);
+ this._updateOverviewConnection(reset);
+ this._reparentPanel(false);
+
+ this._updateStyleChangedConnection(reset);
+
+ const panelBox = Main.layoutManager.panelBox;
+ panelBox.translation_y = 0;
+ Main.panel.opacity = 255;
+ this._setPanelStructs(true);
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ console.debug(' PanelModule - Disabled');
+ }
+
+ _setPanelPosition(reset = false) {
+ const geometry = global.display.get_monitor_geometry(global.display.get_primary_monitor());
+ const panelBox = Main.layoutManager.panelBox;
+ const panelHeight = Main.panel.height; // panelBox height can be 0 after shell start
+
+ if (opt.PANEL_POSITION_TOP || reset)
+ panelBox.set_position(geometry.x, geometry.y);
+ else
+ panelBox.set_position(geometry.x, geometry.y + geometry.height - panelHeight);
+ }
+
+ _updateStyleChangedConnection(reset = false) {
+ if (reset) {
+ if (this._styleChangedConId) {
+ Main.panel.disconnect(this._styleChangedConId);
+ this._styleChangedConId = 0;
+ }
+ } else if (!this._styleChangedConId) {
+ this._styleChangedConId = Main.panel.connect('style-changed', () => {
+ if (opt.PANEL_MODE === 1 && !opt.OVERVIEW_MODE2)
+ Main.panel.add_style_pseudo_class('overview');
+ else if (opt.OVERVIEW_MODE2)
+ Main.panel.remove_style_pseudo_class('overview');
+ });
+ }
+ }
+
+ _updateOverviewConnection(reset = false) {
+ if (reset) {
+ if (this._hidingOverviewConId) {
+ Main.overview.disconnect(this._hidingOverviewConId);
+ this._hidingOverviewConId = 0;
+ }
+ if (this._showingOverviewConId) {
+ Main.overview.disconnect(this._showingOverviewConId);
+ this._showingOverviewConId = 0;
+ }
+ } else {
+ if (!this._hidingOverviewConId) {
+ this._hidingOverviewConId = Main.overview.connect('hiding', () => {
+ if (!opt.SHOW_WS_PREVIEW_BG || opt.OVERVIEW_MODE2)
+ this._showPanel(false);
+ });
+ }
+ if (!this._showingOverviewConId) {
+ this._showingOverviewConId = Main.overview.connect('showing', () => {
+ if (Main.layoutManager._startingUp)
+ return;
+ if (!opt.SHOW_WS_PREVIEW_BG || opt.OVERVIEW_MODE2 || Main.layoutManager.panelBox.translation_y)
+ this._showPanel(true);
+ });
+ }
+ }
+ }
+
+ _reparentPanel(reparent = false) {
+ const panel = Main.layoutManager.panelBox;
+ if (reparent && panel.get_parent() === Main.layoutManager.uiGroup) {
+ Main.layoutManager.uiGroup.remove_child(panel);
+ Main.layoutManager.overviewGroup.add_child(panel);
+ } else if (!reparent && panel.get_parent() === Main.layoutManager.overviewGroup) {
+ Main.layoutManager.overviewGroup.remove_child(panel);
+ // return the panel at default position, panel shouldn't cover objects that should be above
+ Main.layoutManager.uiGroup.insert_child_at_index(panel, 4);
+ }
+ }
+
+ _setPanelStructs(state) {
+ Main.layoutManager._trackedActors.forEach(a => {
+ if (a.actor === Main.layoutManager.panelBox)
+ a.affectsStruts = state;
+ });
+
+ // workaround to force maximized windows to resize after removing affectsStruts
+ // simulation of minimal swipe gesture to the opposite direction
+ // todo - needs better solution!!!!!!!!!!!
+ // const direction = _getAppGridAnimationDirection() === 2 ? 1 : -1;
+ // Main.overview._swipeTracker._beginTouchSwipe(null, global.get_current_time(), 1, 1);
+ // Main.overview._swipeTracker._updateGesture(null, global.get_current_time(), direction, 1);
+ // GLib.timeout_add(0, 50, () => Main.overview._swipeTracker._endGesture(global.get_current_time(), 1, true));*/
+ }
+
+ _showPanel(show = true) {
+ if (show) {
+ Main.panel.opacity = 255;
+ Main.layoutManager.panelBox.ease({
+ duration: ANIMATION_TIME,
+ translation_y: 0,
+ onComplete: () => {
+ this._setPanelStructs(opt.PANEL_MODE === 0);
+ },
+ });
+ } else {
+ const panelHeight = Main.panel.height;
+ Main.layoutManager.panelBox.ease({
+ duration: ANIMATION_TIME,
+ translation_y: opt.PANEL_POSITION_TOP ? -panelHeight + 1 : panelHeight - 1,
+ onComplete: () => {
+ Main.panel.opacity = 0;
+ this._setPanelStructs(opt.PANEL_MODE === 0);
+ },
+ });
+ }
+ }
+};
+
+const ActivitiesButton = {
+ vfunc_event(event) {
+ if (event.type() === Clutter.EventType.TOUCH_END ||
+ event.type() === Clutter.EventType.BUTTON_RELEASE) {
+ if (Main.overview.shouldToggleByCornerOrButton()) {
+ if (event.get_button() === Clutter.BUTTON_SECONDARY && !Main.overview.dash.showAppsButton.checked) {
+ Main.overview.show(2);
+ Main.overview.dash.showAppsButton.checked = true;
+ } else {
+ Main.overview.toggle();
+ }
+ }
+ } else if (event.type() === Clutter.EventType.SCROLL) {
+ Main.wm.handleWorkspaceScroll(event);
+ }
+
+ return Clutter.EVENT_PROPAGATE;
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/recentFilesSearchProvider.js b/extensions/44/vertical-workspaces/lib/recentFilesSearchProvider.js
new file mode 100644
index 0000000..b567ff2
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/recentFilesSearchProvider.js
@@ -0,0 +1,258 @@
+/**
+* V-Shell (Vertical Workspaces)
+ * recentFilesSearchProvider.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ */
+
+'use strict';
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const RecentManager = imports.gi.Gtk.RecentManager;
+const St = imports.gi.St;
+const Shell = imports.gi.Shell;
+
+const Main = imports.ui.main;
+
+let Me;
+let opt;
+// gettext
+let _;
+
+// prefix helps to eliminate results from other search providers
+// so it needs to be something less common
+// needs to be accessible from vw module
+const PREFIX = 'fq//';
+
+var RecentFilesSearchProviderModule = class {
+ // export for other modules
+ static _PREFIX = PREFIX;
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _ = Me.gettext;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._recentFilesSearchProvider = null;
+ this._enableTimeoutId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ _ = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('recentFilesSearchProviderModule');
+
+ reset = reset || !this.moduleEnabled;
+
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' RecentFilesSearchProviderModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ // delay because Fedora had problem to register a new provider soon after Shell restarts
+ this._enableTimeoutId = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT,
+ 2000,
+ () => {
+ if (!this._recentFilesSearchProvider) {
+ this._recentFilesSearchProvider = new RecentFilesSearchProvider(opt);
+ this._getOverviewSearchResult()._registerProvider(this._recentFilesSearchProvider);
+ }
+ this._enableTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ }
+ );
+
+ console.debug(' RecentFilesSearchProviderModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._recentFilesSearchProvider) {
+ this._getOverviewSearchResult()._unregisterProvider(this._recentFilesSearchProvider);
+ this._recentFilesSearchProvider = null;
+ }
+ if (this._enableTimeoutId) {
+ GLib.source_remove(this._enableTimeoutId);
+ this._enableTimeoutId = 0;
+ }
+
+ console.debug(' RecentFilesSearchProviderModule - Disabled');
+ }
+
+ _getOverviewSearchResult() {
+ return Main.overview._overview.controls._searchController._searchResults;
+ }
+};
+
+class RecentFilesSearchProvider {
+ constructor() {
+ this.id = 'recent-files';
+ const appSystem = Shell.AppSystem.get_default();
+ let appInfo = appSystem.lookup_app('org.gnome.Nautilus.desktop')?.get_app_info();
+ if (!appInfo)
+ appInfo = Gio.AppInfo.create_from_commandline('/usr/bin/nautilus -w', _('Recent Files'), null);
+ appInfo.get_description = () => _('Search recent files');
+ appInfo.get_name = () => _('Recent Files');
+ appInfo.get_id = () => 'org.gnome.Nautilus.desktop';
+ appInfo.get_icon = () => Gio.icon_new_for_string('document-open-recent-symbolic');
+ appInfo.should_show = () => true;
+
+ this.appInfo = appInfo;
+ this.canLaunchSearch = true;
+ this.isRemoteProvider = false;
+ }
+
+ getInitialResultSet(terms, callback /* , cancellable = null*/) {
+ // In GS 43 callback arg has been removed
+ /* if (Me.shellVersion >= 43)
+ cancellable = callback; */
+
+ const filesDict = {};
+ let files = [];
+ if (terms[0].startsWith(PREFIX))
+ files = RecentManager.get_default().get_items();
+
+ // Detect whether time stamps are in int, or in GLib.DateTime object
+ this._timeNeedsConversion = files[0]?.get_modified().to_unix;
+
+ for (let file of files)
+ filesDict[file.get_uri()] = file;
+
+ this.files = filesDict;
+
+ if (Me.shellVersion >= 43)
+ return new Promise(resolve => resolve(this._getResultSet(terms)));
+ else
+ callback(this._getResultSet(terms));
+
+ return null;
+ }
+
+ _getResultSet(terms) {
+ if (!terms[0].startsWith(PREFIX))
+ return [];
+ // do not modify original terms
+ let termsCopy = [...terms];
+ // search for terms without prefix
+ termsCopy[0] = termsCopy[0].replace(PREFIX, '');
+
+ const candidates = this.files;
+ const _terms = [].concat(termsCopy);
+ // let match;
+
+ const term = _terms.join(' ');
+ /* match = s => {
+ return fuzzyMatch(term, s);
+ }; */
+
+ const results = [];
+ let m;
+ for (let id in candidates) {
+ const file = this.files[id];
+ const name = `${file.get_age()}d: ${file.get_display_name()} ${file.get_uri_display().replace(`/${file.get_display_name()}`, '')}`;
+ if (opt.SEARCH_FUZZY)
+ m = Me.Util.fuzzyMatch(term, name);
+ else
+ m = Me.Util.strictMatch(term, name);
+
+ if (m !== -1)
+ results.push({ weight: m, id });
+ }
+
+ if (this._timeNeedsConversion)
+ results.sort((a, b) => this.files[a.id].get_modified().to_unix() < this.files[b.id].get_modified().to_unix());
+ else
+ results.sort((a, b) => this.files[a.id].get_modified() < this.files[b.id].get_modified());
+
+ this.resultIds = results.map(item => item.id);
+ return this.resultIds;
+ }
+
+ getResultMetas(resultIds, callback = null) {
+ const metas = resultIds.map(id => this.getResultMeta(id));
+ if (Me.shellVersion >= 43)
+ return new Promise(resolve => resolve(metas));
+ else if (callback)
+ callback(metas);
+ return null;
+ }
+
+ getResultMeta(resultId) {
+ const result = this.files[resultId];
+ return {
+ 'id': resultId,
+ 'name': `${result.get_age()}: ${result.get_display_name()}`,
+ 'description': `${result.get_uri_display().replace(`/${result.get_display_name()}`, '')}`,
+ 'createIcon': size => {
+ let icon = this.getIcon(result, size);
+ return icon;
+ },
+ };
+ }
+
+ getIcon(result, size) {
+ let icon, gicon;
+
+ const appInfo = Gio.AppInfo.get_default_for_type(result.get_mime_type(), false);
+ if (appInfo)
+ gicon = appInfo.get_icon();
+
+ if (gicon)
+ icon = new St.Icon({ gicon, icon_size: size });
+ else
+ icon = new St.Icon({ icon_name: 'icon-missing', icon_size: size });
+
+ return icon;
+ }
+
+ launchSearch(terms, timeStamp) {
+ const appInfo = Gio.AppInfo.create_from_commandline('/usr/bin/nautilus -w recent:///', 'Nautilus', null);
+ appInfo.launch([], global.create_app_launch_context(timeStamp, -1));
+ }
+
+ activateResult(resultId, terms, timeStamp) {
+ const uri = resultId;
+ const context = global.create_app_launch_context(timeStamp, -1);
+ if (Me.Util.isShiftPressed()) {
+ Main.overview.toggle();
+ this.appInfo.launch_uris([uri], context);
+ } else if (Gio.app_info_launch_default_for_uri(uri, context)) {
+ // update recent list after (hopefully) successful activation
+ const recentManager = RecentManager.get_default();
+ recentManager.add_item(resultId);
+ } else {
+ this.appInfo.launch_uris([uri], context);
+ }
+ }
+
+ filterResults(results /* , maxResults*/) {
+ // return results.slice(0, maxResults);
+ return results.slice(0, 20);
+ }
+
+ getSubsearchResultSet(previousResults, terms, callback) {
+ if (Me.shellVersion < 43) {
+ this.getSubsearchResultSet42(terms, callback);
+ return null;
+ }
+ return this.getInitialResultSet(terms);
+ }
+
+ getSubsearchResultSet42(terms, callback) {
+ callback(this._getResultSet(terms));
+ }
+}
diff --git a/extensions/44/vertical-workspaces/lib/search.js b/extensions/44/vertical-workspaces/lib/search.js
new file mode 100644
index 0000000..618c5ed
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/search.js
@@ -0,0 +1,323 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * search.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const AppDisplay = imports.ui.appDisplay;
+const IconGrid = imports.ui.iconGrid;
+const Main = imports.ui.main;
+const Search = imports.ui.search;
+
+let Me;
+// gettext
+let _;
+let opt;
+
+
+let SEARCH_MAX_WIDTH;
+
+var SearchModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _ = Me.gettext;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ _ = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('searchModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' SearchModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ this._updateSearchViewWidth();
+
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._overrides.addOverride('AppSearchProvider', AppDisplay.AppSearchProvider.prototype, AppSearchProvider);
+ this._overrides.addOverride('SearchResult', Search.SearchResult.prototype, SearchResult);
+ this._overrides.addOverride('SearchResultsView', Search.SearchResultsView.prototype, SearchResultsView);
+ this._overrides.addOverride('ProviderInfo', Search.ProviderInfo.prototype, ProviderInfo);
+
+ // Don't expand the search view vertically and align it to the top
+ // this is important in the static workspace mode when the search view bg is not transparent
+ // also the "Searching..." and "No Results" notifications will be closer to the search entry, with the distance given by margin-top in the stylesheet
+ Main.overview._overview._controls.layoutManager._searchController.y_align = Clutter.ActorAlign.START;
+ console.debug(' SearchModule - Activated');
+ }
+
+ _disableModule() {
+ const reset = true;
+ this._updateSearchViewWidth(reset);
+
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ Main.overview._overview._controls.layoutManager._searchController.y_align = Clutter.ActorAlign.FILL;
+
+
+ console.debug(' WorkspaceSwitcherPopupModule - Disabled');
+ }
+
+ _updateSearchViewWidth(reset = false) {
+ const searchContent = Main.overview._overview._controls.layoutManager._searchController._searchResults._content;
+ if (!SEARCH_MAX_WIDTH) { // just store original value;
+ const themeNode = searchContent.get_theme_node();
+ const width = themeNode.get_max_width();
+ SEARCH_MAX_WIDTH = width;
+ }
+
+ if (reset) {
+ searchContent.set_style('');
+ } else {
+ let width = Math.round(SEARCH_MAX_WIDTH * opt.SEARCH_VIEW_SCALE);
+ searchContent.set_style(`max-width: ${width}px;`);
+ }
+ }
+};
+
+// AppDisplay.AppSearchProvider
+const AppSearchProvider = {
+ getInitialResultSet(terms, callback, cancellable) {
+ // Defer until the parental controls manager is initialized, so the
+ // results can be filtered correctly.
+ if (!this._parentalControlsManager.initialized) {
+ if (Me.shellVersion < 43) {
+ let initializedId = this._parentalControlsManager.connect('app-filter-changed', () => {
+ if (this._parentalControlsManager.initialized) {
+ this._parentalControlsManager.disconnect(initializedId);
+ this.getInitialResultSet(terms, callback, cancellable);
+ }
+ });
+ return null;
+ } else {
+ // callback has been removed in 43
+ cancellable = callback;
+ return new Promise(resolve => {
+ let initializedId = this._parentalControlsManager.connect('app-filter-changed', async () => {
+ if (this._parentalControlsManager.initialized) {
+ this._parentalControlsManager.disconnect(initializedId);
+ resolve(await this.getInitialResultSet(terms, cancellable));
+ }
+ });
+ });
+ }
+ }
+
+ const pattern = terms.join(' ');
+
+ let appInfoList = Shell.AppSystem.get_default().get_installed();
+
+ let weightList = {};
+ appInfoList = appInfoList.filter(appInfo => {
+ try {
+ appInfo.get_id(); // catch invalid file encodings
+ } catch (e) {
+ return false;
+ }
+
+ let string = '';
+ let name;
+ let shouldShow = false;
+ if (appInfo.get_display_name) {
+ // show only launchers that should be visible in this DE
+ shouldShow = appInfo.should_show() && this._parentalControlsManager.shouldShowApp(appInfo);
+
+ if (shouldShow) {
+ let id = appInfo.get_id().split('.');
+ id = id[id.length - 2] || '';
+ let baseName = appInfo.get_string('Name') || '';
+ let dispName = appInfo.get_display_name() || '';
+ let gName = appInfo.get_generic_name() || '';
+ let description = appInfo.get_description() || '';
+ let categories = appInfo.get_string('Categories') || '';
+ let keywords = appInfo.get_string('Keywords') || '';
+ name = `${dispName} ${id}`;
+ string = `${dispName} ${gName} ${baseName} ${description} ${categories} ${keywords} ${id}`;
+ }
+ }
+
+ let m = -1;
+ if (shouldShow && opt.SEARCH_FUZZY) {
+ m = Me.Util.fuzzyMatch(pattern, name);
+ m = (m + Me.Util.strictMatch(pattern, string)) / 2;
+ } else if (shouldShow) {
+ m = Me.Util.strictMatch(pattern, string);
+ }
+
+ if (m !== -1)
+ weightList[appInfo.get_id()] = m;
+
+ return shouldShow && (m !== -1);
+ });
+
+ appInfoList.sort((a, b) => weightList[a.get_id()] > weightList[b.get_id()]);
+
+ const usage = Shell.AppUsage.get_default();
+ // sort apps by usage list
+ appInfoList.sort((a, b) => usage.compare(a.get_id(), b.get_id()));
+ // prefer apps where any word in their name starts with the pattern
+ appInfoList.sort((a, b) => Me.Util.isMoreRelevant(a.get_display_name(), b.get_display_name(), pattern));
+
+ let results = appInfoList.map(app => app.get_id());
+
+ results = results.concat(this._systemActions.getMatchingActions(terms));
+
+ if (Me.shellVersion < 43) {
+ callback(results);
+ return null;
+ } else {
+ return new Promise(resolve => resolve(results));
+ }
+ },
+
+ // App search result size
+ createResultObject(resultMeta) {
+ if (resultMeta.id.endsWith('.desktop')) {
+ const icon = new AppDisplay.AppIcon(this._appSys.lookup_app(resultMeta['id']), {
+ expandTitleOnHover: false,
+ });
+ icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
+ return icon;
+ } else {
+ const icon = new AppDisplay.SystemActionIcon(this, resultMeta);
+ icon.icon._setSizeManually = true;
+ icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
+ return icon;
+ }
+ },
+};
+
+const SearchResult = {
+ activate() {
+ this.provider.activateResult(this.metaInfo.id, this._resultsView.terms);
+
+ if (this.metaInfo.clipboardText) {
+ St.Clipboard.get_default().set_text(
+ St.ClipboardType.CLIPBOARD, this.metaInfo.clipboardText);
+ }
+ // don't close overview if Shift key is pressed - Shift moves windows to the workspace
+ if (!Me.Util.isShiftPressed())
+ Main.overview.toggle();
+ },
+};
+
+const SearchResultsView = {
+ _doSearch() {
+ if (!this._doProviderSearch) {
+ this._doSearchLegacy();
+ return;
+ }
+ this._startingSearch = false;
+
+ let previousResults = this._results;
+ this._results = {};
+
+ this._providers.forEach(provider => {
+ const onlyVShellProviders = this._terms.includes('wq//') || this._terms.includes('fq//');
+ if (!onlyVShellProviders || (onlyVShellProviders && (provider.id.includes('open-windows') || provider.id.includes('recent-files')))) {
+ let previousProviderResults = previousResults[provider.id];
+ this._doProviderSearch(provider, previousProviderResults);
+ }
+ });
+
+ this._updateSearchProgress();
+
+ this._clearSearchTimeout();
+ },
+
+ _doSearchLegacy() {
+ this._startingSearch = false;
+
+ let previousResults = this._results;
+ this._results = {};
+
+ this._providers.forEach(provider => {
+ const onlyVShellProviders = this._terms.includes('wq//') || this._terms.includes('fq//');
+ if (!onlyVShellProviders || (onlyVShellProviders && (provider.id.includes('open-windows') || provider.id.includes('recent-files')))) {
+ provider.searchInProgress = true;
+
+ let previousProviderResults = previousResults[provider.id];
+ if (this._isSubSearch && previousProviderResults) {
+ provider.getSubsearchResultSet(previousProviderResults,
+ this._terms,
+ results => {
+ this._gotResults(results, provider);
+ },
+ this._cancellable);
+ } else {
+ provider.getInitialResultSet(this._terms,
+ results => {
+ this._gotResults(results, provider);
+ },
+ this._cancellable);
+ }
+ }
+ });
+
+ this._updateSearchProgress();
+
+ this._clearSearchTimeout();
+ },
+
+ _updateSearchProgress() {
+ let haveResults = this._providers.some(provider => {
+ let display = provider.display;
+ return display.getFirstResult() !== null;
+ });
+
+ this._scrollView.visible = haveResults;
+ this._statusBin.visible = !haveResults;
+
+ if (!haveResults) {
+ if (this.searchInProgress)
+ this._statusText.set_text(_('Searching…'));
+ else
+ this._statusText.set_text(_('No results.'));
+ }
+ },
+};
+
+// fixes app is null error if search provider id is not a desktop app id.
+const ProviderInfo = {
+ animateLaunch() {
+ let appSys = Shell.AppSystem.get_default();
+ let app = appSys.lookup_app(this.provider.appInfo.get_id());
+ if (app && app.state === Shell.AppState.STOPPED)
+ IconGrid.zoomOutActor(this._content);
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/searchController.js b/extensions/44/vertical-workspaces/lib/searchController.js
new file mode 100644
index 0000000..76b65e8
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/searchController.js
@@ -0,0 +1,94 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * searchController.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+
+const Main = imports.ui.main;
+
+let Me;
+let opt;
+
+var SearchControllerModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._originalOnStageKeyPress = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('searchControllerModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' SearchControllerModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._originalOnStageKeyPress)
+ this._originalOnStageKeyPress = Main.overview._overview.controls._searchController._onStageKeyPress;
+
+ Main.overview._overview.controls._searchController._onStageKeyPress = SearchControllerCommon._onStageKeyPress;
+ console.debug(' SearchControllerModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._originalOnStageKeyPress)
+ Main.overview._overview.controls._searchController._onStageKeyPress = this._originalOnStageKeyPress;
+ this._originalOnStageKeyPress = null;
+
+ console.debug(' SearchControlerModule - Disabled');
+ }
+};
+
+// if opt.ESC_BEHAVIOR > 0 force close the overview
+const SearchControllerCommon = {
+ _onStageKeyPress(actor, event) {
+ // Ignore events while anything but the overview has
+ // pushed a modal (system modals, looking glass, ...)
+ if (Main.modalCount > 1)
+ return Clutter.EVENT_PROPAGATE;
+
+ let symbol = event.get_key_symbol();
+ if (symbol === Clutter.KEY_Escape) {
+ if (this._searchActive && !opt.ESC_BEHAVIOR) {
+ this.reset();
+ } else if (this._showAppsButton.checked && !opt.ESC_BEHAVIOR) {
+ this._showAppsButton.checked = false;
+ } else {
+ this.reset();
+ Main.overview.hide();
+ }
+
+ return Clutter.EVENT_STOP;
+ } else if (this._shouldTriggerSearch(symbol)) {
+ this.startSearch(event);
+ }
+ return Clutter.EVENT_PROPAGATE;
+ },
+};
diff --git a/extensions/vertical-workspaces/lib/settings.js b/extensions/44/vertical-workspaces/lib/settings.js
index 66f3a45..cbb74f2 100644
--- a/extensions/vertical-workspaces/lib/settings.js
+++ b/extensions/44/vertical-workspaces/lib/settings.js
@@ -9,25 +9,15 @@
'use strict';
-const { GLib } = imports.gi;
+const GLib = imports.gi.GLib;
-const Config = imports.misc.config;
-
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-
-var shellVersion = parseFloat(Config.PACKAGE_VERSION);
-
-const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
-var _ = Gettext.gettext;
-const _schema = Me.metadata['settings-schema'];
-
-// common instance of Options accessible from all modules
-var opt;
+let Me;
var Options = class Options {
- constructor() {
- this._gsettings = ExtensionUtils.getSettings(_schema);
+ constructor(me) {
+ Me = me;
+
+ this._gsettings = Me.gSettings;
this._connectionIds = [];
this._writeTimeoutId = 0;
this._gsettings.delay();
@@ -51,8 +41,8 @@ var Options = class Options {
wsMaxSpacing: ['int', 'ws-max-spacing'],
wsPreviewScale: ['int', 'ws-preview-scale'],
secWsPreviewScale: ['int', 'secondary-ws-preview-scale'],
- secWsPreviewShift: ['bool', 'secondary-ws-preview-shift'],
- wsThumbnailsFull: ['bool', 'ws-thumbnails-full'],
+ secWsPreviewShift: ['boolean', 'secondary-ws-preview-shift'],
+ wsThumbnailsFull: ['boolean', 'ws-thumbnails-full'],
secWsThumbnailsPosition: ['int', 'secondary-ws-thumbnails-position'],
dashPosition: ['int', 'dash-position'],
dashPositionAdjust: ['int', 'dash-position-adjust'],
@@ -64,6 +54,7 @@ var Options = class Options {
dashMaxIconSize: ['int', 'dash-max-icon-size'],
dashShowWindowsIcon: ['int', 'dash-show-windows-icon'],
dashShowRecentFilesIcon: ['int', 'dash-show-recent-files-icon'],
+ dashShowExtensionsIcon: ['int', 'dash-show-extensions-icon'],
centerDashToWs: ['boolean', 'center-dash-to-ws'],
showAppsIconPosition: ['int', 'show-app-icon-position'],
wsThumbnailScale: ['int', 'ws-thumbnail-scale'],
@@ -73,13 +64,17 @@ var Options = class Options {
centerSearch: ['boolean', 'center-search'],
centerAppGrid: ['boolean', 'center-app-grid'],
dashBgOpacity: ['int', 'dash-bg-opacity'],
+ dashBgColor: ['int', 'dash-bg-color'],
dashBgRadius: ['int', 'dash-bg-radius'],
+ dashBgGS3Style: ['boolean', 'dash-bg-gs3-style'],
+ runningDotStyle: ['int', 'running-dot-style'],
enablePageShortcuts: ['boolean', 'enable-page-shortcuts'],
showWsSwitcherBg: ['boolean', 'show-ws-switcher-bg'],
showWsPreviewBg: ['boolean', 'show-ws-preview-bg'],
wsPreviewBgRadius: ['int', 'ws-preview-bg-radius'],
showBgInOverview: ['boolean', 'show-bg-in-overview'],
overviewBgBrightness: ['int', 'overview-bg-brightness'],
+ searchBgBrightness: ['int', 'search-bg-brightness'],
overviewBgBlurSigma: ['int', 'overview-bg-blur-sigma'],
appGridBgBlurSigma: ['int', 'app-grid-bg-blur-sigma'],
smoothBlurTransitions: ['boolean', 'smooth-blur-transitions'],
@@ -87,9 +82,8 @@ var Options = class Options {
searchViewAnimation: ['int', 'search-view-animation'],
workspaceAnimation: ['int', 'workspace-animation'],
animationSpeedFactor: ['int', 'animation-speed-factor'],
- fixUbuntuDock: ['boolean', 'fix-ubuntu-dock'],
winPreviewIconSize: ['int', 'win-preview-icon-size'],
- alwaysShowWinTitles: ['boolean', 'always-show-win-titles'],
+ winTitlePosition: ['int', 'win-title-position'],
startupState: ['int', 'startup-state'],
overviewMode: ['int', 'overview-mode'],
workspaceSwitcherAnimation: ['int', 'workspace-switcher-animation'],
@@ -105,17 +99,18 @@ var Options = class Options {
appGridContent: ['int', 'app-grid-content'],
appGridIncompletePages: ['boolean', 'app-grid-incomplete-pages'],
appGridOrder: ['int', 'app-grid-order'],
+ appFolderOrder: ['int', 'app-folder-order'],
appGridNamesMode: ['int', 'app-grid-names'],
appGridActivePreview: ['boolean', 'app-grid-active-preview'],
appGridFolderCenter: ['boolean', 'app-grid-folder-center'],
appGridPageWidthScale: ['int', 'app-grid-page-width-scale'],
appGridSpacing: ['int', 'app-grid-spacing'],
- searchWindowsEnable: ['boolean', 'search-windows-enable'],
- searchRecentFilesEnable: ['boolean', 'search-recent-files-enable'],
+ searchWindowsOrder: ['int', 'search-windows-order'],
searchFuzzy: ['boolean', 'search-fuzzy'],
searchMaxResultsRows: ['int', 'search-max-results-rows'],
dashShowWindowsBeforeActivation: ['int', 'dash-show-windows-before-activation'],
dashIconScroll: ['int', 'dash-icon-scroll'],
+ dashIsolateWorkspaces: ['boolean', 'dash-isolate-workspaces'],
searchWindowsIconScroll: ['int', 'search-windows-icon-scroll'],
panelVisibility: ['int', 'panel-visibility'],
panelPosition: ['int', 'panel-position'],
@@ -123,6 +118,8 @@ var Options = class Options {
wsSwPopupHPosition: ['int', 'ws-sw-popup-h-position'],
wsSwPopupVPosition: ['int', 'ws-sw-popup-v-position'],
wsSwPopupMode: ['int', 'ws-sw-popup-mode'],
+ wsSwitcherWraparound: ['boolean', 'ws-switcher-wraparound'],
+ wsSwitcherIgnoreLast: ['boolean', 'ws-switcher-ignore-last'],
favoritesNotify: ['int', 'favorites-notify'],
notificationPosition: ['int', 'notification-position'],
osdPosition: ['int', 'osd-position'],
@@ -131,17 +128,26 @@ var Options = class Options {
hotCornerFullscreen: ['boolean', 'hot-corner-fullscreen'],
hotCornerRipples: ['boolean', 'hot-corner-ripples'],
alwaysActivateSelectedWindow: ['boolean', 'always-activate-selected-window'],
- windowIconClickSearch: ['boolean', 'window-icon-click-search'],
+ winPreviewSecBtnAction: ['int', 'win-preview-sec-mouse-btn-action'],
+ winPreviewMidBtnAction: ['int', 'win-preview-mid-mouse-btn-action'],
+ winPreviewShowCloseButton: ['boolean', 'win-preview-show-close-button'],
+ windowIconClickAction: ['int', 'window-icon-click-action'],
+ overlayKeyPrimary: ['int', 'overlay-key-primary'],
overlayKeySecondary: ['int', 'overlay-key-secondary'],
+ overviewEscBehavior: ['int', 'overview-esc-behavior'],
+ newWindowFocusFix: ['boolean', 'new-window-focus-fix'],
+ appGridPerformance: ['boolean', 'app-grid-performance'],
+ windowThumbnailScale: ['int', 'window-thumbnail-scale'],
- workspaceThumbnailsModule: ['boolean', 'workspace-thumbnails-module'],
workspaceSwitcherPopupModule: ['boolean', 'workspace-switcher-popup-module'],
workspaceAnimationModule: ['boolean', 'workspace-animation-module'],
workspaceModule: ['boolean', 'workspace-module'],
windowManagerModule: ['boolean', 'window-manager-module'],
windowPreviewModule: ['boolean', 'window-preview-module'],
- winAttentionHandlerModule: ['boolean', 'win-attention-handler-module'],
+ windowAttentionHandlerModule: ['boolean', 'win-attention-handler-module'],
+ windowThumbnailModule: ['boolean', 'window-thumbnail-module'],
swipeTrackerModule: ['boolean', 'swipe-tracker-module'],
+ searchControllerModule: ['boolean', 'search-controller-module'],
searchModule: ['boolean', 'search-module'],
panelModule: ['boolean', 'panel-module'],
overlayKeyModule: ['boolean', 'overlay-key-module'],
@@ -151,6 +157,9 @@ var Options = class Options {
dashModule: ['boolean', 'dash-module'],
appFavoritesModule: ['boolean', 'app-favorites-module'],
appDisplayModule: ['boolean', 'app-display-module'],
+ windowSearchProviderModule: ['boolean', 'window-search-provider-module'],
+ recentFilesSearchProviderModule: ['boolean', 'recent-files-search-provider-module'],
+ extensionsSearchProviderModule: ['boolean', 'extensions-search-provider-module'],
profileName1: ['string', 'profile-name-1'],
profileName2: ['string', 'profile-name-2'],
@@ -158,9 +167,10 @@ var Options = class Options {
profileName4: ['string', 'profile-name-4'],
};
this.cachedOptions = {};
+ }
- this.shellVersion = shellVersion;
- // this.storeProfile(0);
+ cleanGlobals() {
+ Me = null;
}
connect(name, callback) {
@@ -183,7 +193,7 @@ var Options = class Options {
get(option, updateCache = false) {
if (!this.options[option]) {
- log(`[${Me.metadata.name}] Error: Option ${option} is undefined.`);
+ console.error(`[${Me.metadata.name}] Error: Option ${option} is undefined.`);
return null;
}
@@ -195,7 +205,6 @@ var Options = class Options {
else
gSettings = this._gsettings;
-
this.cachedOptions[option] = gSettings.get_value(key).deep_unpack();
}
@@ -242,7 +251,8 @@ var Options = class Options {
storeProfile(index) {
const profile = {};
Object.keys(this.options).forEach(v => {
- profile[v] = this.get(v).toString();
+ if (!v.startsWith('profileName'))
+ profile[v] = this.get(v).toString();
});
this._gsettings.set_value(`profile-data-${index}`, new GLib.Variant('a{ss}', profile));
@@ -250,8 +260,14 @@ var Options = class Options {
loadProfile(index) {
const options = this._gsettings.get_value(`profile-data-${index}`).deep_unpack();
+ // set the aaa-loading-data so extension.js doesn't reset V-Shell after each profile item
+ // delayed gsettings writes are processed alphabetically, so this key will be processed first
this._gsettings.set_boolean('aaa-loading-profile', !this._gsettings.get_boolean('aaa-loading-profile'));
for (let o of Object.keys(options)) {
+ if (!this.options[o]) {
+ console.error(`[${Me.metadata.name}] Error: "${o}" is not a valid profile key -> Update your profile`);
+ continue;
+ }
const [type] = this.options[o];
let value = options[o];
switch (type) {
@@ -275,7 +291,14 @@ var Options = class Options {
}
_updateSettings() {
- this.DASH_POSITION = this.get('dashPosition', true);
+ this._updateCachedSettings();
+ this.DASH_BG_ALPHA = this.get('dashBgOpacity') / 100;
+ this.DASH_BG_OPACITY = this.get('dashBgOpacity') * 2.5;
+ this.DASH_BG_COLOR = this.get('dashBgColor');
+ this.DASH_BG_RADIUS = this.get('dashBgRadius');
+ this.DASH_BG_LIGHT = this.DASH_BG_COLOR === 1;
+ this.DASH_BG_GS3_STYLE = this.get('dashBgGS3Style');
+ this.DASH_POSITION = this.get('dashModule') ? this.get('dashPosition') : 2;
this.DASH_TOP = this.DASH_POSITION === 0;
this.DASH_RIGHT = this.DASH_POSITION === 1;
this.DASH_BOTTOM = this.DASH_POSITION === 2;
@@ -284,26 +307,35 @@ var Options = class Options {
this.DASH_VISIBLE = this.DASH_POSITION !== 4; // 4 - disable
this.DASH_FOLLOW_RECENT_WIN = false;
- this.DASH_CLICK_ACTION = this.get('dashShowWindowsBeforeActivation', true);
- this.DASH_ICON_SCROLL = this.get('dashIconScroll', true);
+ this.DASH_ISOLATE_WS = this.get('dashIsolateWorkspaces');
+
+ this.DASH_CLICK_ACTION = this.get('dashShowWindowsBeforeActivation');
+ this.DASH_CLICK_SWITCH_BEFORE_ACTIVATION = this.DASH_CLICK_ACTION === 1;
+ this.DASH_CLICK_OPEN_NEW_WIN = this.DASH_CLICK_ACTION === 2;
+ this.DASH_CLICK_PREFER_WORKSPACE = this.DASH_CLICK_ACTION === 3;
+
+ this.DASH_ICON_SCROLL = this.get('dashIconScroll');
this.DASH_SHIFT_CLICK_MV = true;
- this.SEARCH_WINDOWS_ICON_SCROLL = this.get('searchWindowsIconScroll', true);
+ this.RUNNING_DOT_STYLE = this.get('runningDotStyle');
+
+ this.SEARCH_WINDOWS_ICON_SCROLL = this.get('searchWindowsIconScroll');
- this.DASH_POSITION_ADJUSTMENT = this.get('dashPositionAdjust', true);
+ this.DASH_POSITION_ADJUSTMENT = this.get('dashPositionAdjust');
this.DASH_POSITION_ADJUSTMENT = this.DASH_POSITION_ADJUSTMENT * -1 / 100; // range 1 to -1
- this.CENTER_DASH_WS = this.get('centerDashToWs', true);
+ this.CENTER_DASH_WS = this.get('centerDashToWs');
- this.MAX_ICON_SIZE = 64; // updates from main module
- this.SHOW_WINDOWS_ICON = this.get('dashShowWindowsIcon', true);
- this.SHOW_RECENT_FILES_ICON = this.get('dashShowRecentFilesIcon', true);
+ this.MAX_ICON_SIZE = this.get('dashMaxIconSize');
+ this.SHOW_WINDOWS_ICON = this.get('dashShowWindowsIcon');
+ this.SHOW_RECENT_FILES_ICON = this.get('dashShowRecentFilesIcon');
+ this.SHOW_EXTENSIONS_ICON = this.get('dashShowExtensionsIcon');
- this.WS_TMB_POSITION = this.get('workspaceThumbnailsPosition', true);
+ this.WS_TMB_POSITION = this.get('workspaceThumbnailsPosition');
this.ORIENTATION = this.WS_TMB_POSITION > 4 ? 0 : 1;
- this.WORKSPACE_MAX_SPACING = this.get('wsMaxSpacing', true);
+ this.WORKSPACE_MAX_SPACING = this.get('wsMaxSpacing');
// ORIENTATION || DASH_LEFT || DASH_RIGHT ? 350 : 80;
this.SHOW_WS_TMB = ![4, 9].includes(this.WS_TMB_POSITION); // 4, 9 - disable
- this.WS_TMB_FULL = this.get('wsThumbnailsFull', true);
+ this.WS_TMB_FULL = this.get('wsThumbnailsFull');
// translate ws tmb position to 0 top, 1 right, 2 bottom, 3 left
// 0L 1R, 2LF, 3RF, 4DV, 5T, 6B, 7TF, 8BF, 9DH
this.WS_TMB_POSITION = [3, 1, 3, 1, 4, 0, 2, 0, 2, 8][this.WS_TMB_POSITION];
@@ -311,81 +343,104 @@ var Options = class Options {
this.WS_TMB_RIGHT = this.WS_TMB_POSITION === 1;
this.WS_TMB_BOTTOM = this.WS_TMB_POSITION === 2;
this.WS_TMB_LEFT = this.WS_TMB_POSITION === 3;
- this.WS_TMB_POSITION_ADJUSTMENT = this.get('wsTmbPositionAdjust', true) * -1 / 100; // range 1 to -1
- this.SEC_WS_TMB_POSITION = this.get('secWsThumbnailsPosition', true);
+ this.WS_TMB_POSITION_ADJUSTMENT = this.get('wsTmbPositionAdjust') * -1 / 100; // range 1 to -1
+ this.SEC_WS_TMB_POSITION = this.get('secWsThumbnailsPosition');
this.SHOW_SEC_WS_TMB = this.SEC_WS_TMB_POSITION !== 3 && this.SHOW_WS_TMB;
this.SEC_WS_TMB_TOP = (this.SEC_WS_TMB_POSITION === 0 && !this.ORIENTATION) || (this.SEC_WS_TMB_POSITION === 2 && this.WS_TMB_TOP);
this.SEC_WS_TMB_RIGHT = (this.SEC_WS_TMB_POSITION === 1 && this.ORIENTATION) || (this.SEC_WS_TMB_POSITION === 2 && this.WS_TMB_RIGHT);
this.SEC_WS_TMB_BOTTOM = (this.SEC_WS_TMB_POSITION === 1 && !this.ORIENTATION) || (this.SEC_WS_TMB_POSITION === 2 && this.WS_TMB_BOTTOM);
this.SEC_WS_TMB_LEFT = (this.SEC_WS_TMB_POSITION === 0 && this.ORIENTATION) || (this.SEC_WS_TMB_POSITION === 2 && this.WS_TMB_LEFT);
- this.SEC_WS_TMB_POSITION_ADJUSTMENT = this.get('secWsTmbPositionAdjust', true) * -1 / 100; // range 1 to -1
- this.SEC_WS_PREVIEW_SHIFT = this.get('secWsPreviewShift', true);
- this.SHOW_WST_LABELS = this.get('showWsTmbLabels', true);
- this.SHOW_WST_LABELS_ON_HOVER = this.get('showWsTmbLabelsOnHover', true);
- this.CLOSE_WS_BUTTON_MODE = this.get('closeWsButtonMode', true);
+ this.SEC_WS_TMB_POSITION_ADJUSTMENT = this.get('secWsTmbPositionAdjust') * -1 / 100; // range 1 to -1
+ this.SEC_WS_PREVIEW_SHIFT = this.get('secWsPreviewShift');
+ this.SHOW_WST_LABELS = this.get('showWsTmbLabels');
+ this.SHOW_WST_LABELS_ON_HOVER = this.get('showWsTmbLabelsOnHover');
+ this.CLOSE_WS_BUTTON_MODE = this.get('closeWsButtonMode');
- this.MAX_THUMBNAIL_SCALE = this.get('wsThumbnailScale', true) / 100;
- this.MAX_THUMBNAIL_SCALE_APPGRID = this.get('wsThumbnailScaleAppGrid', true) / 100;
- if (this.MAX_THUMBNAIL_SCALE_APPGRID === 0)
- this.MAX_THUMBNAIL_SCALE_APPGRID = this.MAX_THUMBNAIL_SCALE;
+ this.MAX_THUMBNAIL_SCALE = this.get('wsThumbnailScale') / 100;
+ if (this.MAX_THUMBNAIL_SCALE === 0) {
+ this.MAX_THUMBNAIL_SCALE = 0.01;
+ this.SHOW_WS_TMB = false;
+ }
+ this.MAX_THUMBNAIL_SCALE_APPGRID = this.get('wsThumbnailScaleAppGrid') / 100;
+ this.SHOW_WS_TMB_APPGRID = true;
+ if (this.MAX_THUMBNAIL_SCALE_APPGRID === 0) {
+ this.MAX_THUMBNAIL_SCALE_APPGRID = 0.01;
+ this.SHOW_WS_TMB_APPGRID = false;
+ }
this.MAX_THUMBNAIL_SCALE_STABLE = this.MAX_THUMBNAIL_SCALE === this.MAX_THUMBNAIL_SCALE_APPGRID;
- this.SEC_MAX_THUMBNAIL_SCALE = this.get('secWsThumbnailScale', true) / 100;
- this.WS_PREVIEW_SCALE = this.get('wsPreviewScale', true) / 100;
- this.SEC_WS_PREVIEW_SCALE = this.get('secWsPreviewScale', true) / 100;
+ this.SEC_MAX_THUMBNAIL_SCALE = this.get('secWsThumbnailScale') / 100;
+ if (this.SEC_MAX_THUMBNAIL_SCALE === 0) {
+ this.SEC_MAX_THUMBNAIL_SCALE = 0.01;
+ this.SHOW_SEC_WS_TMB = false;
+ }
+
+ this.WS_PREVIEW_SCALE = this.get('wsPreviewScale') / 100;
+ this.SEC_WS_PREVIEW_SCALE = this.get('secWsPreviewScale') / 100;
// calculate number of possibly visible neighbor previews according to ws scale
this.NUMBER_OF_VISIBLE_NEIGHBORS = Math.round(1 + (1 - this.WS_PREVIEW_SCALE) / 4);
- this.SHOW_WS_TMB_BG = this.get('showWsSwitcherBg', true) && this.SHOW_WS_TMB;
- this.WS_PREVIEW_BG_RADIUS = this.get('wsPreviewBgRadius', true);
- this.SHOW_WS_PREVIEW_BG = this.get('showWsPreviewBg', true);
+ this.SHOW_WS_TMB_BG = this.get('showWsSwitcherBg') && this.SHOW_WS_TMB;
+ this.WS_PREVIEW_BG_RADIUS = this.get('wsPreviewBgRadius');
+ this.SHOW_WS_PREVIEW_BG = this.get('showWsPreviewBg');
- this.CENTER_APP_GRID = this.get('centerAppGrid', true);
+ this.CENTER_APP_GRID = this.get('centerAppGrid');
- this.SHOW_SEARCH_ENTRY = this.get('showSearchEntry', true);
- this.CENTER_SEARCH_VIEW = this.get('centerSearch', true);
- this.APP_GRID_ANIMATION = this.get('appGridAnimation', true);
+ this.SHOW_SEARCH_ENTRY = this.get('showSearchEntry');
+ this.CENTER_SEARCH_VIEW = this.get('centerSearch');
+ this.APP_GRID_ANIMATION = this.get('appGridAnimation');
if (this.APP_GRID_ANIMATION === 4)
this.APP_GRID_ANIMATION = this._getAnimationDirection();
- this.SEARCH_VIEW_ANIMATION = this.get('searchViewAnimation', true);
+ this.SEARCH_VIEW_ANIMATION = this.get('searchViewAnimation');
if (this.SEARCH_VIEW_ANIMATION === 4)
this.SEARCH_VIEW_ANIMATION = 3;
- this.WS_ANIMATION = this.get('workspaceAnimation', true);
+ this.WS_ANIMATION = this.get('workspaceAnimation');
- this.WIN_PREVIEW_ICON_SIZE = [64, 48, 32, 22, 8][this.get('winPreviewIconSize', true)];
- this.ALWAYS_SHOW_WIN_TITLES = this.get('alwaysShowWinTitles', true);
+ this.WIN_PREVIEW_ICON_SIZE = [64, 48, 32, 22, 8][this.get('winPreviewIconSize')];
+ this.WIN_TITLES_POSITION = this.get('winTitlePosition');
+ this.ALWAYS_SHOW_WIN_TITLES = this.WIN_TITLES_POSITION === 1;
- this.STARTUP_STATE = this.get('startupState', true);
- this.SHOW_BG_IN_OVERVIEW = this.get('showBgInOverview', true);
- this.OVERVIEW_BG_BRIGHTNESS = this.get('overviewBgBrightness', true) / 100;
- this.OVERVIEW_BG_BLUR_SIGMA = this.get('overviewBgBlurSigma', true);
- this.APP_GRID_BG_BLUR_SIGMA = this.get('appGridBgBlurSigma', true);
- this.SMOOTH_BLUR_TRANSITIONS = this.get('smoothBlurTransitions', true);
+ this.STARTUP_STATE = this.get('startupState');
+ this.SHOW_BG_IN_OVERVIEW = this.get('showBgInOverview');
+ this.OVERVIEW_BG_BRIGHTNESS = this.get('overviewBgBrightness') / 100;
+ this.SEARCH_BG_BRIGHTNESS = this.get('searchBgBrightness') / 100;
+ this.OVERVIEW_BG_BLUR_SIGMA = this.get('overviewBgBlurSigma');
+ this.APP_GRID_BG_BLUR_SIGMA = this.get('appGridBgBlurSigma');
+ this.SMOOTH_BLUR_TRANSITIONS = this.get('smoothBlurTransitions');
- this.OVERVIEW_MODE = this.get('overviewMode', true);
+ this.OVERVIEW_MODE = this.get('overviewMode');
this.OVERVIEW_MODE2 = this.OVERVIEW_MODE === 2;
this.WORKSPACE_MODE = this.OVERVIEW_MODE ? 0 : 1;
- this.STATIC_WS_SWITCHER_BG = this.get('workspaceSwitcherAnimation', true);
+ this.STATIC_WS_SWITCHER_BG = this.get('workspaceSwitcherAnimation');
- this.ANIMATION_TIME_FACTOR = this.get('animationSpeedFactor', true) / 100;
+ this.ANIMATION_TIME_FACTOR = this.get('animationSpeedFactor') / 100;
- this.SEARCH_ICON_SIZE = this.get('searchIconSize', true);
- this.SEARCH_VIEW_SCALE = this.get('searchViewScale', true) / 100;
- this.SEARCH_MAX_ROWS = this.get('searchMaxResultsRows', true);
- this.SEARCH_FUZZY = this.get('searchFuzzy', true);
+ this.SEARCH_ICON_SIZE = this.get('searchIconSize');
+ this.SEARCH_VIEW_SCALE = this.get('searchViewScale') / 100;
+ this.SEARCH_MAX_ROWS = this.get('searchMaxResultsRows');
+ this.SEARCH_FUZZY = this.get('searchFuzzy');
- this.APP_GRID_ALLOW_INCOMPLETE_PAGES = this.get('appGridIncompletePages', true);
- this.APP_GRID_ICON_SIZE = this.get('appGridIconSize', true);
- this.APP_GRID_COLUMNS = this.get('appGridColumns', true);
- this.APP_GRID_ROWS = this.get('appGridRows', true);
+ this.APP_GRID_ALLOW_INCOMPLETE_PAGES = this.get('appGridIncompletePages');
+ this.APP_GRID_ICON_SIZE = this.get('appGridIconSize');
+ this.APP_GRID_COLUMNS = this.get('appGridColumns');
+ this.APP_GRID_ROWS = this.get('appGridRows');
this.APP_GRID_ADAPTIVE = !this.APP_GRID_COLUMNS && !this.APP_GRID_ROWS;
- this.APP_GRID_ORDER = this.get('appGridOrder', true);
- this.APP_GRID_INCLUDE_DASH = this.get('appGridContent', true);
+ this.APP_GRID_ORDER = this.get('appGridOrder');
+ this.APP_GRID_ALPHABET = [1, 2].includes(this.APP_GRID_ORDER);
+ this.APP_GRID_FOLDERS_FIRST = this.APP_GRID_ORDER === 1;
+ this.APP_GRID_FOLDERS_LAST = this.APP_GRID_ORDER === 2;
+ this.APP_GRID_USAGE = this.APP_GRID_ORDER === 3;
+
+ this.APP_FOLDER_ORDER = this.get('appFolderOrder');
+ this.APP_FOLDER_ALPHABET = this.APP_FOLDER_ORDER === 1;
+ this.APP_FOLDER_USAGE = this.APP_FOLDER_ORDER === 2;
+
+ this.APP_GRID_INCLUDE_DASH = this.get('appGridContent');
/* APP_GRID_INCLUDE_DASH
0 - Include All
1 - Include All - Favorites and Runnings First
@@ -397,46 +452,50 @@ var Options = class Options {
this.APP_GRID_EXCLUDE_RUNNING = this.APP_GRID_INCLUDE_DASH === 3 || this.APP_GRID_INCLUDE_DASH === 4;
this.APP_GRID_DASH_FIRST = this.APP_GRID_INCLUDE_DASH === 1;
- this.APP_GRID_NAMES_MODE = this.get('appGridNamesMode', true);
+ this.APP_GRID_NAMES_MODE = this.get('appGridNamesMode');
- this.APP_GRID_FOLDER_ICON_SIZE = this.get('appGridFolderIconSize', true);
- this.APP_GRID_FOLDER_ICON_GRID = this.get('appGridFolderIconGrid', true);
- this.APP_GRID_FOLDER_COLUMNS = this.get('appGridFolderColumns', true);
- this.APP_GRID_FOLDER_ROWS = this.get('appGridFolderRows', true);
- this.APP_GRID_SPACING = this.get('appGridSpacing', true);
+ this.APP_GRID_FOLDER_ICON_SIZE = this.get('appGridFolderIconSize');
+ this.APP_GRID_FOLDER_ICON_GRID = this.get('appGridFolderIconGrid');
+ this.APP_GRID_FOLDER_COLUMNS = this.get('appGridFolderColumns');
+ this.APP_GRID_FOLDER_ROWS = this.get('appGridFolderRows');
+ this.APP_GRID_SPACING = this.get('appGridSpacing');
this.APP_GRID_FOLDER_DEFAULT = this.APP_GRID_FOLDER_ROWS === 3 && this.APP_GRID_FOLDER_COLUMNS === 3;
- this.APP_GRID_ACTIVE_PREVIEW = this.get('appGridActivePreview', true);
- this.APP_GRID_FOLDER_CENTER = this.get('appGridFolderCenter', true);
- this.APP_GRID_PAGE_WIDTH_SCALE = this.get('appGridPageWidthScale', true) / 100;
+ this.APP_GRID_FOLDER_ADAPTIVE = !this.APP_GRID_FOLDER_COLUMNS && !this.APP_GRID_FOLDER_ROWS;
+ this.APP_GRID_ACTIVE_PREVIEW = this.get('appGridActivePreview');
+ this.APP_GRID_FOLDER_CENTER = this.get('appGridFolderCenter');
+ this.APP_GRID_PAGE_WIDTH_SCALE = this.get('appGridPageWidthScale') / 100;
- this.APP_GRID_ICON_SIZE_DEFAULT = this.APP_GRID_ACTIVE_PREVIEW && !this.APP_GRID_ORDER ? 176 : 96;
+ this.APP_GRID_ICON_SIZE_DEFAULT = this.APP_GRID_ACTIVE_PREVIEW && !this.APP_GRID_USAGE ? 176 : 96;
this.APP_GRID_FOLDER_ICON_SIZE_DEFAULT = 96;
- this.WINDOW_SEARCH_PROVIDER_ENABLED = this.get('searchWindowsEnable', true);
- this.RECENT_FILES_SEARCH_PROVIDER_ENABLED = this.get('searchRecentFilesEnable', true);
+ this.APP_GRID_PERFORMANCE = this.get('appGridPerformance');
- this.PANEL_POSITION_TOP = this.get('panelPosition', true) === 0;
- this.PANEL_MODE = this.get('panelVisibility', true);
+ this.WINDOW_SEARCH_ORDER = this.get('searchWindowsOrder');
+
+ this.PANEL_POSITION_TOP = this.get('panelPosition') === 0;
+ this.PANEL_MODE = this.get('panelVisibility');
this.PANEL_DISABLED = this.PANEL_MODE === 2;
this.PANEL_OVERVIEW_ONLY = this.PANEL_MODE === 1;
this.START_Y_OFFSET = 0; // set from main module
- this.FIX_UBUNTU_DOCK = this.get('fixUbuntuDock', true);
- this.WINDOW_ATTENTION_MODE = this.get('windowAttentionMode', true);
+ this.WINDOW_ATTENTION_MODE = this.get('windowAttentionMode');
this.WINDOW_ATTENTION_DISABLE_NOTIFICATIONS = this.WINDOW_ATTENTION_MODE === 1;
this.WINDOW_ATTENTION_FOCUS_IMMEDIATELY = this.WINDOW_ATTENTION_MODE === 2;
- this.WS_SW_POPUP_H_POSITION = this.get('wsSwPopupHPosition', true) / 100;
- this.WS_SW_POPUP_V_POSITION = this.get('wsSwPopupVPosition', true) / 100;
- this.WS_SW_POPUP_MODE = this.get('wsSwPopupMode', true);
+ this.WS_SW_POPUP_H_POSITION = this.get('wsSwPopupHPosition') / 100;
+ this.WS_SW_POPUP_V_POSITION = this.get('wsSwPopupVPosition') / 100;
+ this.WS_SW_POPUP_MODE = this.get('wsSwPopupMode');
+
+ this.WS_WRAPAROUND = this.get('wsSwitcherWraparound');
+ this.WS_IGNORE_LAST = this.get('wsSwitcherIgnoreLast');
- this.SHOW_FAV_NOTIFICATION = this.get('favoritesNotify', true);
- this.NOTIFICATION_POSITION = this.get('notificationPosition', true);
+ this.SHOW_FAV_NOTIFICATION = this.get('favoritesNotify');
+ this.NOTIFICATION_POSITION = this.get('notificationPosition');
- this.OSD_POSITION = this.get('osdPosition', true);
+ this.OSD_POSITION = this.get('osdPosition');
- this.HOT_CORNER_ACTION = this.get('hotCornerAction', true);
- this.HOT_CORNER_POSITION = this.get('hotCornerPosition', true);
+ this.HOT_CORNER_ACTION = this.get('hotCornerAction');
+ this.HOT_CORNER_POSITION = this.get('hotCornerPosition');
if (this.HOT_CORNER_POSITION === 6 && this.DASH_VISIBLE)
this.HOT_CORNER_EDGE = true;
else
@@ -451,13 +510,24 @@ var Options = class Options {
else
this.HOT_CORNER_POSITION = 0;
}
- this.HOT_CORNER_FULLSCREEN = this.get('hotCornerFullscreen', true);
- this.HOT_CORNER_RIPPLES = this.get('hotCornerRipples', true);
+ this.HOT_CORNER_FULLSCREEN = this.get('hotCornerFullscreen');
+ this.HOT_CORNER_RIPPLES = this.get('hotCornerRipples');
+
+ this.ALWAYS_ACTIVATE_SELECTED_WINDOW = this.get('alwaysActivateSelectedWindow');
+ this.WIN_PREVIEW_SEC_BTN_ACTION = this.get('winPreviewSecBtnAction');
+ this.WIN_PREVIEW_MID_BTN_ACTION = this.get('winPreviewMidBtnAction');
+ this.SHOW_CLOSE_BUTTON = this.get('winPreviewShowCloseButton');
+ this.WINDOW_ICON_CLICK_ACTION = this.get('windowIconClickAction');
+
+ this.OVERLAY_KEY_PRIMARY = this.get('overlayKeyPrimary');
+ this.OVERLAY_KEY_SECONDARY = this.get('overlayKeySecondary');
+
+ this.ESC_BEHAVIOR = this.get('overviewEscBehavior');
- this.ALWAYS_ACTIVATE_SELECTED_WINDOW = this.get('alwaysActivateSelectedWindow', true);
- this.WINDOW_ICON_CLICK_SEARCH = this.get('windowIconClickSearch', true);
+ this.WINDOW_THUMBNAIL_ENABLED = this.get('windowThumbnailModule');
+ this.WINDOW_THUMBNAIL_SCALE = this.get('windowThumbnailScale') / 100;
- this.OVERLAY_KEY_SECONDARY = this.get('overlayKeySecondary', true);
+ this.FIX_NEW_WINDOW_FOCUS = this.get('newWindowFocusFix');
}
_getAnimationDirection() {
diff --git a/extensions/vertical-workspaces/lib/swipeTracker.js b/extensions/44/vertical-workspaces/lib/swipeTracker.js
index d9c3407..7122ead 100644
--- a/extensions/vertical-workspaces/lib/swipeTracker.js
+++ b/extensions/44/vertical-workspaces/lib/swipeTracker.js
@@ -10,61 +10,90 @@
'use strict';
-const { Clutter, GObject } = imports.gi;
+const Clutter = imports.gi.Clutter;
+const GObject = imports.gi.GObject;
+
const Main = imports.ui.main;
const SwipeTracker = imports.ui.swipeTracker;
-const Me = imports.misc.extensionUtils.getCurrentExtension();
-
+let Me;
let opt;
-let _firstRun = true;
-let _vwGestureUpdateId;
-let _originalGestureUpdateId;
+var SwipeTrackerModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('swipeTrackerModule', true);
- reset = reset || !moduleEnabled;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ }
- // don't even touch this module if disabled
- if (_firstRun && reset)
- return;
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
- _firstRun = false;
+ update(reset) {
+ this.moduleEnabled = opt.get('swipeTrackerModule');
+ const conflict = false;
- if (reset || !opt.ORIENTATION) { // 1-VERTICAL, 0-HORIZONTAL
- // original swipeTrackers' orientation and updateGesture function
- Main.overview._swipeTracker.orientation = Clutter.Orientation.VERTICAL;
- Main.wm._workspaceAnimation._swipeTracker.orientation = Clutter.Orientation.HORIZONTAL;
- Main.overview._swipeTracker._updateGesture = SwipeTracker.SwipeTracker.prototype._updateGesture;
- if (_vwGestureUpdateId) {
- Main.overview._swipeTracker._touchpadGesture.disconnect(_vwGestureUpdateId);
- _vwGestureUpdateId = 0;
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
}
- if (_originalGestureUpdateId) {
- Main.overview._swipeTracker._touchpadGesture.unblock_signal_handler(_originalGestureUpdateId);
- _originalGestureUpdateId = 0;
+ if (reset && this._firstActivation)
+ console.debug(' SwipeTrackerModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (opt.ORIENTATION) { // 1-VERTICAL, 0-HORIZONTAL
+ this._setVertical();
+ } else {
+ this._setHorizontal();
}
+ console.debug(' SwipeTrackerModule - Activated');
+ }
- opt = null;
- return;
+ _disableModule() {
+ this._setHorizontal();
+
+ console.debug(' SwipeTrackerModule - Disabled');
}
- if (opt.ORIENTATION) { // 1-VERTICAL, 0-HORIZONTAL
+ _setVertical() {
// reverse swipe gestures for enter/leave overview and ws switching
Main.overview._swipeTracker.orientation = Clutter.Orientation.HORIZONTAL;
Main.wm._workspaceAnimation._swipeTracker.orientation = Clutter.Orientation.VERTICAL;
// overview's updateGesture() function should reflect ws tmb position to match appGrid/ws animation direction
// function in connection cannot be overridden in prototype of its class because connected is actually another copy of the original function
- if (!_originalGestureUpdateId) {
- _originalGestureUpdateId = GObject.signal_handler_find(Main.overview._swipeTracker._touchpadGesture, { signalId: 'update' });
- Main.overview._swipeTracker._touchpadGesture.block_signal_handler(_originalGestureUpdateId);
+ if (!this._originalGestureUpdateId) {
+ this._originalGestureUpdateId = GObject.signal_handler_find(Main.overview._swipeTracker._touchpadGesture, { signalId: 'update' });
+ Main.overview._swipeTracker._touchpadGesture.block_signal_handler(this._originalGestureUpdateId);
Main.overview._swipeTracker._updateGesture = SwipeTrackerVertical._updateGesture;
- _vwGestureUpdateId = Main.overview._swipeTracker._touchpadGesture.connect('update', SwipeTrackerVertical._updateGesture.bind(Main.overview._swipeTracker));
+ this._vwGestureUpdateId = Main.overview._swipeTracker._touchpadGesture.connect('update', SwipeTrackerVertical._updateGesture.bind(Main.overview._swipeTracker));
+ }
+ }
+
+ _setHorizontal() {
+ // original swipeTrackers' orientation and updateGesture function
+ Main.overview._swipeTracker.orientation = Clutter.Orientation.VERTICAL;
+ Main.wm._workspaceAnimation._swipeTracker.orientation = Clutter.Orientation.HORIZONTAL;
+ Main.overview._swipeTracker._updateGesture = SwipeTracker.SwipeTracker.prototype._updateGesture;
+ if (this._vwGestureUpdateId) {
+ Main.overview._swipeTracker._touchpadGesture.disconnect(this._vwGestureUpdateId);
+ this._vwGestureUpdateId = 0;
+ }
+ if (this._originalGestureUpdateId) {
+ Main.overview._swipeTracker._touchpadGesture.unblock_signal_handler(this._originalGestureUpdateId);
+ this._originalGestureUpdateId = 0;
}
}
-}
+};
const SwipeTrackerVertical = {
_updateGesture(gesture, time, delta, distance) {
diff --git a/extensions/vertical-workspaces/lib/util.js b/extensions/44/vertical-workspaces/lib/util.js
index 5f5c069..9bc4365 100644
--- a/extensions/vertical-workspaces/lib/util.js
+++ b/extensions/44/vertical-workspaces/lib/util.js
@@ -10,16 +10,27 @@
'use strict';
+const Clutter = imports.gi.Clutter;
+const Meta = imports.gi.Meta;
const Gi = imports._gi;
-const { Shell, Meta, Clutter } = imports.gi;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Shell = imports.gi.Shell;
-const Config = imports.misc.config;
-const Main = imports.ui.main;
+const Main = imports.ui.main;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
+let Me;
-var shellVersion = parseFloat(Config.PACKAGE_VERSION);
+let _installedExtensions;
+
+function init(me) {
+ Me = me;
+}
+
+function cleanGlobals() {
+ Me = null;
+ _installedExtensions = null;
+}
var Overrides = class {
constructor() {
@@ -27,8 +38,13 @@ var Overrides = class {
}
addOverride(name, prototype, overrideList) {
+ const backup = this.overrideProto(prototype, overrideList, name);
+ // don't update originals when override's just refreshing, keep initial content
+ let originals = this._overrides[name]?.originals;
+ if (!originals)
+ originals = backup;
this._overrides[name] = {
- originals: this.overrideProto(prototype, overrideList),
+ originals,
prototype,
};
}
@@ -38,15 +54,15 @@ var Overrides = class {
if (!override)
return false;
- this.overrideProto(override.prototype, override.originals);
- this._overrides[name] = undefined;
+ this.overrideProto(override.prototype, override.originals, name);
+ delete this._overrides[name];
return true;
}
removeAll() {
for (let name in this._overrides) {
this.removeOverride(name);
- this._overrides[name] = undefined;
+ delete this._overrides[name];
}
}
@@ -54,13 +70,17 @@ var Overrides = class {
proto[Gi.hook_up_vfunc_symbol](symbol, func);
}
- overrideProto(proto, overrides) {
+ overrideProto(proto, overrides, name) {
const backup = {};
-
+ const originals = this._overrides[name]?.originals;
for (let symbol in overrides) {
if (symbol.startsWith('after_')) {
const actualSymbol = symbol.slice('after_'.length);
- const fn = proto[actualSymbol];
+ let fn;
+ if (originals && originals[actualSymbol])
+ fn = originals[actualSymbol];
+ else
+ fn = proto[actualSymbol];
const afterFn = overrides[symbol];
proto[actualSymbol] = function (...args) {
args = Array.prototype.slice.call(args);
@@ -72,11 +92,11 @@ var Overrides = class {
} else {
backup[symbol] = proto[symbol];
if (symbol.startsWith('vfunc')) {
- if (shellVersion < 42)
+ if (Me.shellVersion < 42)
this.hookVfunc(proto, symbol.slice(6), overrides[symbol]);
else
this.hookVfunc(proto[Gi.gobject_prototype_symbol], symbol.slice(6), overrides[symbol]);
- } else {
+ } else if (overrides[symbol] !== null) {
proto[symbol] = overrides[symbol];
}
}
@@ -85,87 +105,21 @@ var Overrides = class {
}
};
-function getOverviewTranslations(opt, dash, tmbBox, searchEntryBin) {
- // const tmbBox = Main.overview._overview._controls._thumbnailsBox;
- let searchTranslationY = 0;
- if (searchEntryBin.visible) {
- const offset = (dash.visible && (!opt.DASH_VERTICAL ? dash.height + 12 : 0)) +
- (opt.WS_TMB_TOP ? tmbBox.height + 12 : 0);
- searchTranslationY = -searchEntryBin.height - offset - 30;
- }
-
- let tmbTranslationX = 0;
- let tmbTranslationY = 0;
- let offset;
- if (tmbBox.visible) {
- switch (opt.WS_TMB_POSITION) {
- case 3: // left
- offset = 10 + (dash?.visible && opt.DASH_LEFT ? dash.width : 0);
- tmbTranslationX = -tmbBox.width - offset;
- tmbTranslationY = 0;
- break;
- case 1: // right
- offset = 10 + (dash?.visible && opt.DASH_RIGHT ? dash.width : 0);
- tmbTranslationX = tmbBox.width + offset;
- tmbTranslationY = 0;
- break;
- case 0: // top
- offset = 10 + (dash?.visible && opt.DASH_TOP ? dash.height : 0) + Main.panel.height;
- tmbTranslationX = 0;
- tmbTranslationY = -tmbBox.height - offset;
- break;
- case 2: // bottom
- offset = 10 + (dash?.visible && opt.DASH_BOTTOM ? dash.height : 0) + Main.panel.height; // just for case the panel is at bottom
- tmbTranslationX = 0;
- tmbTranslationY = tmbBox.height + offset;
- break;
- }
- }
-
- let dashTranslationX = 0;
- let dashTranslationY = 0;
- let position = opt.DASH_POSITION;
- // if DtD replaced the original Dash, read its position
- if (dashIsDashToDock())
- position = dash._position;
-
- if (dash?.visible) {
- switch (position) {
- case 0: // top
- dashTranslationX = 0;
- dashTranslationY = -dash.height - dash.margin_bottom - Main.panel.height;
- break;
- case 1: // right
- dashTranslationX = dash.width;
- dashTranslationY = 0;
- break;
- case 2: // bottom
- dashTranslationX = 0;
- dashTranslationY = dash.height + dash.margin_bottom + Main.panel.height;
- break;
- case 3: // left
- dashTranslationX = -dash.width;
- dashTranslationY = 0;
- break;
- }
- }
-
- return [tmbTranslationX, tmbTranslationY, dashTranslationX, dashTranslationY, searchTranslationY];
-}
-
-function openPreferences() {
+function openPreferences(metadata) {
+ if (!metadata)
+ metadata = Me.metadata;
const windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL, null);
let tracker = Shell.WindowTracker.get_default();
let metaWin, isVW = null;
for (let win of windows) {
const app = tracker.get_window_app(win);
- if (win.get_title().includes(Me.metadata.name) && app.get_name() === 'Extensions') {
+ if (win.get_title()?.includes(metadata.name) && app.get_name() === 'Extensions') {
// this is our existing window
metaWin = win;
isVW = true;
break;
- } else if (win.wm_class.includes('org.gnome.Shell.Extensions')) {
+ } else if (win.wm_class?.includes('org.gnome.Shell.Extensions')) {
// this is prefs window of another extension
metaWin = win;
isVW = false;
@@ -182,17 +136,20 @@ function openPreferences() {
}
if (!metaWin || (metaWin && !isVW)) {
- try {
- Main.extensionManager.openExtensionPrefs(Me.metadata.uuid, '', {});
- } catch (e) {
- log(e);
- }
+ GLib.idle_add(GLib.PRIORITY_LOW, () => {
+ try {
+ Main.extensionManager.openExtensionPrefs(metadata.uuid, '', {});
+ } catch (e) {
+ console.error(e);
+ }
+ });
}
}
function activateSearchProvider(prefix = '') {
const searchEntry = Main.overview.searchEntry;
- if (!searchEntry.get_text() || !searchEntry.get_text().startsWith(prefix)) {
+ const searchEntryText = searchEntry.get_text();
+ if (!searchEntryText || (searchEntryText && !searchEntry.get_text().startsWith(prefix))) {
prefix = `${prefix} `;
const position = prefix.length;
searchEntry.set_text(prefix);
@@ -220,9 +177,16 @@ function reorderWorkspace(direction = 0) {
global.workspace_manager.reorder_workspace(activeWs, targetIdx);
}
+function activateKeyboardForWorkspaceView() {
+ Main.ctrlAltTabManager._items.forEach(i => {
+ if (i.sortGroup === 1 && i.name === 'Windows')
+ Main.ctrlAltTabManager.focusGroup(i);
+ });
+}
+
function exposeWindows(adjustment, activateKeyboard) {
// expose windows for static overview modes
- if (!adjustment.value && !Main.overview._animationInProgress) {
+ if (!adjustment.value/* && !Main.overview._animationInProgress*/) {
if (adjustment.value === 0) {
adjustment.value = 0;
adjustment.ease(1, {
@@ -330,13 +294,48 @@ function isMoreRelevant(stringA, stringB, pattern) {
return !aAny && bAny;
}
-function getEnabledExtensions(uuid = '') {
- let extensions = [];
- Main.extensionManager._extensions.forEach(e => {
- if (e.state === 1 && e.uuid.includes(uuid))
- extensions.push(e);
- });
- return extensions;
+function getEnabledExtensions(pattern = '') {
+ let result = [];
+ // extensionManager is unreliable at startup (if not all extensions were loaded)
+ // but gsettings key can contain removed extensions...
+ // therefore we have to look into filesystem, what's really installed
+ if (!_installedExtensions) {
+ const extensionFiles = [...collectFromDatadirs('extensions', true)];
+ _installedExtensions = extensionFiles.map(({ info }) => {
+ let fileType = info.get_file_type();
+ if (fileType !== Gio.FileType.DIRECTORY)
+ return null;
+ const uuid = info.get_name();
+ return uuid;
+ });
+ }
+ const enabled = Main.extensionManager._enabledExtensions;
+ result = _installedExtensions.filter(ext => enabled.includes(ext));
+ return result.filter(uuid => uuid !== null && uuid.includes(pattern));
+}
+
+function* collectFromDatadirs(subdir, includeUserDir) {
+ let dataDirs = GLib.get_system_data_dirs();
+ if (includeUserDir)
+ dataDirs.unshift(GLib.get_user_data_dir());
+
+ for (let i = 0; i < dataDirs.length; i++) {
+ let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', subdir]);
+ let dir = Gio.File.new_for_path(path);
+
+ let fileEnum;
+ try {
+ fileEnum = dir.enumerate_children('standard::name,standard::type',
+ Gio.FileQueryInfoFlags.NONE, null);
+ } catch (e) {
+ fileEnum = null;
+ }
+ if (fileEnum !== null) {
+ let info;
+ while ((info = fileEnum.next_file(null)))
+ yield { dir: fileEnum.get_child(info), info };
+ }
+ }
}
function getScrollDirection(event) {
diff --git a/extensions/44/vertical-workspaces/lib/winTmb.js b/extensions/44/vertical-workspaces/lib/winTmb.js
new file mode 100644
index 0000000..b18ea18
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/winTmb.js
@@ -0,0 +1,525 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * WinTmb
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2021-2023
+ * @license GPL-3.0
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Meta = imports.gi.Meta;
+const St = imports.gi.St;
+
+const AltTab = imports.ui.altTab;
+const DND = imports.ui.dnd;
+const Main = imports.ui.main;
+
+let Me;
+let opt;
+
+const SCROLL_ICON_OPACITY = 240;
+const DRAG_OPACITY = 200;
+const CLOSE_BTN_OPACITY = 240;
+
+
+var WinTmbModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this._removeTimeouts();
+
+ this.moduleEnabled = opt.get('windowThumbnailModule');
+
+ reset = reset || !this.moduleEnabled;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WinTmb - Keeping untouched');
+ }
+
+ _activateModule() {
+ this._timeouts = {};
+ if (!this._windowThumbnails)
+ this._windowThumbnails = [];
+
+ Main.overview.connectObject('hidden', () => this.showThumbnails(), this);
+ console.debug(' WinTmb - Activated');
+ }
+
+ _disableModule() {
+ Main.overview.disconnectObject(this);
+ this._disconnectStateAdjustment();
+ this.removeAllThumbnails();
+ console.debug(' WinTmb - Disabled');
+ }
+
+ _removeTimeouts() {
+ if (this._timeouts) {
+ Object.values(this._timeouts).forEach(t => {
+ if (t)
+ GLib.source_remove(t);
+ });
+ this._timeouts = null;
+ }
+ }
+
+ createThumbnail(metaWin) {
+ const thumbnail = new WindowThumbnail(metaWin, {
+ 'height': Math.floor(opt.WINDOW_THUMBNAIL_SCALE * global.display.get_monitor_geometry(global.display.get_current_monitor()).height),
+ 'thumbnailsOnScreen': this._windowThumbnails.length,
+ });
+
+ this._windowThumbnails.push(thumbnail);
+ thumbnail.connect('removed', tmb => {
+ this._windowThumbnails.splice(this._windowThumbnails.indexOf(tmb), 1);
+ tmb.destroy();
+ if (!this._windowThumbnails.length)
+ this._disconnectStateAdjustment();
+ });
+
+ if (!this._stateAdjustmentConId) {
+ this._stateAdjustmentConId = Main.overview._overview.controls._stateAdjustment.connectObject('notify::value', () => {
+ if (!this._thumbnailsHidden && (!opt.OVERVIEW_MODE2 || opt.WORKSPACE_MODE))
+ this.hideThumbnails();
+ }, this);
+ }
+ }
+
+ hideThumbnails() {
+ this._windowThumbnails.forEach(tmb => {
+ tmb.ease({
+ opacity: 0,
+ duration: 200,
+ mode: Clutter.AnimationMode.LINEAR,
+ onComplete: () => tmb.hide(),
+ });
+ });
+ this._thumbnailsHidden = true;
+ }
+
+ showThumbnails() {
+ this._windowThumbnails.forEach(tmb => {
+ tmb.show();
+ tmb.ease({
+ opacity: 255,
+ duration: 100,
+ mode: Clutter.AnimationMode.LINEAR,
+ });
+ });
+ this._thumbnailsHidden = false;
+ }
+
+ removeAllThumbnails() {
+ this._windowThumbnails.forEach(tmb => tmb.remove());
+ this._windowThumbnails = [];
+ }
+
+ _disconnectStateAdjustment() {
+ Main.overview._overview.controls._stateAdjustment.disconnectObject(this);
+ }
+};
+
+const WindowThumbnail = GObject.registerClass({
+ Signals: { 'removed': {} },
+}, class WindowThumbnail extends St.Widget {
+ _init(metaWin, args) {
+ this._hoverShowsPreview = false;
+ this._customOpacity = 255;
+ this._initTmbHeight = args.height;
+ this._minimumHeight = Math.floor(5 / 100 * global.display.get_monitor_geometry(global.display.get_current_monitor()).height);
+ this._scrollTimeout = 100;
+ this._positionOffset = args.thumbnailsOnScreen;
+ this._reverseTmbWheelFunc = false;
+ this._click_count = 1;
+ this._prevBtnPressTime = 0;
+ this.w = metaWin;
+ super._init({
+ layout_manager: new Clutter.BinLayout(),
+ visible: true,
+ reactive: true,
+ can_focus: true,
+ track_hover: true,
+ });
+ this.connect('button-release-event', this._onBtnReleased.bind(this));
+ this.connect('scroll-event', this._onScrollEvent.bind(this));
+ // this.connect('motion-event', this._onMouseMove.bind(this)); // may be useful in the future..
+
+ this._delegate = this;
+ this._draggable = DND.makeDraggable(this, { dragActorOpacity: DRAG_OPACITY });
+ this._draggable.connect('drag-end', this._end_drag.bind(this));
+ this._draggable.connect('drag-cancelled', this._end_drag.bind(this));
+ this._draggable._animateDragEnd = eventTime => {
+ this._draggable._animationInProgress = true;
+ this._draggable._onAnimationComplete(this._draggable._dragActor, eventTime);
+ this.opacity = this._customOpacity;
+ };
+
+ this.clone = new Clutter.Clone({ reactive: true });
+ Main.layoutManager.addChrome(this);
+
+ this.window = this.w.get_compositor_private();
+
+ this.clone.set_source(this.window);
+
+ this.add_child(this.clone);
+ this._addCloseButton();
+ this._addScrollModeIcon();
+
+ this.connect('enter-event', () => {
+ global.display.set_cursor(Meta.Cursor.POINTING_HAND);
+ this._closeButton.opacity = CLOSE_BTN_OPACITY;
+ this._scrollModeBin.opacity = SCROLL_ICON_OPACITY;
+ if (this._hoverShowsPreview && !Main.overview._shown) {
+ this._closeButton.opacity = 50;
+ this._showWindowPreview(false, true);
+ }
+ });
+
+ this.connect('leave-event', () => {
+ global.display.set_cursor(Meta.Cursor.DEFAULT);
+ this._closeButton.opacity = 0;
+ this._scrollModeBin.opacity = 0;
+ if (this._winPreview)
+ this._destroyWindowPreview();
+ });
+
+ this._setSize(true);
+ this.set_position(...this._getInitialPosition());
+ this.show();
+ this.window_id = this.w.get_id();
+ this.tmbRedrawDirection = true;
+
+ // remove thumbnail content and hide thumbnail if its window is destroyed
+ this.windowConnect = this.window.connect('destroy', () => {
+ if (this)
+ this.remove();
+ });
+ }
+
+ _getInitialPosition() {
+ const offset = 20;
+ let monitor = Main.layoutManager.monitors[global.display.get_current_monitor()];
+ let x = Math.min(monitor.x + monitor.width - (this.window.width * this.scale) - offset);
+ let y = Math.min(monitor.y + monitor.height - (this.window.height * this.scale) - offset - ((this._positionOffset * this._initTmbHeight) % (monitor.height - this._initTmbHeight)));
+ return [x, y];
+ }
+
+ _setSize(resetScale = false) {
+ if (resetScale)
+ this.scale = Math.min(1.0, this._initTmbHeight / this.window.height);
+
+ const width = this.window.width * this.scale;
+ const height = this.window.height * this.scale;
+ this.set_size(width, height);
+ if (this.icon) {
+ this.icon.scale_x = this.scale;
+ this.icon.scale_y = this.scale;
+ }
+
+ // when the scale of this. actor change, this.clone resize accordingly,
+ // but the reactive area of the actor doesn't change until the actor is redrawn
+ // this updates the actor's input region area:
+ Main.layoutManager._queueUpdateRegions();
+ }
+
+ /* _onMouseMove(actor, event) {
+ let [pos_x, pos_y] = event.get_coords();
+ let state = event.get_state();
+ if (this._ctrlPressed(state)) {
+ }
+ }*/
+
+ _onBtnReleased(actor, event) {
+ // Clutter.Event.click_count property in no longer available, since GS42
+ if ((event.get_time() - this._prevBtnPressTime) < Clutter.Settings.get_default().double_click_time)
+ this._click_count += 1;
+ else
+ this._click_count = 1;
+
+ this._prevBtnPressTime = event.get_time();
+
+ if (this._click_count === 2 && event.get_button() === Clutter.BUTTON_PRIMARY)
+ this.w.activate(global.get_current_time());
+
+
+ const button = event.get_button();
+ const state = event.get_state();
+ switch (button) {
+ case Clutter.BUTTON_PRIMARY:
+ if (this._ctrlPressed(state)) {
+ this._setSize();
+ } else {
+ this._reverseTmbWheelFunc = !this._reverseTmbWheelFunc;
+ this._scrollModeBin.set_child(this._reverseTmbWheelFunc ? this._scrollModeSourceIcon : this._scrollModeResizeIcon);
+ }
+ return Clutter.EVENT_STOP;
+ case Clutter.BUTTON_SECONDARY:
+ if (this._ctrlPressed(state)) {
+ this.remove();
+ } else {
+ this._hoverShowsPreview = !this._hoverShowsPreview;
+ this._showWindowPreview();
+ }
+ return Clutter.EVENT_STOP;
+ case Clutter.BUTTON_MIDDLE:
+ if (this._ctrlPressed(state))
+ this.w.delete(global.get_current_time());
+ return Clutter.EVENT_STOP;
+ default:
+ return Clutter.EVENT_PROPAGATE;
+ }
+ }
+
+ _onScrollEvent(actor, event) {
+ let direction = Me.Util.getScrollDirection(event);
+
+ if (this._actionTimeoutActive())
+ return Clutter.EVENT_PROPAGATE;
+ let state = event.get_state();
+ switch (direction) {
+ case Clutter.ScrollDirection.UP:
+ if (this._shiftPressed(state)) {
+ this.opacity = Math.min(255, this.opacity + 24);
+ this._customOpacity = this.opacity;
+ } else if (this._reverseTmbWheelFunc !== this._ctrlPressed(state)) {
+ this._switchSourceWin(-1);
+ } else if (this._reverseTmbWheelFunc === this._ctrlPressed(state)) {
+ this.scale = Math.max(0.05, this.scale - 0.025);
+ }
+ break;
+ case Clutter.ScrollDirection.DOWN:
+ if (this._shiftPressed(state)) {
+ this.opacity = Math.max(48, this.opacity - 24);
+ this._customOpacity = this.opacity;
+ } else if (this._reverseTmbWheelFunc !== this._ctrlPressed(state)) {
+ this._switchSourceWin(+1);
+ } else if (this._reverseTmbWheelFunc === this._ctrlPressed(state)) {
+ this.scale = Math.min(1, this.scale + 0.025);
+ }
+ break;
+ default:
+ return Clutter.EVENT_PROPAGATE;
+ }
+ this._setSize();
+ return Clutter.EVENT_STOP;
+ }
+
+ remove() {
+ if (this.clone) {
+ this.window.disconnect(this.windowConnect);
+ this.clone.set_source(null);
+ }
+ if (this._winPreview)
+ this._destroyWindowPreview();
+
+ this.emit('removed');
+ }
+
+ _end_drag() {
+ this.set_position(this._draggable._dragOffsetX + this._draggable._dragX, this._draggable._dragOffsetY + this._draggable._dragY);
+ this._setSize();
+ }
+
+ _ctrlPressed(state) {
+ return (state & Clutter.ModifierType.CONTROL_MASK) !== 0;
+ }
+
+ _shiftPressed(state) {
+ return (state & Clutter.ModifierType.SHIFT_MASK) !== 0;
+ }
+
+ _switchSourceWin(direction) {
+ let windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL, null);
+ windows = windows.filter(w => !(w.skip_taskbar || w.minimized));
+ let idx = -1;
+ for (let i = 0; i < windows.length; i++) {
+ if (windows[i] === this.w) {
+ idx = i + direction;
+ break;
+ }
+ }
+ idx = idx >= windows.length ? 0 : idx;
+ idx = idx < 0 ? windows.length - 1 : idx;
+ let w = windows[idx];
+ let win = w.get_compositor_private();
+ this.clone.set_source(win);
+ this.window.disconnect(this.windowConnect);
+ // the new thumbnail should be the same height as the previous one
+ this.scale = (this.scale * this.window.height) / win.height;
+ this.window = win;
+ this.windowConnect = this.window.connect('destroy', () => {
+ if (this)
+ this.remove();
+ });
+ this.w = w;
+
+ if (this._winPreview)
+ this._showWindowPreview(true);
+ }
+
+ _actionTimeoutActive() {
+ const timeout = this._reverseTmbWheelFunc ? this._scrollTimeout : this._scrollTimeout / 4;
+ if (!this._lastActionTime || Date.now() - this._lastActionTime > timeout) {
+ this._lastActionTime = Date.now();
+ return false;
+ }
+ return true;
+ }
+
+ /* _setIcon() {
+ let tracker = Shell.WindowTracker.get_default();
+ let app = tracker.get_window_app(this.w);
+ let icon = app
+ ? app.create_icon_texture(this.height)
+ : new St.Icon({ icon_name: 'icon-missing', icon_size: this.height });
+ icon.x_expand = icon.y_expand = true;
+ if (this.icon)
+ this.icon.destroy();
+ this.icon = icon;
+ }*/
+
+ _addCloseButton() {
+ const closeButton = new St.Button({
+ opacity: 0,
+ style_class: 'window-close',
+ child: new St.Icon({ icon_name: 'preview-close-symbolic' }),
+ x_align: Clutter.ActorAlign.END,
+ y_align: Clutter.ActorAlign.START,
+ x_expand: true,
+ y_expand: true,
+ });
+
+ closeButton.set_style(`
+ margin: 3px;
+ background-color: rgba(200, 0, 0, 0.9);
+ `);
+
+ closeButton.connect('clicked', () => {
+ this.remove();
+ return Clutter.EVENT_STOP;
+ });
+
+ this._closeButton = closeButton;
+ this.add_child(this._closeButton);
+ }
+
+ _addScrollModeIcon() {
+ this._scrollModeBin = new St.Bin({
+ x_expand: true,
+ y_expand: true,
+ });
+ this._scrollModeResizeIcon = new St.Icon({
+ icon_name: 'view-fullscreen-symbolic',
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.END,
+ x_expand: true,
+ y_expand: true,
+ opacity: SCROLL_ICON_OPACITY,
+ style_class: 'icon-dropshadow',
+ scale_x: 0.5,
+ scale_y: 0.5,
+ });
+ this._scrollModeResizeIcon.set_style(`
+ margin: 13px;
+ color: rgb(255, 255, 255);
+ box-shadow: 0 0 40px 40px rgba(0,0,0,0.7);
+ `);
+ this._scrollModeSourceIcon = new St.Icon({
+ icon_name: 'media-skip-forward-symbolic',
+ x_align: Clutter.ActorAlign.CENTER,
+ y_align: Clutter.ActorAlign.END,
+ x_expand: true,
+ y_expand: true,
+ opacity: SCROLL_ICON_OPACITY,
+ style_class: 'icon-dropshadow',
+ scale_x: 0.5,
+ scale_y: 0.5,
+ });
+ this._scrollModeSourceIcon.set_style(`
+ margin: 13px;
+ color: rgb(255, 255, 255);
+ box-shadow: 0 0 40px 40px rgba(0,0,0,0.7);
+ `);
+ this._scrollModeBin.set_child(this._scrollModeResizeIcon);
+ this.add_child(this._scrollModeBin);
+ this._scrollModeBin.opacity = 0;
+ }
+
+ _showWindowPreview(update = false, dontDestroy = false) {
+ if (this._winPreview && !dontDestroy) {
+ this._destroyWindowPreview();
+ this._previewCreationTime = 0;
+ this._closeButton.opacity = CLOSE_BTN_OPACITY;
+ if (!update)
+ return;
+ }
+
+ if (!this._winPreview) {
+ this._winPreview = new AltTab.CyclerHighlight();
+ global.window_group.add_actor(this._winPreview);
+ [this._winPreview._xPointer, this._winPreview._yPointer] = global.get_pointer();
+ }
+
+ if (!update) {
+ this._winPreview.opacity = 0;
+ this._winPreview.ease({
+ opacity: 255,
+ duration: 70,
+ mode: Clutter.AnimationMode.LINEAR,
+ /* onComplete: () => {
+ this._closeButton.opacity = 50;
+ },*/
+ });
+
+ this.ease({
+ opacity: Math.min(50, this._customOpacity),
+ duration: 70,
+ mode: Clutter.AnimationMode.LINEAR,
+ onComplete: () => {
+ },
+ });
+ } else {
+ this._winPreview.opacity = 255;
+ }
+ this._winPreview.window = this.w;
+ this._winPreview._window = this.w;
+ global.window_group.set_child_above_sibling(this._winPreview, null);
+ }
+
+ _destroyWindowPreview() {
+ if (this._winPreview) {
+ this._winPreview.ease({
+ opacity: 0,
+ duration: 100,
+ mode: Clutter.AnimationMode.LINEAR,
+ onComplete: () => {
+ this._winPreview.destroy();
+ this._winPreview = null;
+ this.opacity = this._customOpacity;
+ },
+ });
+ }
+ }
+});
diff --git a/extensions/vertical-workspaces/lib/windowAttentionHandler.js b/extensions/44/vertical-workspaces/lib/windowAttentionHandler.js
index 10703c2..a3db986 100644
--- a/extensions/vertical-workspaces/lib/windowAttentionHandler.js
+++ b/extensions/44/vertical-workspaces/lib/windowAttentionHandler.js
@@ -11,47 +11,69 @@
'use strict';
const Main = imports.ui.main;
-const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const MessageTray = imports.ui.messageTray;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-
-const _Util = Me.imports.lib.util;
+const WindowAttentionHandler = imports.ui.windowAttentionHandler;
+let Me;
let opt;
-let _firstRun = false;
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('winAttentionHandlerModule', true);
- reset = reset || !moduleEnabled;
+var WindowAttentionHandlerModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
- if (_firstRun && reset)
- return;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
- _firstRun = false;
- if (reset) {
- reset = true;
- _updateConnections(reset);
+ cleanGlobals() {
+ Me = null;
opt = null;
- return;
}
- _updateConnections();
-}
+ update(reset) {
+ this.moduleEnabled = opt.get('windowAttentionHandlerModule');
+ const conflict = false;
-function _updateConnections(reset) {
- global.display.disconnectObject(Main.windowAttentionHandler);
+ reset = reset || !this.moduleEnabled || conflict;
- const handlerFnc = reset
- ? Main.windowAttentionHandler._onWindowDemandsAttention
- : WindowAttentionHandlerCommon._onWindowDemandsAttention;
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WindowAttentionHandlerModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ this._updateConnections();
+ console.debug(' WindowAttentionHandlerModule - Activated');
+ }
- global.display.connectObject(
- 'window-demands-attention', handlerFnc.bind(Main.windowAttentionHandler),
- 'window-marked-urgent', handlerFnc.bind(Main.windowAttentionHandler),
- Main.windowAttentionHandler);
-}
+ _disableModule() {
+ const reset = true;
+ this._updateConnections(reset);
+
+ console.debug(' WindowAttentionHandlerModule - Disabled');
+ }
+
+ _updateConnections(reset) {
+ global.display.disconnectObject(Main.windowAttentionHandler);
+
+ const handlerFnc = reset
+ ? Main.windowAttentionHandler._onWindowDemandsAttention
+ : WindowAttentionHandlerCommon._onWindowDemandsAttention;
+
+ global.display.connectObject(
+ 'window-demands-attention', handlerFnc.bind(Main.windowAttentionHandler),
+ 'window-marked-urgent', handlerFnc.bind(Main.windowAttentionHandler),
+ Main.windowAttentionHandler);
+ }
+};
const WindowAttentionHandlerCommon = {
_onWindowDemandsAttention(display, window) {
diff --git a/extensions/vertical-workspaces/lib/windowManager.js b/extensions/44/vertical-workspaces/lib/windowManager.js
index 2d46b0b..0cae6aa 100644
--- a/extensions/vertical-workspaces/lib/windowManager.js
+++ b/extensions/44/vertical-workspaces/lib/windowManager.js
@@ -10,81 +10,101 @@
'use strict';
-const { GObject, Clutter, Meta } = imports.gi;
+const Clutter = imports.gi.Clutter;
+const GObject = imports.gi.GObject;
+const Meta = imports.gi.Meta;
const Main = imports.ui.main;
const WindowManager = imports.ui.windowManager;
-const Me = imports.misc.extensionUtils.getCurrentExtension();
-const _Util = Me.imports.lib.util;
-let _overrides;
-
-const MINIMIZE_WINDOW_ANIMATION_TIME = WindowManager.MINIMIZE_WINDOW_ANIMATION_TIME;
-const MINIMIZE_WINDOW_ANIMATION_MODE = WindowManager.MINIMIZE_WINDOW_ANIMATION_MODE;
+let Me;
let opt;
-let _firstRun = true;
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('windowManagerModule', true);
- reset = reset || !moduleEnabled;
+var WindowManagerModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
- // don't even touch this module if disabled
- if (_firstRun && reset)
- return;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
- _firstRun = false;
+ this._originalMinimizeSigId = 0;
+ this._minimizeSigId = 0;
+ this._originalUnminimizeSigId = 0;
+ this._unminimizeSigId = 0;
+ }
- if (_overrides)
- _overrides.removeAll();
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+ update(reset) {
+ this.moduleEnabled = opt.get('windowManagerModule');
+ const conflict = false;
- _replaceMinimizeFunction(reset);
+ reset = reset || !this.moduleEnabled || conflict;
+ // don't even touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WindowManagerModule - Keeping untouched');
+ }
- if (reset) {
- _overrides = null;
- opt = null;
- return;
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._overrides.addOverride('WindowManager', WindowManager.WindowManager.prototype, WindowManagerCommon);
+
+ if (!this._minimizeSigId) {
+ this._originalMinimizeSigId = GObject.signal_handler_find(Main.wm._shellwm, { signalId: 'minimize' });
+ if (this._originalMinimizeSigId) {
+ Main.wm._shellwm.block_signal_handler(this._originalMinimizeSigId);
+ this._minimizeSigId = Main.wm._shellwm.connect('minimize', WindowManagerCommon._minimizeWindow.bind(Main.wm));
+ }
+
+ this._originalUnminimizeSigId = GObject.signal_handler_find(Main.wm._shellwm, { signalId: 'unminimize' });
+ if (this._originalUnminimizeSigId) {
+ Main.wm._shellwm.block_signal_handler(this._originalUnminimizeSigId);
+ this._unminimizeSigId = Main.wm._shellwm.connect('unminimize', WindowManagerCommon._unminimizeWindow.bind(Main.wm));
+ }
+ }
+ console.debug(' WindowManagerModule - Activated');
}
- _overrides = new _Util.Overrides();
-
- _overrides.addOverride('WindowManager', WindowManager.WindowManager.prototype, WindowManagerCommon);
-}
-
-// ------------- Fix and adapt minimize/unminimize animations --------------------------------------
-
-let _originalMinimizeSigId;
-let _minimizeSigId;
-let _originalUnminimizeSigId;
-let _unminimizeSigId;
-
-function _replaceMinimizeFunction(reset = false) {
- if (reset) {
- Main.wm._shellwm.disconnect(_minimizeSigId);
- _minimizeSigId = 0;
- Main.wm._shellwm.unblock_signal_handler(_originalMinimizeSigId);
- _originalMinimizeSigId = 0;
-
- Main.wm._shellwm.disconnect(_unminimizeSigId);
- _unminimizeSigId = 0;
- Main.wm._shellwm.unblock_signal_handler(_originalUnminimizeSigId);
- _originalUnminimizeSigId = 0;
- } else if (!_minimizeSigId) {
- _originalMinimizeSigId = GObject.signal_handler_find(Main.wm._shellwm, { signalId: 'minimize' });
- if (_originalMinimizeSigId) {
- Main.wm._shellwm.block_signal_handler(_originalMinimizeSigId);
- _minimizeSigId = Main.wm._shellwm.connect('minimize', WindowManagerCommon._minimizeWindow.bind(Main.wm));
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ if (this._minimizeSigId) {
+ Main.wm._shellwm.disconnect(this._minimizeSigId);
+ this._minimizeSigId = 0;
+ }
+ if (this._originalMinimizeSigId) {
+ Main.wm._shellwm.unblock_signal_handler(this._originalMinimizeSigId);
+ this._originalMinimizeSigId = 0;
}
- _originalUnminimizeSigId = GObject.signal_handler_find(Main.wm._shellwm, { signalId: 'unminimize' });
- if (_originalUnminimizeSigId) {
- Main.wm._shellwm.block_signal_handler(_originalUnminimizeSigId);
- _unminimizeSigId = Main.wm._shellwm.connect('unminimize', WindowManagerCommon._unminimizeWindow.bind(Main.wm));
+ if (this._unminimizeSigId) {
+ Main.wm._shellwm.disconnect(this._unminimizeSigId);
+ this._unminimizeSigId = 0;
+ }
+ if (this._originalUnminimizeSigId) {
+ Main.wm._shellwm.unblock_signal_handler(this._originalUnminimizeSigId);
+ this._originalUnminimizeSigId = 0;
}
+
+ console.debug(' WindowManagerModule - Disabled');
}
-}
+};
// fix for mainstream bug - fullscreen windows should minimize using opacity transition
// but its being applied directly on window actor and that doesn't work
@@ -109,8 +129,8 @@ const WindowManagerCommon = {
/* if (actor.meta_window.is_monitor_sized()) {
actor.get_first_child().ease({
opacity: 0,
- duration: MINIMIZE_WINDOW_ANIMATION_TIME,
- mode: MINIMIZE_WINDOW_ANIMATION_MODE,
+ duration: WindowManager.MINIMIZE_WINDOW_ANIMATION_TIME,
+ mode: WindowManager.MINIMIZE_WINDOW_ANIMATION_MODE,
onStopped: () => this._minimizeWindowDone(shellwm, actor),
});
} else { */
@@ -140,8 +160,8 @@ const WindowManagerCommon = {
scale_y: yScale,
x: xDest,
y: yDest,
- duration: MINIMIZE_WINDOW_ANIMATION_TIME,
- mode: MINIMIZE_WINDOW_ANIMATION_MODE,
+ duration: WindowManager.MINIMIZE_WINDOW_ANIMATION_TIME,
+ mode: WindowManager.MINIMIZE_WINDOW_ANIMATION_MODE,
onStopped: () => this._minimizeWindowDone(shellwm, actor),
});
// }
@@ -176,8 +196,8 @@ const WindowManagerCommon = {
actor.set_scale(1.0, 1.0);
actor.ease({
opacity: 255,
- duration: MINIMIZE_WINDOW_ANIMATION_TIME,
- mode: MINIMIZE_WINDOW_ANIMATION_MODE,
+ duration: WindowManager.MINIMIZE_WINDOW_ANIMATION_TIME,
+ mode: WindowManager.MINIMIZE_WINDOW_ANIMATION_MODE,
onStopped: () => this._unminimizeWindowDone(shellwm, actor),
});
} else { */
@@ -208,8 +228,8 @@ const WindowManagerCommon = {
scale_y: 1,
x: xDest,
y: yDest,
- duration: MINIMIZE_WINDOW_ANIMATION_TIME,
- mode: MINIMIZE_WINDOW_ANIMATION_MODE,
+ duration: WindowManager.MINIMIZE_WINDOW_ANIMATION_TIME,
+ mode: WindowManager.MINIMIZE_WINDOW_ANIMATION_MODE,
onStopped: () => this._unminimizeWindowDone(shellwm, actor),
});
// }
diff --git a/extensions/44/vertical-workspaces/lib/windowPreview.js b/extensions/44/vertical-workspaces/lib/windowPreview.js
new file mode 100644
index 0000000..2766138
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/windowPreview.js
@@ -0,0 +1,633 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * windowPreview.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+const Atk = imports.gi.Atk;
+const GLib = imports.gi.GLib;
+const Graphene = imports.gi.Graphene;
+const Meta = imports.gi.Meta;
+const Pango = imports.gi.Pango;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const DND = imports.ui.dnd;
+const Main = imports.ui.main;
+const OverviewControls = imports.ui.overviewControls;
+const WindowPreview = imports.ui.windowPreview;
+
+let Me;
+let opt;
+
+const WINDOW_SCALE_TIME = 200;
+const WINDOW_ACTIVE_SIZE_INC = 5;
+const WINDOW_OVERLAY_FADE_TIME = 200;
+const WINDOW_DND_SIZE = 256;
+const DRAGGING_WINDOW_OPACITY = 100;
+
+const ControlsState = OverviewControls.ControlsState;
+
+var WindowPreviewModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('windowPreviewModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WindowPreviewModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._overrides.addOverride('WindowPreview', WindowPreview.WindowPreview.prototype, WindowPreviewCommon);
+ // A shorter timeout allows user to quickly cancel the selection by leaving the preview with the mouse pointer
+ if (opt.ALWAYS_ACTIVATE_SELECTED_WINDOW)
+ WindowPreview.WINDOW_OVERLAY_IDLE_HIDE_TIMEOUT = 150;
+ console.debug(' WindowPreviewModule - Activated');
+ }
+
+ _disableModule() {
+ // If WindowPreview._init was injected by another extension (like Burn My Windows)
+ // which enables/disables before V-Shell
+ // don't restore the original if it's not injected,
+ // because it would restore injected _init and recursion would freeze GS when extensions are enabled again.
+ // This can happen when all extension re-enabled, not only when screen is locked/unlocked
+ // If _init doesn't include "fn.apply(this, args)" when reset === true, some extension already restored the original
+ const skipReset = WindowPreview.WindowPreview.prototype._init.toString().includes('fn.apply(this, args)');
+ if (this._overrides && skipReset) {
+ // skip restoring original _init()
+ this._overrides['_init'] = null;
+ }
+
+ if (this._overrides)
+ this._overrides.removeAll();
+
+ this._overrides = null;
+
+ console.debug(' WindowPreviewModule - Disabled');
+ }
+};
+
+const WindowPreviewCommon = {
+ _init(metaWindow, workspace, overviewAdjustment) {
+ this.metaWindow = metaWindow;
+ this.metaWindow._delegate = this;
+ this._windowActor = metaWindow.get_compositor_private();
+ this._workspace = workspace;
+ this._overviewAdjustment = overviewAdjustment;
+
+ const ICON_SIZE = opt.WIN_PREVIEW_ICON_SIZE;
+ const ICON_OVERLAP = 0.7;
+
+ Shell.WindowPreview.prototype._init.bind(this)({
+ reactive: true,
+ can_focus: true,
+ accessible_role: Atk.Role.PUSH_BUTTON,
+ offscreen_redirect: Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY,
+ });
+
+ const windowContainer = new Clutter.Actor({
+ pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
+ });
+ this.window_container = windowContainer;
+
+ windowContainer.connect('notify::scale-x',
+ () => this._adjustOverlayOffsets());
+ // gjs currently can't handle setting an actors layout manager during
+ // the initialization of the actor if that layout manager keeps track
+ // of its container, so set the layout manager after creating the
+ // container
+ windowContainer.layout_manager = new Shell.WindowPreviewLayout();
+ this.add_child(windowContainer);
+
+ this._addWindow(metaWindow);
+
+ this._delegate = this;
+
+ this._stackAbove = null;
+
+ this._cachedBoundingBox = {
+ x: windowContainer.layout_manager.bounding_box.x1,
+ y: windowContainer.layout_manager.bounding_box.y1,
+ width: windowContainer.layout_manager.bounding_box.get_width(),
+ height: windowContainer.layout_manager.bounding_box.get_height(),
+ };
+
+ windowContainer.layout_manager.connect(
+ 'notify::bounding-box', layout => {
+ this._cachedBoundingBox = {
+ x: layout.bounding_box.x1,
+ y: layout.bounding_box.y1,
+ width: layout.bounding_box.get_width(),
+ height: layout.bounding_box.get_height(),
+ };
+
+ // A bounding box of 0x0 means all windows were removed
+ if (layout.bounding_box.get_area() > 0)
+ this.emit('size-changed');
+ });
+
+ this._windowActor.connectObject('destroy', () => this.destroy(), this);
+
+ this._updateAttachedDialogs();
+
+ let clickAction = new Clutter.ClickAction();
+ clickAction.connect('clicked', act => {
+ const button = act.get_button();
+ if (button === Clutter.BUTTON_SECONDARY) {
+ if (opt.WIN_PREVIEW_SEC_BTN_ACTION === 1) {
+ this._closeWinAction();
+ return Clutter.EVENT_STOP;
+ } else if (opt.WIN_PREVIEW_SEC_BTN_ACTION === 2) {
+ this._searchAppWindowsAction();
+ return Clutter.EVENT_STOP;
+ } else if (opt.WIN_PREVIEW_SEC_BTN_ACTION === 3 && opt.WINDOW_THUMBNAIL_ENABLED) {
+ this._removeLaters();
+ Me.Modules.winTmbModule.createThumbnail(metaWindow);
+ return Clutter.EVENT_STOP;
+ }
+ } else if (button === Clutter.BUTTON_MIDDLE) {
+ if (opt.WIN_PREVIEW_MID_BTN_ACTION === 1) {
+ this._closeWinAction();
+ return Clutter.EVENT_STOP;
+ } else if (opt.WIN_PREVIEW_MID_BTN_ACTION === 2) {
+ this._searchAppWindowsAction();
+ return Clutter.EVENT_STOP;
+ } else if (opt.WIN_PREVIEW_MID_BTN_ACTION === 3 && opt.WINDOW_THUMBNAIL_ENABLED) {
+ this._removeLaters();
+ Me.Modules.winTmbModule.createThumbnail(metaWindow);
+ return Clutter.EVENT_STOP;
+ }
+ }
+ return this._activate();
+ });
+
+
+ if (this._onLongPress) {
+ clickAction.connect('long-press', this._onLongPress.bind(this));
+ } else {
+ clickAction.connect('long-press', (action, actor, state) => {
+ if (state === Clutter.LongPressState.ACTIVATE)
+ this.showOverlay(true);
+ return true;
+ });
+ }
+
+ this.connect('destroy', this._onDestroy.bind(this));
+
+ this._draggable = DND.makeDraggable(this, {
+ restoreOnSuccess: true,
+ manualMode: !!this._onLongPress,
+ dragActorMaxSize: WINDOW_DND_SIZE,
+ dragActorOpacity: DRAGGING_WINDOW_OPACITY,
+ });
+
+ // _draggable.addClickAction is new in GS45
+ if (this._draggable.addClickAction)
+ this._draggable.addClickAction(clickAction);
+ else
+ this.add_action(clickAction);
+
+ this._draggable.connect('drag-begin', this._onDragBegin.bind(this));
+ this._draggable.connect('drag-cancelled', this._onDragCancelled.bind(this));
+ this._draggable.connect('drag-end', this._onDragEnd.bind(this));
+ this.inDrag = false;
+
+ this._selected = false;
+ this._overlayEnabled = true;
+ this._overlayShown = false;
+ this._closeRequested = false;
+ this._idleHideOverlayId = 0;
+
+ const tracker = Shell.WindowTracker.get_default();
+ const app = tracker.get_window_app(this.metaWindow);
+ this._icon = app.create_icon_texture(ICON_SIZE);
+ this._icon.add_style_class_name('icon-dropshadow');
+ this._icon.set({
+ reactive: true,
+ pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
+ });
+ this._icon.add_constraint(new Clutter.BindConstraint({
+ source: windowContainer,
+ coordinate: Clutter.BindCoordinate.POSITION,
+ }));
+ this._icon.add_constraint(new Clutter.AlignConstraint({
+ source: windowContainer,
+ align_axis: Clutter.AlignAxis.X_AXIS,
+ factor: 0.5,
+ }));
+ this._icon.add_constraint(new Clutter.AlignConstraint({
+ source: windowContainer,
+ align_axis: Clutter.AlignAxis.Y_AXIS,
+ pivot_point: new Graphene.Point({ x: -1, y: ICON_OVERLAP }),
+ factor: 1,
+ }));
+
+ if (opt.WINDOW_ICON_CLICK_ACTION) {
+ const iconClickAction = new Clutter.ClickAction();
+ iconClickAction.connect('clicked', act => {
+ if (act.get_button() === Clutter.BUTTON_PRIMARY) {
+ if (opt.WINDOW_ICON_CLICK_ACTION === 1) {
+ this._searchAppWindowsAction();
+ return Clutter.EVENT_STOP;
+ } else if (opt.WINDOW_ICON_CLICK_ACTION === 2 && opt.WINDOW_THUMBNAIL_ENABLED) {
+ this._removeLaters();
+ Me.Modules.winTmbModule.createThumbnail(metaWindow);
+ return Clutter.EVENT_STOP;
+ }
+ } /* else if (act.get_button() === Clutter.BUTTON_SECONDARY) {
+ return Clutter.EVENT_STOP;
+ }*/
+ return Clutter.EVENT_PROPAGATE;
+ });
+ this._icon.add_action(iconClickAction);
+ }
+ const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
+ this._title = new St.Label({
+ visible: false,
+ style_class: 'window-caption',
+ text: this._getCaption(),
+ reactive: true,
+ });
+ this._title.clutter_text.single_line_mode = true;
+ this._title.add_constraint(new Clutter.BindConstraint({
+ source: windowContainer,
+ coordinate: Clutter.BindCoordinate.X,
+ }));
+
+ let offset;
+ if (opt.WIN_TITLES_POSITION < 2) {
+ // we cannot get proper title height before it gets to the stage, so 35 is estimated height + spacing
+ offset = -scaleFactor * (ICON_SIZE * ICON_OVERLAP + 35);
+ } else {
+ offset = scaleFactor * (ICON_SIZE * (1 - ICON_OVERLAP) + 4);
+ }
+ this._title.add_constraint(new Clutter.BindConstraint({
+ source: windowContainer,
+ coordinate: Clutter.BindCoordinate.Y,
+ offset,
+ }));
+ this._title.add_constraint(new Clutter.AlignConstraint({
+ source: windowContainer,
+ align_axis: Clutter.AlignAxis.X_AXIS,
+ factor: 0.5,
+ }));
+ this._title.add_constraint(new Clutter.AlignConstraint({
+ source: windowContainer,
+ align_axis: Clutter.AlignAxis.Y_AXIS,
+ pivot_point: new Graphene.Point({ x: -1, y: 0 }),
+ factor: 1,
+ }));
+ this._title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
+ this.label_actor = this._title;
+ this.metaWindow.connectObject(
+ 'notify::title', () => (this._title.text = this._getCaption()),
+ this);
+
+ const layout = Meta.prefs_get_button_layout();
+ this._closeButtonSide =
+ layout.left_buttons.includes(Meta.ButtonFunction.CLOSE)
+ ? St.Side.LEFT : St.Side.RIGHT;
+ if (Me.shellVersion < 43) {
+ this._closeButton = new St.Button({
+ visible: false,
+ style_class: 'window-close',
+ child: new St.Icon({ icon_name: 'preview-close-symbolic' }),
+ });
+ } else {
+ this._closeButton = new St.Button({
+ visible: false,
+ style_class: 'window-close',
+ icon_name: 'preview-close-symbolic',
+ });
+ }
+ this._closeButton.add_constraint(new Clutter.BindConstraint({
+ source: windowContainer,
+ coordinate: Clutter.BindCoordinate.POSITION,
+ }));
+ this._closeButton.add_constraint(new Clutter.AlignConstraint({
+ source: windowContainer,
+ align_axis: Clutter.AlignAxis.X_AXIS,
+ pivot_point: new Graphene.Point({ x: 0.5, y: -1 }),
+ factor: this._closeButtonSide === St.Side.LEFT ? 0 : 1,
+ }));
+ this._closeButton.add_constraint(new Clutter.AlignConstraint({
+ source: windowContainer,
+ align_axis: Clutter.AlignAxis.Y_AXIS,
+ pivot_point: new Graphene.Point({ x: -1, y: 0.5 }),
+ factor: 0,
+ }));
+ this._closeButton.connect('clicked', () => this._deleteAll());
+
+ this.add_child(this._title);
+ this.add_child(this._icon);
+ this.add_child(this._closeButton);
+
+ this._overviewAdjustment.connectObject(
+ 'notify::value', () => this._updateIconScale(), this);
+ this._updateIconScale();
+
+ this.connect('notify::realized', () => {
+ if (!this.realized)
+ return;
+
+ this._title.ensure_style();
+ this._icon.ensure_style();
+ });
+
+ if (ICON_SIZE < 22) {
+ // disable app icon
+ this._icon.hide();
+ } else {
+ this._updateIconScale();
+ }
+
+
+
+ // if window is created while the overview is shown, icon and title should be visible immediately
+ if (Main.overview._overview._controls._stateAdjustment.value < 1) {
+ this._icon.scale_x = 0;
+ this._icon.scale_y = 0;
+ this._title.opacity = 0;
+ }
+
+ if (opt.ALWAYS_SHOW_WIN_TITLES)
+ this._title.show();
+
+ if (opt.OVERVIEW_MODE === 1) {
+ // spread windows on hover
+ this._wsStateConId = this.connect('enter-event', () => {
+ // don't spread windows if user don't use pointer device at this moment
+ if (global.get_pointer()[0] === opt.showingPointerX || Main.overview._overview._controls._stateAdjustment.value < 1)
+ return;
+
+ opt.WORKSPACE_MODE = 1;
+ const view = this._workspace.get_parent();
+ view.exposeWindows(this._workspace.metaWorkspace.index());
+ this.disconnect(this._wsStateConId);
+ });
+ }
+
+ if (opt.OVERVIEW_MODE) {
+ // show window icon and title on ws windows spread
+ this._stateAdjustmentSigId = this._workspace.stateAdjustment.connect('notify::value', this._updateIconScale.bind(this));
+ }
+
+ const metaWin = this.metaWindow;
+ if (opt.DASH_ISOLATE_WS && !metaWin._wsChangedConId) {
+ metaWin._wsChangedConId = metaWin.connect('workspace-changed',
+ () => Main.overview.dash._queueRedisplay());
+ } else if (!opt.DASH_ISOLATE_WS && metaWin._wsChangedConId) {
+ metaWin.disconnect(metaWin._wsChangedConId);
+ }
+ },
+
+ _closeWinAction() {
+ this.hide();
+ this._deleteAll();
+ },
+
+ _removeLaters() {
+ // this action cancels long-press event and the 'long-press-cancel' event is used by the Shell to actually initiate DnD
+ // so the dnd initiation needs to be removed
+ if (this._longPressLater) {
+ if (Meta.later_remove)
+ Meta.later_remove(this._longPressLater);
+ else
+ global.compositor.get_laters().remove(this._longPressLater);
+ delete this._longPressLater;
+ }
+ },
+
+ _searchAppWindowsAction() {
+ this._removeLaters();
+ const tracker = Shell.WindowTracker.get_default();
+ const appName = tracker.get_window_app(this.metaWindow).get_name();
+ Me.Util.activateSearchProvider(`${Me.WSP_PREFIX} ${appName}`);
+ },
+
+ _updateIconScale() {
+ let { currentState, initialState, finalState } =
+ this._overviewAdjustment.getStateTransitionParams();
+
+ // Current state - 0 - HIDDEN, 1 - WINDOW_PICKER, 2 - APP_GRID
+ const primaryMonitor = this.metaWindow.get_monitor() === global.display.get_primary_monitor();
+
+ const visible =
+ (initialState > ControlsState.HIDDEN || finalState > ControlsState.HIDDEN) &&
+ !(finalState === ControlsState.APP_GRID && opt.WS_ANIMATION && primaryMonitor);
+
+ let scale = 0;
+ if (visible)
+ scale = currentState >= 1 ? 1 : currentState % 1;
+
+ if (!primaryMonitor && opt.WORKSPACE_MODE &&
+ ((initialState === ControlsState.WINDOW_PICKER && finalState === ControlsState.APP_GRID) ||
+ (initialState === ControlsState.APP_GRID && finalState === ControlsState.WINDOW_PICKER))
+ )
+ scale = 1;
+ else if (!primaryMonitor && opt.OVERVIEW_MODE && !opt.WORKSPACE_MODE)
+ scale = 0;
+ /* } else if (primaryMonitor && ((initialState === ControlsState.WINDOW_PICKER && finalState === ControlsState.APP_GRID) ||
+ initialState === ControlsState.APP_GRID && finalState === ControlsState.HIDDEN)) {*/
+ else if (primaryMonitor && currentState > ControlsState.WINDOW_PICKER)
+ scale = 0;
+
+ // in static workspace mode show icon and title on windows expose
+ if (opt.OVERVIEW_MODE) {
+ if (currentState === 1)
+ scale = opt.WORKSPACE_MODE;
+ else if (finalState === 1 || (finalState === 0 && !opt.WORKSPACE_MODE))
+ return;
+ }
+
+ if (!opt.WS_ANIMATION && (Main.overview._overview.controls._searchController.searchActive ||
+ ((initialState === ControlsState.WINDOW_PICKER && finalState === ControlsState.APP_GRID) ||
+ (initialState === ControlsState.APP_GRID && finalState === ControlsState.WINDOW_PICKER)))
+ )
+ return;
+
+ // if titles are in 'always show' mode, we need to add transition between visible/invisible state
+ // but the transition is quite expensive,
+ // showing the titles at the end of the transition is good enough and workspace preview transition is much smoother
+ if (scale === 1) {
+ this._icon.set({
+ scale_x: 1,
+ scale_y: 1,
+ });
+ this._title.ease({
+ duration: 100,
+ opacity: 255,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ } else {
+ this._title.opacity = 0;
+ this._icon.set({
+ scale_x: scale,
+ scale_y: scale,
+ });
+ }
+ },
+
+ showOverlay(animate) {
+ if (!this._overlayEnabled)
+ return;
+
+ if (this._overlayShown)
+ return;
+
+ this._overlayShown = true;
+ if (opt.WIN_TITLES_POSITION === 2)
+ this._restack();
+
+ // If we're supposed to animate and an animation in our direction
+ // is already happening, let that one continue
+ const ongoingTransition = this._title.get_transition('opacity');
+ if (animate &&
+ ongoingTransition &&
+ ongoingTransition.get_interval().peek_final_value() === 255)
+ return;
+
+ const toShow = this._windowCanClose() && opt.SHOW_CLOSE_BUTTON
+ ? [this._closeButton]
+ : [];
+
+ if (!opt.ALWAYS_SHOW_WIN_TITLES)
+ toShow.push(this._title);
+
+
+ toShow.forEach(a => {
+ a.opacity = 0;
+ a.show();
+ a.ease({
+ opacity: 255,
+ duration: animate ? WINDOW_OVERLAY_FADE_TIME : 0,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ });
+
+ const [width, height] = this.window_container.get_size();
+ const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
+ const activeExtraSize = WINDOW_ACTIVE_SIZE_INC * 2 * scaleFactor;
+ const origSize = Math.max(width, height);
+ const scale = (origSize + activeExtraSize) / origSize;
+
+ this.window_container.ease({
+ scale_x: scale,
+ scale_y: scale,
+ duration: animate ? WINDOW_SCALE_TIME : 0,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+
+ this.emit('show-chrome');
+ },
+
+ hideOverlay(animate) {
+ if (!this._overlayShown)
+ return;
+ this._overlayShown = false;
+
+ if (opt.ALWAYS_ACTIVATE_SELECTED_WINDOW && Main.overview._overview.controls._stateAdjustment.value < 1)
+ this._activateSelected = true;
+
+
+ if (opt.WIN_TITLES_POSITION === 2)
+ this._restack();
+
+ // If we're supposed to animate and an animation in our direction
+ // is already happening, let that one continue
+ const ongoingTransition = this._title.get_transition('opacity');
+ if (animate &&
+ ongoingTransition &&
+ ongoingTransition.get_interval().peek_final_value() === 0)
+ return;
+
+ const toHide = [this._closeButton];
+
+ if (!opt.ALWAYS_SHOW_WIN_TITLES)
+ toHide.push(this._title);
+
+ toHide.forEach(a => {
+ a.opacity = 255;
+ a.ease({
+ opacity: 0,
+ duration: animate ? WINDOW_OVERLAY_FADE_TIME : 0,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => a.hide(),
+ });
+ });
+
+ if (this.window_container) {
+ this.window_container.ease({
+ scale_x: 1,
+ scale_y: 1,
+ duration: animate ? WINDOW_SCALE_TIME : 0,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+ },
+
+ _onDestroy() {
+ // workaround for upstream bug - hideOverlay is called after windowPreview is destroyed, from the leave event callback
+ // hiding the preview now avoids firing the post-mortem leave event
+ this.hide();
+ if (this._activateSelected)
+ this._activate();
+
+ this.metaWindow._delegate = null;
+ this._delegate = null;
+
+ if (this._longPressLater) {
+ if (Meta.later_add)
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, this._longPressLater);
+ else
+ global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, this._longPressLater);
+ delete this._longPressLater;
+ }
+
+ if (this._idleHideOverlayId > 0) {
+ GLib.source_remove(this._idleHideOverlayId);
+ this._idleHideOverlayId = 0;
+ }
+
+ if (this.inDrag) {
+ this.emit('drag-end');
+ this.inDrag = false;
+ }
+
+ if (this._stateAdjustmentSigId)
+ this._workspace.stateAdjustment.disconnect(this._stateAdjustmentSigId);
+ },
+};
diff --git a/extensions/vertical-workspaces/lib/windowSearchProvider.js b/extensions/44/vertical-workspaces/lib/windowSearchProvider.js
index 5f90784..b82f365 100644
--- a/extensions/vertical-workspaces/lib/windowSearchProvider.js
+++ b/extensions/44/vertical-workspaces/lib/windowSearchProvider.js
@@ -9,30 +9,23 @@
'use strict';
-const { GLib, Gio, Meta, St, Shell } = imports.gi;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Meta = imports.gi.Meta;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
const Main = imports.ui.main;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-const Settings = Me.imports.lib.settings;
-const _Util = Me.imports.lib.util;
+let Me;
+let opt;
// gettext
-const _ = Settings._;
-
-const shellVersion = Settings.shellVersion;
-
-const ModifierType = imports.gi.Clutter.ModifierType;
-
-let windowSearchProvider;
-let _enableTimeoutId = 0;
+let _;
// prefix helps to eliminate results from other search providers
// so it needs to be something less common
// needs to be accessible from vw module
-var prefix = 'wq//';
-
-let opt;
+const PREFIX = 'wq//';
const Action = {
NONE: 0,
@@ -42,66 +35,77 @@ const Action = {
MOVE_ALL_TO_WS: 4,
};
-function getOverviewSearchResult() {
- return Main.overview._overview.controls._searchController._searchResults;
-}
+var WindowSearchProviderModule = class {
+ // export for other modules
+ static _PREFIX = PREFIX;
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+ _ = Me.gettext;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ // export for other modules
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- if (!reset && opt.WINDOW_SEARCH_PROVIDER_ENABLED && !windowSearchProvider) {
- enable();
- } else if (reset || !opt.WINDOW_SEARCH_PROVIDER_ENABLED) {
- disable();
+ this._windowSearchProvider = null;
+ this._enableTimeoutId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
opt = null;
+ _ = null;
}
-}
-
-function enable() {
- // delay because Fedora had problem to register a new provider soon after Shell restarts
- _enableTimeoutId = GLib.timeout_add(
- GLib.PRIORITY_DEFAULT,
- 2000,
- () => {
- if (!windowSearchProvider) {
- windowSearchProvider = new WindowSearchProvider(opt);
- getOverviewSearchResult()._registerProvider(
- windowSearchProvider
- );
- }
- _enableTimeoutId = 0;
- return GLib.SOURCE_REMOVE;
+
+ update(reset) {
+ this.moduleEnabled = opt.get('windowSearchProviderModule');
+
+ reset = reset || !this.moduleEnabled;
+
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
}
- );
-}
+ if (reset && this._firstActivation)
+ console.debug(' WindowSearchProviderModule - Keeping untouched');
+ }
-function disable() {
- if (windowSearchProvider) {
- getOverviewSearchResult()._unregisterProvider(
- windowSearchProvider
+ _activateModule() {
+ // delay because Fedora had problem to register a new provider soon after Shell restarts
+ this._enableTimeoutId = GLib.timeout_add(
+ GLib.PRIORITY_DEFAULT,
+ 2000,
+ () => {
+ if (!this._windowSearchProvider) {
+ this._windowSearchProvider = new WindowSearchProvider(opt);
+ this._getOverviewSearchResult()._registerProvider(this._windowSearchProvider);
+ }
+ this._enableTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ }
);
- windowSearchProvider = null;
+ console.debug(' WindowSearchProviderModule - Activated');
}
- if (_enableTimeoutId) {
- GLib.source_remove(_enableTimeoutId);
- _enableTimeoutId = 0;
+
+ _disableModule() {
+ if (this._windowSearchProvider) {
+ this._getOverviewSearchResult()._unregisterProvider(this._windowSearchProvider);
+ this._windowSearchProvider = null;
+ }
+ if (this._enableTimeoutId) {
+ GLib.source_remove(this._enableTimeoutId);
+ this._enableTimeoutId = 0;
+ }
+
+ console.debug(' WindowSearchProviderModule - Disabled');
}
-}
-
-function makeResult(window, i) {
- const app = Shell.WindowTracker.get_default().get_window_app(window);
- const appName = app ? app.get_name() : 'Unknown';
- const windowTitle = window.get_title();
- const wsIndex = window.get_workspace().index();
-
- return {
- 'id': i,
- // convert all accented chars to their basic form and lower case for search
- 'name': `${wsIndex + 1}: ${windowTitle} ${appName}`.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(),
- appName,
- windowTitle,
- window,
- };
-}
+
+ _getOverviewSearchResult() {
+ return Main.overview._overview.controls._searchController._searchResults;
+ }
+};
const closeSelectedRegex = /^\/x!$/;
const closeAllResultsRegex = /^\/xa!$/;
@@ -110,15 +114,22 @@ const moveAllToWsRegex = /^\/ma[0-9]+$/;
const WindowSearchProvider = class WindowSearchProvider {
constructor() {
- this.id = `open-windows@${Me.metadata.uuid}`;
- this.appInfo = Gio.AppInfo.create_from_commandline('true', _('Open Windows'), null);
- this.appInfo.get_description = () => _('List of open windows');
- this.appInfo.get_name = () => _('Open Windows');
- this.appInfo.get_id = () => this.id;
- this.appInfo.get_icon = () => Gio.icon_new_for_string('focus-windows-symbolic');
- this.appInfo.should_show = () => true;
-
- this.canLaunchSearch = true;
+ this.id = 'open-windows';
+ const appSystem = Shell.AppSystem.get_default();
+ // use arbitrary app to get complete appInfo object
+ let appInfo = appSystem.lookup_app('com.matjakeman.ExtensionManager.desktop')?.get_app_info();
+ if (!appInfo)
+ appInfo = appSystem.lookup_app('org.gnome.Extensions.desktop')?.get_app_info();
+ if (!appInfo)
+ appInfo = Gio.AppInfo.create_from_commandline('true', _('Open Windows'), null);
+ appInfo.get_description = () => _('Search open windows');
+ appInfo.get_name = () => _('Open Windows');
+ appInfo.get_id = () => this.id;
+ appInfo.get_icon = () => Gio.icon_new_for_string('focus-windows-symbolic');
+ appInfo.should_show = () => true;
+
+ this.appInfo = appInfo;
+ this.canLaunchSearch = false;
this.isRemoteProvider = false;
this.action = 0;
@@ -128,7 +139,7 @@ const WindowSearchProvider = class WindowSearchProvider {
// do not modify original terms
let termsCopy = [...terms];
// search for terms without prefix
- termsCopy[0] = termsCopy[0].replace(prefix, '');
+ termsCopy[0] = termsCopy[0].replace(PREFIX, '');
/* if (gOptions.get('searchWindowsCommands')) {
this.action = 0;
@@ -167,9 +178,9 @@ const WindowSearchProvider = class WindowSearchProvider {
let m;
for (let key in candidates) {
if (opt.SEARCH_FUZZY)
- m = _Util.fuzzyMatch(term, candidates[key].name);
+ m = Me.Util.fuzzyMatch(term, candidates[key].name);
else
- m = _Util.strictMatch(term, candidates[key].name);
+ m = Me.Util.strictMatch(term, candidates[key].name);
if (m !== -1)
results.push({ weight: m, id: key });
@@ -178,7 +189,19 @@ const WindowSearchProvider = class WindowSearchProvider {
results.sort((a, b) => a.weight > b.weight);
const currentWs = global.workspace_manager.get_active_workspace_index();
// prefer current workspace
- results.sort((a, b) => (this.windows[a.id].window.get_workspace().index() !== currentWs) && (this.windows[b.id].window.get_workspace().index() === currentWs));
+ switch (opt.WINDOW_SEARCH_ORDER) {
+ case 1: // MRU - current ws first
+ results.sort((a, b) => (this.windows[a.id].window.get_workspace().index() !== currentWs) && (this.windows[b.id].window.get_workspace().index() === currentWs));
+ break;
+ case 2: // MRU - by workspace
+ results.sort((a, b) => this.windows[a.id].window.get_workspace().index() > this.windows[b.id].window.get_workspace().index());
+ break;
+ case 3: // Stable sequence - by workspace
+ results.sort((a, b) => this.windows[a.id].window.get_stable_sequence() > this.windows[b.id].window.get_stable_sequence());
+ results.sort((a, b) => this.windows[a.id].window.get_workspace().index() > this.windows[b.id].window.get_workspace().index());
+ break;
+ }
+
results.sort((a, b) => (_terms !== ' ') && (a.weight > 0 && b.weight === 0));
this.resultIds = results.map(item => item.id);
@@ -187,7 +210,7 @@ const WindowSearchProvider = class WindowSearchProvider {
getResultMetas(resultIds, callback = null) {
const metas = resultIds.map(id => this.getResultMeta(id));
- if (shellVersion >= 43)
+ if (Me.shellVersion >= 43)
return new Promise(resolve => resolve(metas));
else
callback(metas);
@@ -210,12 +233,29 @@ const WindowSearchProvider = class WindowSearchProvider {
};
}
+ makeResult(window, i) {
+ const app = Shell.WindowTracker.get_default().get_window_app(window);
+ const appName = app ? app.get_name() : 'Unknown';
+ const windowTitle = window.get_title();
+ const wsIndex = window.get_workspace().index();
+
+ return {
+ 'id': i,
+ // convert all accented chars to their basic form and lower case for search
+ 'name': `${wsIndex + 1}: ${windowTitle} ${appName}`.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(),
+ appName,
+ windowTitle,
+ window,
+ };
+ }
+
launchSearch(/* terms, timeStamp*/) {
+
}
activateResult(resultId/* , terms, timeStamp*/) {
- const isCtrlPressed = _Util.isCtrlPressed();
- const isShiftPressed = _Util.isShiftPressed();
+ const isCtrlPressed = Me.Util.isCtrlPressed();
+ const isShiftPressed = Me.Util.isShiftPressed();
this.action = 0;
this.targetWs = 0;
@@ -276,15 +316,16 @@ const WindowSearchProvider = class WindowSearchProvider {
this.windows = windows = {};
global.display.get_tab_list(Meta.TabList.NORMAL, null).filter(w => w.get_workspace() !== null).map(
(v, i) => {
- windows[`${i}-${v.get_id()}`] = makeResult(v, `${i}-${v.get_id()}`);
+ windows[`${i}-${v.get_id()}`] = this.makeResult(v, `${i}-${v.get_id()}`);
return windows[`${i}-${v.get_id()}`];
}
);
- if (shellVersion >= 43)
+ if (Me.shellVersion >= 43)
return new Promise(resolve => resolve(this._getResultSet(terms)));
else
callback(this._getResultSet(terms));
+
return null;
}
@@ -293,13 +334,15 @@ const WindowSearchProvider = class WindowSearchProvider {
return results;
}
- getSubsearchResultSet(previousResults, terms, callback/* , cancellable*/) {
- // if we return previous results, quick typers get non-actual results
- callback(this._getResultSet(terms));
+ getSubsearchResultSet(previousResults, terms, callback) {
+ if (Me.shellVersion < 43) {
+ this.getSubsearchResultSet42(terms, callback);
+ return null;
+ }
+ return this.getInitialResultSet(terms);
}
- /* createResultObject(resultMeta) {
- const app = Shell.WindowTracker.get_default().get_window_app(resultMeta.id);
- return new AppIcon(app);
- }*/
+ getSubsearchResultSet42(terms, callback) {
+ callback(this._getResultSet(terms));
+ }
};
diff --git a/extensions/vertical-workspaces/lib/workspace.js b/extensions/44/vertical-workspaces/lib/workspace.js
index 3b61a6d..be60403 100644
--- a/extensions/vertical-workspaces/lib/workspace.js
+++ b/extensions/44/vertical-workspaces/lib/workspace.js
@@ -10,51 +10,68 @@
'use strict';
-const { St, Graphene } = imports.gi;
+const Graphene = imports.gi.Graphene;
+const St = imports.gi.St;
const Main = imports.ui.main;
-const Util = imports.misc.util;
const Workspace = imports.ui.workspace;
+const Util = imports.misc.util;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-
-const _Util = Me.imports.lib.util;
-
-let _overrides;
+let Me;
let opt;
-let _firstRun = true;
-function update(reset = false) {
- opt = Me.imports.lib.settings.opt;
- const moduleEnabled = opt.get('workspaceModule', true);
- reset = reset || !moduleEnabled;
+var WorkspaceModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
- // don't even touch this module if disabled
- if (_firstRun && reset)
- return;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
- _firstRun = false;
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
- if (_overrides)
- _overrides.removeAll();
+ update(reset) {
+ this.moduleEnabled = opt.get('workspaceModule');
+ const conflict = false;
+ reset = reset || !this.moduleEnabled || conflict;
- if (reset) {
- Workspace.WINDOW_PREVIEW_MAXIMUM_SCALE = 0.95;
- _overrides = null;
- opt = null;
- return;
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WorkspaceModule - Keeping untouched');
}
- _overrides = new _Util.Overrides();
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
- _overrides.addOverride('WorkspaceBackground', Workspace.WorkspaceBackground.prototype, WorkspaceBackground);
+ this._overrides.addOverride('WorkspaceBackground', Workspace.WorkspaceBackground.prototype, WorkspaceBackground);
- // fix overlay base for Vertical Workspaces
- _overrides.addOverride('WorkspaceLayout', Workspace.WorkspaceLayout.prototype, WorkspaceLayout);
-}
+ // fix overlay base for Vertical Workspaces
+ this._overrides.addOverride('WorkspaceLayout', Workspace.WorkspaceLayout.prototype, WorkspaceLayout);
+ console.debug(' WorkspaceModule - Activated');
+ }
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+ Workspace.WINDOW_PREVIEW_MAXIMUM_SCALE = 0.95;
+
+ console.debug(' WorkspaceModule - Disabled');
+ }
+};
// workaround for upstream bug (that is not that invisible in default shell)
// smaller window cannot be scaled below 0.95 (WINDOW_PREVIEW_MAXIMUM_SCALE)
diff --git a/extensions/44/vertical-workspaces/lib/workspaceAnimation.js b/extensions/44/vertical-workspaces/lib/workspaceAnimation.js
new file mode 100644
index 0000000..d790895
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/workspaceAnimation.js
@@ -0,0 +1,206 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * workspacesAnimation.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Main = imports.ui.main;
+const WorkspaceAnimation = imports.ui.workspaceAnimation;
+const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
+
+let Me;
+let opt;
+
+var WorkspaceAnimationModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ // first reference to constant defined using const in other module returns undefined, the MonitorGroup const will remain empty and unused
+ this.dummy = WorkspaceAnimation.MonitorGroup;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ this._origBaseDistance = null;
+ this._wsAnimationSwipeBeginId = 0;
+ this._wsAnimationSwipeUpdateId = 0;
+ this._wsAnimationSwipeEndId = 0;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('workspaceAnimationModule');
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WorkspaceAnimationModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ if (opt.STATIC_WS_SWITCHER_BG) {
+ this._overrideMonitorGroupProperty();
+ this._overrides.addOverride('WorkspaceAnimationMonitorGroup', WorkspaceAnimation.MonitorGroup.prototype, MonitorGroup);
+ }
+
+ this._connectWsAnimationSwipeTracker();
+ console.debug(' WorkspaceAnimationModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+ const reset = true;
+ this._connectWsAnimationSwipeTracker(reset);
+ this._overrideMonitorGroupProperty(reset);
+ console.debug(' WorkspaceAnimationModule - Disabled');
+ }
+
+ _overrideMonitorGroupProperty(reset = false) {
+ if (!this._origBaseDistance)
+ this._origBaseDistance = Object.getOwnPropertyDescriptor(WorkspaceAnimation.MonitorGroup.prototype, 'baseDistance').get;
+
+ let getter;
+ if (reset) {
+ if (this._origBaseDistance)
+ getter = { get: this._origBaseDistance };
+ } else {
+ getter = {
+ get() {
+ // const spacing = 100 * imports.gi.St.ThemeContext.get_for_stage(global.stage).scale_factor;
+ const spacing = 0;
+ if (global.workspace_manager.layout_rows === -1)
+ return this._monitor.height + spacing + (opt.PANEL_MODE ? Main.panel.height : 0); // compensation for hidden panel
+ else
+ return this._monitor.width + spacing;
+ },
+ };
+ }
+
+ if (getter)
+ Object.defineProperty(WorkspaceAnimation.MonitorGroup.prototype, 'baseDistance', getter);
+ }
+
+ _connectWsAnimationSwipeTracker(reset = false) {
+ if (reset) {
+ if (this._wsAnimationSwipeBeginId) {
+ Main.wm._workspaceAnimation._swipeTracker.disconnect(this._wsAnimationSwipeBeginId);
+ this._wsAnimationSwipeBeginId = 0;
+ }
+ if (this._wsAnimationSwipeEndId) {
+ Main.wm._workspaceAnimation._swipeTracker.disconnect(this._wsAnimationSwipeEndId);
+ this._wsAnimationSwipeEndId = 0;
+ }
+ } else if (!this._wsAnimationSwipeBeginId) {
+ // display ws switcher popup when gesture begins and connect progress
+ this._wsAnimationSwipeBeginId = Main.wm._workspaceAnimation._swipeTracker.connect('begin', () => this._connectWsAnimationProgress(true));
+ // we want to be sure that popup with the final ws index show up when gesture ends
+ this._wsAnimationSwipeEndId = Main.wm._workspaceAnimation._swipeTracker.connect('end', (tracker, duration, endProgress) => this._connectWsAnimationProgress(false, endProgress));
+ }
+ }
+
+ _connectWsAnimationProgress(connect, endProgress = null) {
+ if (Main.overview.visible)
+ return;
+
+ if (connect && !this._wsAnimationSwipeUpdateId) {
+ this._wsAnimationSwipeUpdateId = Main.wm._workspaceAnimation._swipeTracker.connect('update', (tracker, progress) => this._showWsSwitcherPopup(progress));
+ } else if (!connect && this._wsAnimationSwipeUpdateId) {
+ Main.wm._workspaceAnimation._swipeTracker.disconnect(this._wsAnimationSwipeUpdateId);
+ this._wsAnimationSwipeUpdateId = 0;
+ this._showWsSwitcherPopup(Math.round(endProgress));
+ }
+ }
+
+ _showWsSwitcherPopup(progress) {
+ if (Main.overview.visible)
+ return;
+
+ const wsIndex = Math.round(progress);
+ if (Main.wm._workspaceSwitcherPopup === null) {
+ Main.wm._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
+ Main.wm._workspaceSwitcherPopup.connect('destroy', () => {
+ Main.wm._workspaceSwitcherPopup = null;
+ });
+ }
+
+ Main.wm._workspaceSwitcherPopup.display(wsIndex);
+ }
+};
+
+const MonitorGroup = {
+ // injection to _init()
+ after__init() {
+ // we have two options to implement static bg feature
+ // one is adding background to monitorGroup
+ // but this one has disadvantage - sticky windows will be always on top of animated windows
+ // which is bad for conky, for example, that window should be always below
+ /* this._bgManager = new Background.BackgroundManager({
+ container: this,
+ monitorIndex: this._monitor.index,
+ controlPosition: false,
+ });*/
+
+ // the second option is to make background of the monitorGroup transparent so the real desktop content will stay visible,
+ // hide windows that should be animated and keep only sticky windows
+ // we can keep certain sticky windows bellow and also extensions like DING (icons on desktop) will stay visible
+ this.set_style('background-color: transparent;');
+ // stickyGroup holds the Always on Visible Workspace windows to keep them static and above other windows during animation
+ const stickyGroup = this.get_children()[1];
+ stickyGroup._windowRecords.forEach(r => {
+ const metaWin = r.windowActor.metaWindow;
+ // conky is sticky but should never get above other windows during ws animation
+ // so we hide it from the overlay group, we will see the original if not covered by other windows
+ if (metaWin.wm_class === 'conky')
+ r.clone.opacity = 0;
+ });
+ this._hiddenWindows = [];
+ // remove (hide) background wallpaper from the animation, we will see the original one
+ this._workspaceGroups.forEach(w => {
+ w._background.opacity = 0;
+ });
+ // hide (scale to 0) all non-sticky windows, their clones will be animated
+ global.get_window_actors().forEach(actor => {
+ const metaWin = actor.metaWindow;
+ if (metaWin?.get_monitor() === this._monitor.index &&
+ !(metaWin?.wm_class === 'conky' && metaWin?.is_on_all_workspaces()) &&
+ !(metaWin?.wm_class === 'Gjs' && metaWin?.is_on_all_workspaces())) { // DING extension uses window with Gjs class
+ // hide original window. we cannot use opacity since it also affects clones.
+ // scaling them to 0 works well
+ actor.scale_x = 0;
+ this._hiddenWindows.push(actor);
+ }
+ });
+
+ // restore all hidden windows at the end of animation
+ // todo - actors removed during transition need to be removed from the list to avoid access to destroyed actor
+ this.connect('destroy', () => {
+ this._hiddenWindows.forEach(actor => {
+ actor.scale_x = 1;
+ });
+ });
+ },
+};
diff --git a/extensions/44/vertical-workspaces/lib/workspaceSwitcherPopup.js b/extensions/44/vertical-workspaces/lib/workspaceSwitcherPopup.js
new file mode 100644
index 0000000..5bde6d0
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/workspaceSwitcherPopup.js
@@ -0,0 +1,109 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * workspacesSwitcherPopup.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Main = imports.ui.main;
+const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
+
+let Me;
+let opt;
+
+var WorkspaceSwitcherPopupModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = opt.get('workspaceSwitcherPopupModule');
+ const conflict = Me.Util.getEnabledExtensions('workspace-switcher-manager').length ||
+ Me.Util.getEnabledExtensions('WsSwitcherPopupManager').length;
+
+ if (conflict && !reset)
+ console.warn(`[${Me.metadata.name}] Warning: "WorkspaceSwitcherPopup" module disabled due to potential conflict with another extension`);
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WorkspaceSwitcherPopupModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ this._overrides.addOverride('WorkspaceSwitcherPopup', WorkspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype, WorkspaceSwitcherPopupCommon);
+ console.debug(' WorkspaceSwitcherPopupModule - Activated');
+ }
+
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ console.debug(' WorkspaceSwitcherPopupModule - Disabled');
+ }
+};
+
+const WorkspaceSwitcherPopupCommon = {
+ // injection to _init()
+ after__init() {
+ if (opt.ORIENTATION) { // 1-VERTICAL, 0-HORIZONTAL
+ this._list.vertical = true;
+ }
+ this._list.set_style('margin: 0;');
+ if (this.get_constraints()[0])
+ this.remove_constraint(this.get_constraints()[0]);
+ },
+
+ // injection to display()
+ after_display() {
+ if (opt.WS_SW_POPUP_MODE)
+ this._setPopupPosition();
+ else
+ this.opacity = 0;
+ },
+
+ _setPopupPosition() {
+ let workArea;
+ if (opt.WS_SW_POPUP_MODE === 1) {
+ // workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);*/
+ workArea = global.display.get_monitor_geometry(Main.layoutManager.primaryIndex);
+ } else {
+ // workArea = Main.layoutManager.getWorkAreaForMonitor(global.display.get_current_monitor());
+ workArea = global.display.get_monitor_geometry(global.display.get_current_monitor());
+ }
+
+ let [, natHeight] = this.get_preferred_height(global.screen_width);
+ let [, natWidth] = this.get_preferred_width(natHeight);
+ let h = opt.WS_SW_POPUP_H_POSITION;
+ let v = opt.WS_SW_POPUP_V_POSITION;
+ this.x = workArea.x + Math.floor((workArea.width - natWidth) * h);
+ this.y = workArea.y + Math.floor((workArea.height - natHeight) * v);
+ this.set_position(this.x, this.y);
+ },
+};
diff --git a/extensions/vertical-workspaces/lib/workspaceThumbnail.js b/extensions/44/vertical-workspaces/lib/workspaceThumbnail.js
index d0bc206..844c224 100644
--- a/extensions/vertical-workspaces/lib/workspaceThumbnail.js
+++ b/extensions/44/vertical-workspaces/lib/workspaceThumbnail.js
@@ -10,56 +10,90 @@
'use strict';
-const { GLib, Clutter, Graphene, Meta, Shell, St } = imports.gi;
+const Clutter = imports.gi.Clutter;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const Meta = imports.gi.Meta;
+const Shell = imports.gi.Shell;
+const St = imports.gi.St;
+
+const AppDisplay = imports.ui.appDisplay;
+const Background = imports.ui.background;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
-const Background = imports.ui.background;
+const OverviewControls = imports.ui.overviewControls;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
+
+let Me;
+let opt;
+
const ThumbnailState = WorkspaceThumbnail.ThumbnailState;
+const ControlsState = OverviewControls.ControlsState;
-const ControlsState = imports.ui.overviewControls.ControlsState;
+const WORKSPACE_CUT_SIZE = 10;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
+var WorkspaceThumbnailModule = class {
+ constructor(me) {
+ Me = me;
+ opt = Me.opt;
-// gettext
-const _ = Me.imports.lib.settings._;
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
-const _Util = Me.imports.lib.util;
-const shellVersion = _Util.shellVersion;
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
-let _overrides;
+ update(reset) {
+ this.moduleEnabled = true;
+ const conflict = false;
-const WORKSPACE_CUT_SIZE = 10;
-const _originalMaxThumbnailScale = WorkspaceThumbnail.MAX_THUMBNAIL_SCALE;
+ reset = reset || !this.moduleEnabled || conflict;
-let opt = null;
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WorkspaceThumbnailModule - Keeping untouched');
+ }
-function update(reset = false) {
- if (_overrides)
- _overrides.removeAll();
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+ if (!this._originalMaxThumbnailScale)
+ this._originalMaxThumbnailScale = WorkspaceThumbnail.MAX_THUMBNAIL_SCALE;
- if (reset) {
- if (_originalMaxThumbnailScale)
- WorkspaceThumbnail.MAX_THUMBNAIL_SCALE = _originalMaxThumbnailScale;
- _overrides = null;
- opt = null;
- return;
- }
+ // don't limit max thumbnail scale for other clients than overview, specifically AATWS.
+ WorkspaceThumbnail.MAX_THUMBNAIL_SCALE = 1;
+ // WorkspaceThumbnail.ThumbnailsBox._MAX_THUMBNAIL_SCALE = 1;
+
+ this._overrides.addOverride('WorkspaceThumbnail', WorkspaceThumbnail.WorkspaceThumbnail.prototype, WorkspaceThumbnailCommon);
+ this._overrides.addOverride('ThumbnailsBoxCommon', WorkspaceThumbnail.ThumbnailsBox.prototype, ThumbnailsBoxCommon);
- opt = Me.imports.lib.settings.opt;
- _overrides = new _Util.Overrides();
+ // replacing opt.ORIENTATION local constant with boxOrientation internal variable allows external customers such as the AATWS extension to control the box orientation.
+ Main.overview._overview.controls._thumbnailsBox._boxOrientation = opt.ORIENTATION;
+
+ console.debug(' WorkspaceThumbnailModule - Activated');
+ }
- // don't limit max thumbnail scale for other clients than overview, for example AATWS.
- WorkspaceThumbnail.MAX_THUMBNAIL_SCALE = 1;
+ _disableModule() {
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
- _overrides.addOverride('WorkspaceThumbnail', WorkspaceThumbnail.WorkspaceThumbnail.prototype, WorkspaceThumbnailCommon);
- _overrides.addOverride('ThumbnailsBoxCommon', WorkspaceThumbnail.ThumbnailsBox.prototype, ThumbnailsBoxCommon);
+ WorkspaceThumbnail.MAX_THUMBNAIL_SCALE = this._originalMaxThumbnailScale;
- // replacing opt.ORIENTATION local constant with boxOrientation internal variable allows external customers such as the AATWS extension to control the box orientation.
- Main.overview._overview.controls._thumbnailsBox._boxOrientation = opt.ORIENTATION;
-}
+ console.debug(' WorkspaceThumbnailModule - Disabled');
+ }
+};
const WorkspaceThumbnailCommon = {
// injection to _init()
@@ -70,6 +104,8 @@ const WorkspaceThumbnailCommon = {
// unless border is removed
if (opt.SHOW_WS_TMB_BG)
this.add_style_class_name('ws-tmb-labeled');
+ else
+ this.add_style_class_name('ws-tmb-transparent');
// add workspace thumbnails labels if enabled
if (opt.SHOW_WST_LABELS) { // 0 - disable
@@ -77,7 +113,7 @@ const WorkspaceThumbnailCommon = {
const wsIndex = this.metaWorkspace.index();
let label = `${wsIndex + 1}`;
if (opt.SHOW_WST_LABELS === 2) { // 2 - index + workspace name
- const settings = ExtensionUtils.getSettings('org.gnome.desktop.wm.preferences');
+ const settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.wm.preferences' });
const wsLabels = settings.get_strv('workspace-names');
if (wsLabels.length > wsIndex && wsLabels[wsIndex])
label += `: ${wsLabels[wsIndex]}`;
@@ -129,7 +165,9 @@ const WorkspaceThumbnailCommon = {
}
});
this._nWindowsConId = this.metaWorkspace.connect('notify::n-windows', () => {
- // wait for new information
+ if (this._updateLabelTimeout)
+ return;
+ // wait for new data
this._updateLabelTimeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 250, () => {
const newLabel = getLabel();
this._wsLabel.text = newLabel;
@@ -168,7 +206,7 @@ const WorkspaceThumbnailCommon = {
closeButton.opacity = 255;
if (!Meta.prefs_get_dynamic_workspaces() || (Meta.prefs_get_dynamic_workspaces() && global.workspace_manager.get_n_workspaces() - 1 !== this.metaWorkspace.index())) {
// color the button red if ready to react on clicks
- if (opt.CLOSE_WS_BUTTON_MODE < 3 || (opt.CLOSE_WS_BUTTON_MODE === 3 && _Util.isCtrlPressed()))
+ if (opt.CLOSE_WS_BUTTON_MODE < 3 || (opt.CLOSE_WS_BUTTON_MODE === 3 && Me.Util.isCtrlPressed()))
closeButton.add_style_class_name('workspace-close-button-hover');
}
});
@@ -220,12 +258,6 @@ const WorkspaceThumbnailCommon = {
this._viewport.set_child_below_sibling(this._bgManager.backgroundActor, null);
- this.connect('destroy', () => {
- if (this._bgManager)
- this._bgManager.destroy();
- this._bgManager = null;
- });
-
// full brightness of the thumbnail bg draws unnecessary attention
// there is a grey bg under the wallpaper
this._bgManager.backgroundActor.opacity = 220;
@@ -256,7 +288,7 @@ const WorkspaceThumbnailCommon = {
this._lastCloseClickTime = Date.now();
return;
}
- } else if (opt.CLOSE_WS_BUTTON_MODE === 3 && !_Util.isCtrlPressed()) {
+ } else if (opt.CLOSE_WS_BUTTON_MODE === 3 && !Me.Util.isCtrlPressed()) {
return;
}
@@ -335,7 +367,7 @@ const WorkspaceThumbnailCommon = {
if (!source.app && source.shellWorkspaceLaunch)
return DND.DragMotionResult.COPY_DROP;
- if (source instanceof imports.ui.appDisplay.FolderIcon)
+ if (source instanceof AppDisplay.FolderIcon)
return DND.DragMotionResult.COPY_DROP;
@@ -369,8 +401,8 @@ const WorkspaceThumbnailCommon = {
timestamp: time,
});
return true;
- } else if (source instanceof imports.ui.appDisplay.FolderIcon) {
- if (shellVersion >= 44) {
+ } else if (source instanceof AppDisplay.FolderIcon) {
+ if (Me.shellVersion >= 44) {
for (let app of source.view._apps) {
// const app = Shell.AppSystem.get_default().lookup_app(id);
app.open_new_window(this.metaWorkspace.index());
@@ -419,7 +451,7 @@ const ThumbnailsBoxCommon = {
if (!source.metaWindow &&
(!source.app || !source.app.can_open_new_window()) &&
(source.app || !source.shellWorkspaceLaunch) &&
- !(source instanceof imports.ui.appDisplay.FolderIcon))
+ !(source instanceof AppDisplay.FolderIcon))
return false;
@@ -448,8 +480,8 @@ const ThumbnailsBoxCommon = {
workspace: newWorkspaceIndex,
timestamp: time,
});
- } else if (source instanceof imports.ui.appDisplay.FolderIcon) {
- if (shellVersion >= 44) {
+ } else if (source instanceof AppDisplay.FolderIcon) {
+ if (Me.shellVersion >= 44) {
for (let app of source.view._apps) {
// const app = Shell.AppSystem.get_default().lookup_app(id);
app.open_new_window(newWorkspaceIndex);
@@ -495,7 +527,7 @@ const ThumbnailsBoxCommon = {
if (!source.metaWindow &&
(!source.app || !source.app.can_open_new_window()) &&
(source.app || !source.shellWorkspaceLaunch) &&
- source !== Main.xdndHandler && !(source instanceof imports.ui.appDisplay.FolderIcon))
+ source !== Main.xdndHandler && !(source instanceof AppDisplay.FolderIcon))
return DND.DragMotionResult.CONTINUE;
const rtl = Clutter.get_default_text_direction() === Clutter.TextDirection.RTL;
@@ -551,18 +583,18 @@ const ThumbnailsBoxCommon = {
return ThumbnailsBoxHorizontal._withinWorkspace.bind(this)(...args);
},
- get_preferred_custom_width(...args) {
+ vfunc_get_preferred_width(...args) {
if (this._boxOrientation)
- return ThumbnailsBoxVertical.get_preferred_custom_width.bind(this)(...args);
+ return ThumbnailsBoxVertical.vfunc_get_preferred_width.bind(this)(...args);
else
- return ThumbnailsBoxHorizontal.get_preferred_custom_width.bind(this)(...args);
+ return ThumbnailsBoxHorizontal.vfunc_get_preferred_width.bind(this)(...args);
},
- get_preferred_custom_height(...args) {
+ vfunc_get_preferred_height(...args) {
if (this._boxOrientation)
- return ThumbnailsBoxVertical.get_preferred_custom_height.bind(this)(...args);
+ return ThumbnailsBoxVertical.vfunc_get_preferred_height.bind(this)(...args);
else
- return ThumbnailsBoxHorizontal.get_preferred_custom_height.bind(this)(...args);
+ return ThumbnailsBoxHorizontal.vfunc_get_preferred_height.bind(this)(...args);
},
vfunc_allocate(...args) {
@@ -632,14 +664,9 @@ const ThumbnailsBoxVertical = {
return y > workspaceY1 && y <= workspaceY2;
},
- // vfunc_get_preferred_width: function(forHeight) {
- // override of this vfunc doesn't work for some reason (tested on Ubuntu and Fedora), it's not reachable
- get_preferred_custom_width(forHeight) {
- if (!this.visible)
- return [0, 0];
-
- if (forHeight === -1)
- return this.get_preferred_custom_height(forHeight);
+ vfunc_get_preferred_width(forHeight) {
+ if (forHeight < 10)
+ return [this._porthole.width, this._porthole.width];
let themeNode = this.get_theme_node();
@@ -652,19 +679,14 @@ const ThumbnailsBoxVertical = {
const avail = forHeight - totalSpacing;
let scale = (avail / nWorkspaces) / this._porthole.height;
- // scale = Math.min(scale, opt.MAX_THUMBNAIL_SCALE);
const width = Math.round(this._porthole.width * scale);
return themeNode.adjust_preferred_height(width, width);
},
- get_preferred_custom_height(_forWidth) {
- if (!this.visible)
- return [0, 0];
-
- // Note that for getPreferredHeight/Width we cheat a bit and skip propagating
- // the size request to our children because we know how big they are and know
- // that the actors aren't depending on the virtual functions being called.
+ vfunc_get_preferred_height(forWidth) {
+ if (forWidth < 10)
+ return [0, this._porthole.height];
let themeNode = this.get_theme_node();
let spacing = themeNode.get_length('spacing');
@@ -674,15 +696,14 @@ const ThumbnailsBoxVertical = {
let totalSpacing = (nWorkspaces - 3) * spacing;
const ratio = this._porthole.width / this._porthole.height;
- const tmbHeight = themeNode.adjust_for_width(_forWidth) / ratio;
+ const tmbHeight = themeNode.adjust_for_width(forWidth) / ratio;
const naturalheight = this._thumbnails.reduce((accumulator, thumbnail/* , index*/) => {
const progress = 1 - thumbnail.collapse_fraction;
const height = tmbHeight * progress;
return accumulator + height;
}, 0);
-
- return themeNode.adjust_preferred_width(totalSpacing, naturalheight);
+ return themeNode.adjust_preferred_width(totalSpacing, Math.round(naturalheight));
},
// removes extra space (extraWidth in the original function), we need the box as accurate as possible
@@ -759,16 +780,11 @@ const ThumbnailsBoxVertical = {
this._dropPlaceholder.allocate_preferred_size(
...this._dropPlaceholder.get_position());
- if (shellVersion >= 44) {
- const laters = global.compositor.get_laters();
- laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.hide();
- });
- } else {
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.hide();
- });
- }
+ const laterFunc = () => this._dropPlaceholder.hide();
+ if (Meta.later_add)
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
+ else
+ global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
}
let childBox = new Clutter.ActorBox();
@@ -796,16 +812,11 @@ const ThumbnailsBoxVertical = {
this._dropPlaceholder.allocate(childBox);
- if (shellVersion >= 44) {
- const laters = global.compositor.get_laters();
- laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.show();
- });
- } else {
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.show();
- });
- }
+ const laterFunc = () => this._dropPlaceholder.show();
+ if (Meta.later_add)
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
+ else
+ global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
y += placeholderHeight + spacing;
}
@@ -925,7 +936,10 @@ const ThumbnailsBoxHorizontal = {
return x > workspaceX1 && x <= workspaceX2;
},
- get_preferred_custom_height(forWidth) {
+ vfunc_get_preferred_height(forWidth) {
+ if (forWidth < 10)
+ return [this._porthole.height, this._porthole.height];
+
let themeNode = this.get_theme_node();
forWidth = themeNode.adjust_for_width(forWidth);
@@ -937,18 +951,15 @@ const ThumbnailsBoxHorizontal = {
const avail = forWidth - totalSpacing;
let scale = (avail / nWorkspaces) / this._porthole.width;
- // scale = Math.min(scale, opt.MAX_THUMBNAIL_SCALE);
const height = Math.round(this._porthole.height * scale);
+
return themeNode.adjust_preferred_height(height, height);
},
- get_preferred_custom_width(_forHeight) {
- // Note that for getPreferredHeight/Width we cheat a bit and skip propagating
- // the size request to our children because we know how big they are and know
- // that the actors aren't depending on the virtual functions being called.
- if (!this.visible)
- return [0, 0];
+ vfunc_get_preferred_width(forHeight) {
+ if (forHeight < 10)
+ return [0, this._porthole.width];
let themeNode = this.get_theme_node();
@@ -959,13 +970,14 @@ const ThumbnailsBoxHorizontal = {
const ratio = this._porthole.height / this._porthole.width;
- const tmbWidth = themeNode.adjust_for_height(_forHeight) / ratio;
+ const tmbWidth = themeNode.adjust_for_height(forHeight) / ratio;
const naturalWidth = this._thumbnails.reduce((accumulator, thumbnail) => {
const progress = 1 - thumbnail.collapse_fraction;
const width = tmbWidth * progress;
return accumulator + width;
}, 0);
+
return themeNode.adjust_preferred_width(totalSpacing, naturalWidth);
},
@@ -1041,16 +1053,11 @@ const ThumbnailsBoxHorizontal = {
this._dropPlaceholder.allocate_preferred_size(
...this._dropPlaceholder.get_position());
- if (shellVersion >= 44) {
- const laters = global.compositor.get_laters();
- laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.hide();
- });
- } else {
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.hide();
- });
- }
+ const laterFunc = () => this._dropPlaceholder.hide();
+ if (Meta.later_add)
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
+ else
+ global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
}
let childBox = new Clutter.ActorBox();
@@ -1078,16 +1085,11 @@ const ThumbnailsBoxHorizontal = {
this._dropPlaceholder.allocate(childBox);
- if (shellVersion >= 44) {
- const laters = global.compositor.get_laters();
- laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.show();
- });
- } else {
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._dropPlaceholder.show();
- });
- }
+ const laterFunc = () => this._dropPlaceholder.show();
+ if (Meta.later_add)
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
+ else
+ global.compositor.get_laters().add(Meta.LaterType.BEFORE_REDRAW, laterFunc);
x += placeholderWidth + spacing;
}
diff --git a/extensions/44/vertical-workspaces/lib/workspacesView.js b/extensions/44/vertical-workspaces/lib/workspacesView.js
new file mode 100644
index 0000000..3df7b22
--- /dev/null
+++ b/extensions/44/vertical-workspaces/lib/workspacesView.js
@@ -0,0 +1,993 @@
+/**
+ * V-Shell (Vertical Workspaces)
+ * workspacesView.js
+ *
+ * @author GdH <G-dH@github.com>
+ * @copyright 2022 - 2023
+ * @license GPL-3.0
+ *
+ */
+
+'use strict';
+
+const Clutter = imports.gi.Clutter;
+const GObject = imports.gi.GObject;
+const Meta = imports.gi.Meta;
+const St = imports.gi.St;
+
+const Main = imports.ui.main;
+const OverviewControls = imports.ui.overviewControls;
+const WorkspacesView = imports.ui.workspacesView;
+const Util = imports.misc.util;
+
+let Me;
+let opt;
+
+const ControlsState = OverviewControls.ControlsState;
+const FitMode = WorkspacesView.FitMode;
+
+var WorkspacesViewModule = class {
+ constructor(me) {
+ // first reference to constant defined using const in other module returns undefined, the SecondaryMonitorDisplay const will remain empty and unused
+ this.dummy = WorkspacesView.SecondaryMonitorDisplay;
+
+ Me = me;
+ opt = Me.opt;
+
+ this._firstActivation = true;
+ this.moduleEnabled = false;
+ this._overrides = null;
+ }
+
+ cleanGlobals() {
+ Me = null;
+ opt = null;
+ }
+
+ update(reset) {
+ this.moduleEnabled = true;
+ const conflict = false;
+
+ reset = reset || !this.moduleEnabled || conflict;
+
+ // don't touch the original code if module disabled
+ if (reset && !this._firstActivation) {
+ this._disableModule();
+ } else if (!reset) {
+ this._firstActivation = false;
+ this._activateModule();
+ }
+ if (reset && this._firstActivation)
+ console.debug(' WorkspacesViewModule - Keeping untouched');
+ }
+
+ _activateModule() {
+ if (!this._overrides)
+ this._overrides = new Me.Util.Overrides();
+
+ const desktopCubeEnabled = Me.Util.getEnabledExtensions('desktop-cube@schneegans.github.com').length;
+ const desktopCubeConflict = desktopCubeEnabled && !opt.ORIENTATION && !opt.OVERVIEW_MODE;
+
+ if (!desktopCubeConflict)
+ this._overrides.addOverride('WorkspacesView', WorkspacesView.WorkspacesView.prototype, WorkspacesViewCommon);
+
+ this._overrides.addOverride('WorkspacesDisplay', WorkspacesView.WorkspacesDisplay.prototype, WorkspacesDisplayCommon);
+ this._overrides.addOverride('ExtraWorkspaceView', WorkspacesView.ExtraWorkspaceView.prototype, ExtraWorkspaceViewCommon);
+ this._overrides.addOverride('SecondaryMonitorDisplayCommon', WorkspacesView.SecondaryMonitorDisplay.prototype, SecondaryMonitorDisplayCommon);
+
+ if (opt.ORIENTATION) {
+ // switch internal workspace orientation in GS
+ global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT, false, -1, 1);
+ this._overrides.addOverride('SecondaryMonitorDisplay', WorkspacesView.SecondaryMonitorDisplay.prototype, SecondaryMonitorDisplayVertical);
+ } else {
+ global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT, false, 1, -1);
+ this._overrides.addOverride('SecondaryMonitorDisplay', WorkspacesView.SecondaryMonitorDisplay.prototype, SecondaryMonitorDisplayHorizontal);
+ }
+
+ console.debug(' WorkspacesViewModule - Activated');
+ }
+
+ _disableModule() {
+ global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT, false, 1, -1);
+ if (this._overrides)
+ this._overrides.removeAll();
+ this._overrides = null;
+
+ console.debug(' WorkspacesViewModule - Disabled');
+ }
+};
+
+const WorkspacesViewCommon = {
+ _getFirstFitSingleWorkspaceBox(box, spacing, vertical) {
+ let [width, height] = box.get_size();
+ const [workspace] = this._workspaces;
+
+ const rtl = this.text_direction === Clutter.TextDirection.RTL;
+ const adj = this._scrollAdjustment;
+ const currentWorkspace = vertical || !rtl
+ ? adj.value : adj.upper - adj.value - 1;
+
+ // Single fit mode implies centered too
+ let [x1, y1] = box.get_origin();
+ const [, workspaceWidth] = workspace ? workspace.get_preferred_width(Math.floor(height)) : [0, width];
+ const [, workspaceHeight] = workspace ? workspace.get_preferred_height(workspaceWidth) : [0, height];
+
+ if (vertical) {
+ x1 += (width - workspaceWidth) / 2;
+ y1 -= currentWorkspace * (workspaceHeight + spacing);
+ } else {
+ x1 += (width - workspaceWidth) / 2;
+ x1 -= currentWorkspace * (workspaceWidth + spacing);
+ }
+
+ const fitSingleBox = new Clutter.ActorBox({ x1, y1 });
+ fitSingleBox.set_size(workspaceWidth, workspaceHeight);
+
+ return fitSingleBox;
+ },
+
+ // set spacing between ws previews
+ _getSpacing(box, fitMode, vertical) {
+ const [width, height] = box.get_size();
+ const [workspace] = this._workspaces;
+
+ if (!workspace)
+ return 0;
+
+ let availableSpace;
+ let workspaceSize;
+ if (vertical) {
+ [, workspaceSize] = workspace.get_preferred_height(width);
+ availableSpace = height;
+ } else {
+ [, workspaceSize] = workspace.get_preferred_width(height);
+ availableSpace = width;
+ }
+
+ const spacing = (availableSpace - workspaceSize * 0.4) * (1 - fitMode);
+ const { scaleFactor } = St.ThemeContext.get_for_stage(global.stage);
+ return Math.clamp(spacing,
+ opt.WORKSPACE_MIN_SPACING * scaleFactor,
+ opt.WORKSPACE_MAX_SPACING * scaleFactor);
+ },
+
+ // this function has duplicate in OverviewControls so we use one function for both to avoid issues with syncing them
+ _getFitModeForState(state) {
+ return _getFitModeForState(state);
+ },
+
+ // normal view 0, spread windows 1
+ _getWorkspaceModeForOverviewState(state) {
+
+ switch (state) {
+ case ControlsState.HIDDEN:
+ return 0;
+ case ControlsState.WINDOW_PICKER:
+ return opt.WORKSPACE_MODE;
+ case ControlsState.APP_GRID:
+ return (this._monitorIndex !== global.display.get_primary_monitor() || !opt.WS_ANIMATION) && !opt.OVERVIEW_MODE ? 1 : 0;
+ }
+
+ return 0;
+ },
+
+ _updateVisibility() {
+ // visibility handles _updateWorkspacesState()
+ },
+
+ // disable scaling and hide inactive workspaces
+ _updateWorkspacesState() {
+ const adj = this._scrollAdjustment;
+ const fitMode = this._fitModeAdjustment.value;
+
+ let { initialState, finalState, progress, currentState } =
+ this._overviewAdjustment.getStateTransitionParams();
+
+ const workspaceMode = (1 - fitMode) * Util.lerp(
+ this._getWorkspaceModeForOverviewState(initialState),
+ this._getWorkspaceModeForOverviewState(finalState),
+ progress);
+
+ const primaryMonitor = Main.layoutManager.primaryMonitor.index;
+
+ const wsScrollProgress = adj.value % 1;
+ const secondaryMonitor = this._monitorIndex !== global.display.get_primary_monitor();
+ const blockSecondaryAppGrid = opt.OVERVIEW_MODE && currentState > 1;
+
+ // Hide inactive workspaces
+ this._workspaces.forEach((w, index) => {
+ if (!(blockSecondaryAppGrid && secondaryMonitor))
+ w.stateAdjustment.value = workspaceMode;
+
+ let distance = adj.value - index;
+ const distanceToCurrentWorkspace = Math.abs(distance);
+
+ const scaleProgress = 1 - Math.clamp(distanceToCurrentWorkspace, 0, 1);
+ // const scale = Util.lerp(0.94, 1, scaleProgress);
+ // w.set_scale(scale, scale);
+
+ // if we disable workspaces that we can't or don't need to see, transition animations will be noticeably smoother
+ // only the current ws needs to be visible during overview transition animations
+ // and only current and adjacent ws when switching ws
+ w.visible = (this._animating && wsScrollProgress && distanceToCurrentWorkspace <= (opt.NUMBER_OF_VISIBLE_NEIGHBORS + 1)) || scaleProgress === 1 ||
+ (opt.WORKSPACE_MAX_SPACING > 340 && distanceToCurrentWorkspace <= opt.NUMBER_OF_VISIBLE_NEIGHBORS && currentState === ControlsState.WINDOW_PICKER) ||
+ (this._monitorIndex !== primaryMonitor && distanceToCurrentWorkspace <= opt.NUMBER_OF_VISIBLE_NEIGHBORS) || (!opt.WS_ANIMATION && distanceToCurrentWorkspace < opt.NUMBER_OF_VISIBLE_NEIGHBORS) ||
+ (opt.WORKSPACE_MAX_SPACING < 340 && distanceToCurrentWorkspace <= opt.NUMBER_OF_VISIBLE_NEIGHBORS && currentState <= ControlsState.WINDOW_PICKER &&
+ ((initialState < ControlsState.APP_GRID && finalState < ControlsState.APP_GRID))
+ );
+
+ // after transition from APP_GRID to WINDOW_PICKER state,
+ // adjacent workspaces are hidden and we need them to show up
+ // make them visible during animation can impact smoothness of the animation
+ // so we show them after the animation finished, move them to their position from outside of the monitor
+ if (!w.visible && distanceToCurrentWorkspace === 1 && initialState === ControlsState.APP_GRID && currentState === ControlsState.WINDOW_PICKER) {
+ w.visible = true;
+ const directionNext = distance > 0;
+ if (!opt.ORIENTATION) {
+ const width = w.width * 0.6 * opt.WS_PREVIEW_SCALE;
+ w.translation_x = directionNext ? -width : width;
+ }
+ if (opt.ORIENTATION) {
+ const height = w.height * 0.6 * opt.WS_PREVIEW_SCALE;
+ w.translation_y = directionNext ? -height : height;
+ }
+
+ w.opacity = 10;
+ w.get_parent().set_child_below_sibling(w, null);
+ w.ease({
+ duration: 300,
+ translation_x: 0,
+ translation_y: 0,
+ opacity: 255,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+
+ // force ws preview bg corner radiuses where GS doesn't do it
+ if (opt.SHOW_WS_PREVIEW_BG && opt.OVERVIEW_MODE === 1 && distanceToCurrentWorkspace < 2)
+ w._background._updateBorderRadius(Math.min(1, w._overviewAdjustment.value));
+
+
+ // hide workspace background
+ if (!opt.SHOW_WS_PREVIEW_BG && w._background.opacity)
+ w._background.opacity = 0;
+ });
+ },
+
+ exposeWindows(workspaceIndex = null, callback) {
+ let adjustments = [];
+ if (workspaceIndex === null) {
+ this._workspaces.forEach(ws => {
+ adjustments.push(ws._background._stateAdjustment);
+ });
+ } else {
+ adjustments.push(this._workspaces[workspaceIndex]._background._stateAdjustment);
+ }
+
+ adjustments.forEach(adj => {
+ if (adj.value === 0) {
+ adj.value = 0;
+ adj.ease(1, {
+ duration: 200,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => {
+ opt.WORKSPACE_MODE = 1;
+ if (callback)
+ callback();
+ },
+ });
+ }
+ });
+ },
+};
+
+const SecondaryMonitorDisplayCommon = {
+ exposeWindows(...args) {
+ this._workspacesView.exposeWindows(...args);
+ },
+};
+
+const SecondaryMonitorDisplayVertical = {
+ _getThumbnailParamsForState(state) {
+
+ let opacity, scale, translationX;
+ switch (state) {
+ case ControlsState.HIDDEN:
+ opacity = 255;
+ scale = 1;
+ translationX = 0;
+ if (!Main.layoutManager._startingUp && (!opt.SHOW_WS_PREVIEW_BG || opt.OVERVIEW_MODE2))
+ translationX = this._thumbnails.width * (opt.SEC_WS_TMB_LEFT ? -1 : 1);
+
+ break;
+ case ControlsState.WINDOW_PICKER:
+ case ControlsState.APP_GRID:
+ opacity = 255;
+ scale = 1;
+ translationX = 0;
+ break;
+ default:
+ opacity = 255;
+ scale = 1;
+ translationX = 0;
+ break;
+ }
+
+ return { opacity, scale, translationX };
+ },
+
+ _getWorkspacesBoxForState(state, box, padding, thumbnailsWidth, spacing) {
+ // const { ControlsState } = OverviewControls;
+ const workspaceBox = box.copy();
+ const [width, height] = workspaceBox.get_size();
+
+ let wWidth, wHeight, wsbX, wsbY, offset, yShift;
+ switch (state) {
+ case ControlsState.HIDDEN:
+ break;
+ case ControlsState.WINDOW_PICKER:
+ case ControlsState.APP_GRID:
+ if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)
+ break;
+
+ yShift = 0;
+ if (opt.SEC_WS_PREVIEW_SHIFT && Main.panel.visible) {
+ if (opt.PANEL_POSITION_TOP)
+ yShift = Main.panel.height;
+ else
+ yShift = -Main.panel.height;
+ }
+
+ wWidth = width - thumbnailsWidth - 5 * spacing;
+ wHeight = Math.min(wWidth / (width / height) - Math.abs(yShift), height - 4 * spacing);
+ wWidth = Math.round(wWidth * opt.SEC_WS_PREVIEW_SCALE);
+ wHeight = Math.round(wHeight * opt.SEC_WS_PREVIEW_SCALE);
+
+ offset = Math.round(width - thumbnailsWidth - wWidth) / 2;
+ if (opt.SEC_WS_TMB_LEFT)
+ wsbX = thumbnailsWidth + offset;
+ else
+ wsbX = offset;
+
+ wsbY = Math.round((height - wHeight - Math.abs(yShift)) / 2 + yShift);
+
+ workspaceBox.set_origin(wsbX, wsbY);
+ workspaceBox.set_size(wWidth, wHeight);
+ break;
+ }
+
+ return workspaceBox;
+ },
+
+ vfunc_allocate(box) {
+ this.set_allocation(box);
+
+ const themeNode = this.get_theme_node();
+ const contentBox = themeNode.get_content_box(box);
+ const [width, height] = contentBox.get_size();
+ const { expandFraction } = this._thumbnails;
+ const spacing = themeNode.get_length('spacing') * expandFraction;
+ const padding = Math.round(0.1 * height);
+
+ let thumbnailsWidth = 0;
+ let thumbnailsHeight = 0;
+ this._thumbnails.visible = !opt.SEC_WS_TMB_HIDDEN;
+ if (this._thumbnails.visible) {
+ const reduceBoxHeight = opt.SEC_WS_PREVIEW_SHIFT && Main.panel.visible ? Main.panel.height : 0;
+
+ thumbnailsWidth = width * opt.SEC_MAX_THUMBNAIL_SCALE;
+
+ let totalTmbSpacing;
+ [totalTmbSpacing, thumbnailsHeight] = this._thumbnails.get_preferred_height(thumbnailsWidth);
+ thumbnailsHeight = Math.round(thumbnailsHeight + totalTmbSpacing);
+
+ const thumbnailsHeightMax = height - spacing - reduceBoxHeight;
+
+ if (thumbnailsHeight > thumbnailsHeightMax) {
+ thumbnailsHeight = thumbnailsHeightMax;
+ thumbnailsWidth = Math.round(this._thumbnails.get_preferred_width(thumbnailsHeight)[1]);
+ }
+
+ let wsTmbX;
+ if (opt.SEC_WS_TMB_LEFT) { // left
+ wsTmbX = spacing / 2;
+ this._thumbnails._positionLeft = true;
+ } else {
+ wsTmbX = width - spacing / 2 - thumbnailsWidth;
+ this._thumbnails._positionLeft = false;
+ }
+
+ const childBox = new Clutter.ActorBox();
+ const availSpace = height - thumbnailsHeight;
+
+ let wsTmbY = availSpace / 2;
+ wsTmbY -= opt.SEC_WS_TMB_POSITION_ADJUSTMENT * wsTmbY;
+ wsTmbY += opt.SEC_WS_PREVIEW_SHIFT && Main.panel.visible ? Main.panel.height : 0;
+
+ childBox.set_origin(Math.round(wsTmbX), Math.round(wsTmbY));
+ childBox.set_size(thumbnailsWidth, thumbnailsHeight);
+ this._thumbnails.allocate(childBox);
+ }
+
+ const {
+ currentState, initialState, finalState, transitioning, progress,
+ } = this._overviewAdjustment.getStateTransitionParams();
+
+ let workspacesBox;
+ const workspaceParams = [contentBox, padding, thumbnailsWidth, spacing];
+ if (!transitioning) {
+ workspacesBox =
+ this._getWorkspacesBoxForState(currentState, ...workspaceParams);
+ } else {
+ const initialBox =
+ this._getWorkspacesBoxForState(initialState, ...workspaceParams);
+ const finalBox =
+ this._getWorkspacesBoxForState(finalState, ...workspaceParams);
+ workspacesBox = initialBox.interpolate(finalBox, progress);
+ }
+ this._workspacesView.allocate(workspacesBox);
+ },
+
+ _updateThumbnailVisibility() {
+ if (opt.OVERVIEW_MODE2)
+ this.set_child_above_sibling(this._thumbnails, null);
+
+ const visible = !opt.SEC_WS_TMB_HIDDEN;
+
+ if (this._thumbnails.visible === visible)
+ return;
+
+ this._thumbnails.show();
+ this._thumbnails.visible = visible;
+ this._updateThumbnailParams();
+ },
+
+ _updateThumbnailParams() {
+ if (opt.SEC_WS_TMB_HIDDEN)
+ return;
+
+ // workaround for upstream bug - secondary thumbnails boxes don't catch 'showing' signal on the shell startup and don't populate the box with thumbnails
+ // the tmbBox contents is also destroyed when overview state adjustment gets above 1 when swiping gesture from window picker to app grid
+ if (!this._thumbnails._thumbnails.length)
+ this._thumbnails._createThumbnails();
+
+ const { initialState, finalState, progress } =
+ this._overviewAdjustment.getStateTransitionParams();
+
+ const initialParams = this._getThumbnailParamsForState(initialState);
+ const finalParams = this._getThumbnailParamsForState(finalState);
+
+ /* const opacity =
+ Util.lerp(initialParams.opacity, finalParams.opacity, progress);
+ const scale =
+ Util.lerp(initialParams.scale, finalParams.scale, progress);*/
+
+ // OVERVIEW_MODE 2 should animate dash and wsTmbBox only if WORKSPACE_MODE === 0 (windows not spread)
+ const animateOverviewMode2 = opt.OVERVIEW_MODE2 && !(finalState === 1 && opt.WORKSPACE_MODE);
+ const translationX = !Main.layoutManager._startingUp && ((!opt.SHOW_WS_PREVIEW_BG && !opt.OVERVIEW_MODE2) || animateOverviewMode2)
+ ? Util.lerp(initialParams.translationX, finalParams.translationX, progress)
+ : 0;
+
+ this._thumbnails.set({
+ opacity: 255,
+ // scale_x: scale,
+ // scale_y: scale,
+ translation_x: translationX,
+ });
+ },
+
+ _updateWorkspacesView() {
+ if (this._workspacesView)
+ this._workspacesView.destroy();
+
+ if (this._settings.get_boolean('workspaces-only-on-primary')) {
+ opt.SEC_WS_TMB_HIDDEN = true;
+ this._workspacesView = new WorkspacesView.ExtraWorkspaceView(
+ this._monitorIndex,
+ this._overviewAdjustment);
+ } else {
+ opt.SEC_WS_TMB_HIDDEN = !opt.SHOW_SEC_WS_TMB;
+ this._workspacesView = new WorkspacesView.WorkspacesView(
+ this._monitorIndex,
+ this._controls,
+ this._scrollAdjustment,
+ // Secondary monitors don't need FitMode.ALL since there is workspace switcher always visible
+ // this._fitModeAdjustment,
+ new St.Adjustment({
+ actor: this,
+ value: 0, // FitMode.SINGLE,
+ lower: 0, // FitMode.SINGLE,
+ upper: 0, // FitMode.SINGLE,
+ }),
+ // secondaryOverviewAdjustment);
+ this._overviewAdjustment);
+ }
+ this.add_child(this._workspacesView);
+ this._thumbnails.opacity = 0;
+ },
+};
+
+const SecondaryMonitorDisplayHorizontal = {
+ _getThumbnailParamsForState(state) {
+ // const { ControlsState } = OverviewControls;
+
+ let opacity, scale, translationY;
+ switch (state) {
+ case ControlsState.HIDDEN:
+ opacity = 255;
+ scale = 1;
+ translationY = 0;
+ if (!Main.layoutManager._startingUp && (!opt.SHOW_WS_PREVIEW_BG || opt.OVERVIEW_MODE2))
+ translationY = this._thumbnails.height * (opt.SEC_WS_TMB_TOP ? -1 : 1);
+
+ break;
+ case ControlsState.WINDOW_PICKER:
+ case ControlsState.APP_GRID:
+ opacity = 255;
+ scale = 1;
+ translationY = 0;
+ break;
+ default:
+ opacity = 255;
+ scale = 1;
+ translationY = 0;
+ break;
+ }
+
+ return { opacity, scale, translationY };
+ },
+
+ _getWorkspacesBoxForState(state, box, padding, thumbnailsHeight, spacing) {
+ // const { ControlsState } = OverviewControls;
+ const workspaceBox = box.copy();
+ const [width, height] = workspaceBox.get_size();
+
+ let wWidth, wHeight, wsbX, wsbY, offset, yShift;
+ switch (state) {
+ case ControlsState.HIDDEN:
+ break;
+ case ControlsState.WINDOW_PICKER:
+ case ControlsState.APP_GRID:
+ if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)
+ break;
+
+ yShift = 0;
+ if (opt.SEC_WS_PREVIEW_SHIFT && Main.panel.visible) {
+ if (opt.PANEL_POSITION_TOP)
+ yShift = Main.panel.height;
+ else
+ yShift = -Main.panel.height;
+ }
+
+ wHeight = height - Math.abs(yShift) - (thumbnailsHeight ? thumbnailsHeight + 4 * spacing : padding);
+ wWidth = Math.min(wHeight * (width / height), width - 5 * spacing);
+ wWidth = Math.round(wWidth * opt.SEC_WS_PREVIEW_SCALE);
+ wHeight = Math.round(wHeight * opt.SEC_WS_PREVIEW_SCALE);
+
+ offset = Math.round((height - thumbnailsHeight - wHeight - Math.abs(yShift)) / 2);
+ if (opt.SEC_WS_TMB_TOP)
+ wsbY = thumbnailsHeight + offset;
+ else
+ wsbY = offset;
+
+ wsbY += yShift;
+ wsbX = Math.round((width - wWidth) / 2);
+
+ workspaceBox.set_origin(wsbX, wsbY);
+ workspaceBox.set_size(wWidth, wHeight);
+ break;
+ }
+
+ return workspaceBox;
+ },
+
+ _getThumbnailsHeight(box) {
+ if (opt.SEC_WS_TMB_HIDDEN)
+ return 0;
+
+ const [width, height] = box.get_size();
+ const { expandFraction } = this._thumbnails;
+ const [thumbnailsHeight] = this._thumbnails.get_preferred_height(width);
+ return Math.min(
+ thumbnailsHeight * expandFraction,
+ height * opt.SEC_MAX_THUMBNAIL_SCALE);
+ },
+
+ vfunc_allocate(box) {
+ this.set_allocation(box);
+
+ const themeNode = this.get_theme_node();
+ const contentBox = themeNode.get_content_box(box);
+ const [width, height] = contentBox.get_size();
+ const { expandFraction } = this._thumbnails;
+ const spacing = themeNode.get_length('spacing') * expandFraction;
+ const padding = Math.round(0.1 * height);
+
+ let thumbnailsWidth = 0;
+ let thumbnailsHeight = 0;
+ this._thumbnails.visible = !opt.SEC_WS_TMB_HIDDEN;
+ if (this._thumbnails.visible) {
+ const reservedHeight = opt.SEC_WS_PREVIEW_SHIFT && Main.panel.visible ? Main.panel.height : 0;
+
+ thumbnailsHeight = height * opt.SEC_MAX_THUMBNAIL_SCALE;
+
+ let totalTmbSpacing;
+ [totalTmbSpacing, thumbnailsWidth] = this._thumbnails.get_preferred_width(thumbnailsHeight);
+ thumbnailsWidth = Math.round(thumbnailsWidth + totalTmbSpacing);
+
+ const thumbnailsWidthMax = width - spacing;
+
+ if (thumbnailsWidth > thumbnailsWidthMax) {
+ thumbnailsWidth = thumbnailsWidthMax;
+ thumbnailsHeight = Math.round(this._thumbnails.get_preferred_height(thumbnailsWidth)[1]);
+ }
+
+ let wsTmbY;
+ if (opt.SEC_WS_TMB_TOP)
+ wsTmbY = spacing / 2 + reservedHeight;
+ else
+ wsTmbY = height - spacing / 2 - thumbnailsHeight;
+
+ const childBox = new Clutter.ActorBox();
+ const availSpace = width - thumbnailsWidth;
+
+ let wsTmbX = availSpace / 2;
+ wsTmbX -= opt.SEC_WS_TMB_POSITION_ADJUSTMENT * wsTmbX;
+
+ childBox.set_origin(Math.round(wsTmbX), Math.round(wsTmbY));
+ childBox.set_size(thumbnailsWidth, thumbnailsHeight);
+ this._thumbnails.allocate(childBox);
+ }
+
+ const {
+ currentState, initialState, finalState, transitioning, progress,
+ } = this._overviewAdjustment.getStateTransitionParams();
+
+ let workspacesBox;
+ const workspaceParams = [contentBox, padding, thumbnailsHeight, spacing];
+ if (!transitioning) {
+ workspacesBox =
+ this._getWorkspacesBoxForState(currentState, ...workspaceParams);
+ } else {
+ const initialBox =
+ this._getWorkspacesBoxForState(initialState, ...workspaceParams);
+ const finalBox =
+ this._getWorkspacesBoxForState(finalState, ...workspaceParams);
+ workspacesBox = initialBox.interpolate(finalBox, progress);
+ }
+ this._workspacesView.allocate(workspacesBox);
+ },
+
+ _updateThumbnailVisibility: SecondaryMonitorDisplayVertical._updateThumbnailVisibility,
+
+ _updateThumbnailParams() {
+ if (opt.SEC_WS_TMB_HIDDEN)
+ return;
+
+ // workaround for upstream bug - secondary thumbnails boxes don't catch 'showing' signal on the shell startup and don't populate the box with thumbnails
+ // the tmbBox contents is also destroyed when overview state adjustment gets above 1 when swiping gesture from window picker to app grid
+ if (!this._thumbnails._thumbnails.length)
+ this._thumbnails._createThumbnails();
+
+ const { initialState, finalState, progress } =
+ this._overviewAdjustment.getStateTransitionParams();
+
+ const initialParams = this._getThumbnailParamsForState(initialState);
+ const finalParams = this._getThumbnailParamsForState(finalState);
+
+ /* const opacity =
+ Util.lerp(initialParams.opacity, finalParams.opacity, progress);
+ const scale =
+ Util.lerp(initialParams.scale, finalParams.scale, progress);*/
+
+ // OVERVIEW_MODE 2 should animate dash and wsTmbBox only if WORKSPACE_MODE === 0 (windows not spread)
+ const animateOverviewMode2 = opt.OVERVIEW_MODE2 && !(finalState === 1 && opt.WORKSPACE_MODE);
+ const translationY = !Main.layoutManager._startingUp && ((!opt.SHOW_WS_PREVIEW_BG && !opt.OVERVIEW_MODE2) || animateOverviewMode2)
+ ? Util.lerp(initialParams.translationY, finalParams.translationY, progress)
+ : 0;
+
+ this._thumbnails.set({
+ opacity: 255,
+ // scale_x: scale,
+ // scale_y: scale,
+ translation_y: translationY,
+ });
+ },
+
+ _updateWorkspacesView() {
+ if (this._workspacesView)
+ this._workspacesView.destroy();
+
+ if (this._settings.get_boolean('workspaces-only-on-primary')) {
+ opt.SEC_WS_TMB_HIDDEN = true;
+ this._workspacesView = new WorkspacesView.ExtraWorkspaceView(
+ this._monitorIndex,
+ this._overviewAdjustment);
+ } else {
+ opt.SEC_WS_TMB_HIDDEN = !opt.SHOW_SEC_WS_TMB;
+ this._workspacesView = new WorkspacesView.WorkspacesView(
+ this._monitorIndex,
+ this._controls,
+ this._scrollAdjustment,
+ // Secondary monitors don't need FitMode.ALL since there is workspace switcher always visible
+ // this._fitModeAdjustment,
+ new St.Adjustment({
+ actor: this,
+ value: 0, // FitMode.SINGLE,
+ lower: 0, // FitMode.SINGLE,
+ upper: 0, // FitMode.SINGLE,
+ }),
+ // secondaryOverviewAdjustment);
+ this._overviewAdjustment);
+ }
+ this.add_child(this._workspacesView);
+ this._thumbnails.opacity = 0;
+ },
+};
+
+const ExtraWorkspaceViewCommon = {
+ _updateWorkspaceMode() {
+ const overviewState = this._overviewAdjustment.value;
+
+ const progress = Math.clamp(overviewState,
+ ControlsState.HIDDEN,
+ opt.OVERVIEW_MODE && !opt.WORKSPACE_MODE ? ControlsState.HIDDEN : ControlsState.WINDOW_PICKER);
+
+ this._workspace.stateAdjustment.value = progress;
+
+ // force ws preview bg corner radiuses where GS doesn't do it
+ if (opt.SHOW_WS_PREVIEW_BG && opt.OVERVIEW_MODE === 1)
+ this._workspace._background._updateBorderRadius(Math.min(1, this._workspace._overviewAdjustment.value));
+
+
+ // hide workspace background
+ if (!opt.SHOW_WS_PREVIEW_BG && this._workspace._background.opacity)
+ this._workspace._background.opacity = 0;
+ },
+
+ exposeWindows() {
+ const adjustment = this._workspace._background._stateAdjustment;
+ if (adjustment.value === 0) {
+ adjustment.value = 0;
+ adjustment.ease(1, {
+ duration: 200,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => {
+ opt.WORKSPACE_MODE = 1;
+ },
+ });
+ }
+ },
+};
+
+const WorkspacesDisplayCommon = {
+ _updateWorkspacesViews() {
+ for (let i = 0; i < this._workspacesViews.length; i++)
+ this._workspacesViews[i].destroy();
+
+ this._primaryIndex = Main.layoutManager.primaryIndex;
+ this._workspacesViews = [];
+ let monitors = Main.layoutManager.monitors;
+ for (let i = 0; i < monitors.length; i++) {
+ let view;
+ if (i === this._primaryIndex) {
+ view = new WorkspacesView.WorkspacesView(i,
+ this._controls,
+ this._scrollAdjustment,
+ this._fitModeAdjustment,
+ this._overviewAdjustment);
+
+ view.visible = this._primaryVisible;
+ this.bind_property('opacity', view, 'opacity', GObject.BindingFlags.SYNC_CREATE);
+ this.add_child(view);
+ } else {
+ view = new WorkspacesView.SecondaryMonitorDisplay(i,
+ this._controls,
+ this._scrollAdjustment,
+ // Secondary monitors don't need FitMode.ALL since there is workspace switcher always visible
+ // this._fitModeAdjustment,
+ new St.Adjustment({
+ actor: this,
+ value: 0, // FitMode.SINGLE,
+ lower: 0, // FitMode.SINGLE,
+ upper: 0, // FitMode.SINGLE,
+ }),
+ this._overviewAdjustment);
+ Main.layoutManager.overviewGroup.add_actor(view);
+ }
+
+ this._workspacesViews.push(view);
+ }
+ },
+
+ _onScrollEvent(actor, event) {
+ if (this._swipeTracker.canHandleScrollEvent(event))
+ return Clutter.EVENT_PROPAGATE;
+
+ if (!this.mapped)
+ return Clutter.EVENT_PROPAGATE;
+
+ if (this._workspacesOnlyOnPrimary &&
+ this._getMonitorIndexForEvent(event) !== this._primaryIndex)
+ return Clutter.EVENT_PROPAGATE;
+
+ if (opt.PANEL_MODE === 1) {
+ const panelBox = Main.layoutManager.panelBox;
+ const [, y] = global.get_pointer();
+ if (y > panelBox.allocation.y1 && y < panelBox.allocation.y2)
+ return Clutter.EVENT_STOP;
+ }
+
+ if (Me.Util.isShiftPressed()) {
+ let direction = Me.Util.getScrollDirection(event);
+ if (direction === null || (Date.now() - this._lastScrollTime) < 150)
+ return Clutter.EVENT_STOP;
+ this._lastScrollTime = Date.now();
+
+ if (direction === Clutter.ScrollDirection.UP)
+ direction = -1;
+
+ else if (direction === Clutter.ScrollDirection.DOWN)
+ direction = 1;
+ else
+ direction = 0;
+
+ if (direction) {
+ Me.Util.reorderWorkspace(direction);
+ // make all workspaces on primary monitor visible for case the new position is hidden
+ const primaryMonitorIndex = global.display.get_primary_monitor();
+ Main.overview._overview._controls._workspacesDisplay._workspacesViews[primaryMonitorIndex]._workspaces.forEach(w => {
+ w.visible = true;
+ });
+ return Clutter.EVENT_STOP;
+ }
+ }
+
+ return Main.wm.handleWorkspaceScroll(event);
+ },
+
+ _onKeyPressEvent(actor, event) {
+ const symbol = event.get_key_symbol();
+ /* const { ControlsState } = OverviewControls;
+ if (this._overviewAdjustment.value !== ControlsState.WINDOW_PICKER && symbol !== Clutter.KEY_space)
+ return Clutter.EVENT_PROPAGATE;*/
+
+ /* if (!this.reactive)
+ return Clutter.EVENT_PROPAGATE; */
+ const { workspaceManager } = global;
+ const vertical = workspaceManager.layout_rows === -1;
+ const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
+ const state = this._overviewAdjustment.value;
+
+ let which;
+ switch (symbol) {
+ case Clutter.KEY_Return:
+ case Clutter.KEY_KP_Enter:
+ if (Me.Util.isCtrlPressed()) {
+ Main.ctrlAltTabManager._items.forEach(i => {
+ if (i.sortGroup === 1 && i.name === 'Dash')
+ Main.ctrlAltTabManager.focusGroup(i);
+ });
+ }
+ return Clutter.EVENT_STOP;
+ case Clutter.KEY_Page_Up:
+ if (vertical)
+ which = Meta.MotionDirection.UP;
+ else if (rtl)
+ which = Meta.MotionDirection.RIGHT;
+ else
+ which = Meta.MotionDirection.LEFT;
+ break;
+ case Clutter.KEY_Page_Down:
+ if (vertical)
+ which = Meta.MotionDirection.DOWN;
+ else if (rtl)
+ which = Meta.MotionDirection.LEFT;
+ else
+ which = Meta.MotionDirection.RIGHT;
+ break;
+ case Clutter.KEY_Home:
+ which = 0;
+ break;
+ case Clutter.KEY_End:
+ which = workspaceManager.n_workspaces - 1;
+ break;
+ case Clutter.KEY_space:
+ if (Me.Util.isCtrlPressed() && Me.Util.isShiftPressed()) {
+ Me.Util.activateSearchProvider(Me.ESP_PREFIX);
+ } else if (Me.Util.isAltPressed()) {
+ Main.ctrlAltTabManager._items.forEach(i => {
+ if (i.sortGroup === 1 && i.name === 'Dash')
+ Main.ctrlAltTabManager.focusGroup(i);
+ });
+ } else if (opt.get('recentFilesSearchProviderModule') && Me.Util.isCtrlPressed()) {
+ Me.Util.activateSearchProvider(Me.RFSP_PREFIX);
+ } else if (opt.get('windowSearchProviderModule')) {
+ Me.Util.activateSearchProvider(Me.WSP_PREFIX);
+ }
+
+ return Clutter.EVENT_STOP;
+ case Clutter.KEY_Down:
+ case Clutter.KEY_Left:
+ case Clutter.KEY_Right:
+ case Clutter.KEY_Up:
+ case Clutter.KEY_Tab:
+ if (Main.overview._overview._controls._searchController.searchActive) {
+ Main.overview.searchEntry.grab_key_focus();
+ } else if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE && state === 1) {
+ // expose windows by "clicking" on ws thumbnail
+ // in this case overview stateAdjustment will be used for transition
+ Main.overview._overview.controls._thumbnailsBox._activateThumbnailAtPoint(0, 0, global.get_current_time(), true);
+ Main.ctrlAltTabManager._items.forEach(i => {
+ if (i.sortGroup === 1 && i.name === 'Windows')
+ Main.ctrlAltTabManager.focusGroup(i);
+ });
+ } else if (opt.OVERVIEW_MODE && !opt.WORKSPACE_MODE && state === 1) {
+ // expose windows for OVERVIEW_MODE 1
+ const wsIndex = global.workspace_manager.get_active_workspace().index();
+ // after expose animation activate keyboard for window selection
+ const callback = Me.Util.activateKeyboardForWorkspaceView;
+ this._workspacesViews.forEach(
+ view => {
+ view.exposeWindows(wsIndex, callback);
+ }
+ );
+ } else {
+ if (state === 2)
+ return Clutter.EVENT_PROPAGATE;
+ Me.Util.activateKeyboardForWorkspaceView();
+ }
+
+ return Clutter.EVENT_STOP;
+ default:
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ if (state === 2)
+ return Clutter.EVENT_PROPAGATE;
+
+ let ws;
+ if (which < 0)
+ // Negative workspace numbers are directions
+ ws = workspaceManager.get_active_workspace().get_neighbor(which);
+ else
+ // Otherwise it is a workspace index
+ ws = workspaceManager.get_workspace_by_index(which);
+
+ if (Me.Util.isShiftPressed()) {
+ let direction;
+ if (which === Meta.MotionDirection.UP || which === Meta.MotionDirection.LEFT)
+ direction = -1;
+ else if (which === Meta.MotionDirection.DOWN || which === Meta.MotionDirection.RIGHT)
+ direction = 1;
+ if (direction)
+ Me.Util.reorderWorkspace(direction);
+ // make all workspaces on primary monitor visible for case the new position is hidden
+ Main.overview._overview._controls._workspacesDisplay._workspacesViews[0]._workspaces.forEach(w => {
+ w.visible = true;
+ });
+ return Clutter.EVENT_STOP;
+ }
+
+ if (ws)
+ Main.wm.actionMoveWorkspace(ws);
+
+ return Clutter.EVENT_STOP;
+ },
+};
+
+// same copy of this function should be available in OverviewControls and WorkspacesView
+function _getFitModeForState(state) {
+ switch (state) {
+ case ControlsState.HIDDEN:
+ case ControlsState.WINDOW_PICKER:
+ return FitMode.SINGLE;
+ case ControlsState.APP_GRID:
+ if (opt.WS_ANIMATION && opt.SHOW_WS_TMB)
+ return FitMode.ALL;
+ else
+ return FitMode.SINGLE;
+ default:
+ return FitMode.SINGLE;
+ }
+}
diff --git a/extensions/vertical-workspaces/metadata.json b/extensions/44/vertical-workspaces/metadata.json
index dbfaa91..fa62b14 100644
--- a/extensions/vertical-workspaces/metadata.json
+++ b/extensions/44/vertical-workspaces/metadata.json
@@ -7,8 +7,16 @@
"43",
"44"
],
+ "session-modes": [
+ "user",
+ "unlock-dialog"
+ ],
"url": "https://github.com/G-dH/vertical-workspaces",
+ "donations": {
+ "buymeacoffee": "georgdh"
+ },
"gettext-domain": "vertical-workspaces",
"settings-schema": "org.gnome.shell.extensions.vertical-workspaces",
- "version": 28
+ "version-name": "44.10"
}
+
diff --git a/extensions/vertical-workspaces/po/cs.po b/extensions/44/vertical-workspaces/po/cs.po
index e588c73..e588c73 100644
--- a/extensions/vertical-workspaces/po/cs.po
+++ b/extensions/44/vertical-workspaces/po/cs.po
diff --git a/extensions/44/vertical-workspaces/po/nl.po b/extensions/44/vertical-workspaces/po/nl.po
new file mode 100644
index 0000000..2d9613e
--- /dev/null
+++ b/extensions/44/vertical-workspaces/po/nl.po
@@ -0,0 +1,1551 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR GdH
+# This file is distributed under the same license as the vertical-workspaces package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vertical-workspaces\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-03-08 12:37+0100\n"
+"PO-Revision-Date: 2023-05-04 14:03+0200\n"
+"Last-Translator: Heimen Stoffels <vistausss@fastmail.com>\n"
+"Language-Team: \n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 3.2.2\n"
+
+#: dash.js:743
+msgid "Search Open Windows (Hotkey: Space)"
+msgstr "Geopende vensters doorzoeken (sneltoets: spatiebalk)"
+
+#: dash.js:816
+msgid "Search Recent Files (Hotkey: Ctrl + Space)"
+msgstr "Onlangs gebruikte bestanden doorzoeken (sneltoets: Ctrl+spatiebalk)"
+
+#: windowSearchProvider.js:117 windowSearchProvider.js:119
+msgid "Open Windows"
+msgstr "Geopende vensters"
+
+#: windowSearchProvider.js:118
+msgid "List of open windows"
+msgstr "Een lijst met geopende vensters"
+
+#: appDisplay.js:1317
+msgid "Force Quit"
+msgstr "Toepassing gedwongen afsluiten"
+
+#: appDisplay.js:1335
+msgid "Move App to Current Workspace ( Shift + Click )"
+msgstr "Toepassing verplaatsen naar huidig werkblad (Shift+muisklik)"
+
+#: prefs.js:47 prefs.js:1465
+msgid "Layout"
+msgstr "Indeling"
+
+#: prefs.js:53
+msgid "Appearance"
+msgstr "Vormgeving"
+
+#: prefs.js:59
+msgid "Behavior"
+msgstr "Gedrag"
+
+#: prefs.js:65
+msgid "Misc"
+msgstr "Overig"
+
+#: prefs.js:71
+msgid "About"
+msgstr "Over"
+
+#: prefs.js:119 prefs.js:517 prefs.js:1030 prefs.js:1456
+msgid "Dash"
+msgstr "Dash"
+
+#: prefs.js:125
+msgid "Dash Position"
+msgstr "Dashlocatie"
+
+#: prefs.js:131
+msgid "Top"
+msgstr "Bovenaan"
+
+#: prefs.js:132
+msgid "Right"
+msgstr "Rechts"
+
+#: prefs.js:133 prefs.js:355
+msgid "Bottom"
+msgstr "Onderaan"
+
+#: prefs.js:134
+msgid "Left"
+msgstr "Links"
+
+#: prefs.js:135 prefs.js:393 prefs.js:557 prefs.js:572 prefs.js:587
+msgid "Hide"
+msgstr "Verbergen"
+
+#: prefs.js:142
+msgid "Center Horizontal Dash to Workspace"
+msgstr "Horizontale dash centreren op werkblad"
+
+#: prefs.js:143
+msgid ""
+"If the Dash Position is set to Top or Bottom, the position will be "
+"recalculated relative to the workspace preview instead of the screen. Works "
+"only with the default Dash."
+msgstr ""
+"Als de dashlocatie boven- of onderaan is, dan wordt de locatie herberekend "
+"op basis van de werkbladvoorvertoning in plaats van het scherm. Werkt alleen "
+"met de standaarddash."
+
+#: prefs.js:160
+msgid "Fine Tune Dash Position"
+msgstr "Dashlocatie aanpassen"
+
+#: prefs.js:161
+msgid ""
+"Adjusts position of the dock on chosen axis. Works only with the default "
+"Dash."
+msgstr ""
+"Pas de locatie van het dock op de gekozen as aan. Werkt alleen met de "
+"standaarddash."
+
+#: prefs.js:170
+msgid "Workspace Thumbnails / Orientation"
+msgstr "Werkbladminiaturen/-oriëntatie"
+
+#: prefs.js:176
+msgid "Thumbnails Position / Workspaces Orientation"
+msgstr "Miniatuurlocatie/Werkbladoriëntatie"
+
+#: prefs.js:177
+msgid ""
+"Position of the workspace thumbnails on the screen also sets orientation of "
+"the workspaces to vertical or horizontal. You have two options to disable "
+"workspace thumbnails, one sets workspaces to the vertical orientation, the "
+"second one to horizontal."
+msgstr ""
+"De locatie van werkbladminiaturen op het scherm stelt tevens de oriëntatie "
+"van werkbladen in op verticaal of horizontaal. U heeft twee mogelijkheden om "
+"miniaturen uit te schakelen: u kunt de werkbladen instellen op verticaal of "
+"horizontaal."
+
+#: prefs.js:183
+msgid "Left \t Vertical Orientation"
+msgstr "Links \t Verticale oriëntatie"
+
+#: prefs.js:184
+msgid "Right \t Vertical Orientation"
+msgstr "Rechts \t Horizontale oriëntatie"
+
+#: prefs.js:185
+msgid "Hide \t Set Vertical Orientation"
+msgstr "Verbergen \t Verticale oriëntatie instellen"
+
+#: prefs.js:186
+msgid "Top \t Horizontal Orientation"
+msgstr "Bovenaan \t Horizontale oriëntatie"
+
+#: prefs.js:187
+msgid "Bottom \t Horizontal Orientation"
+msgstr "Onderaan \t Horizontale oriëntatie"
+
+#: prefs.js:188
+msgid "Hide \t Set Horizontal Orientation"
+msgstr "Verbergen \t Horizontale oriëntatie instellen"
+
+#: prefs.js:204 prefs.js:409
+msgid "Fine Tune Workspace Thumbnails Position"
+msgstr "Werkbladminiatuurlocatie instellen"
+
+#: prefs.js:205
+msgid "Adjusts workspace thumbnails vertical position."
+msgstr "Pas de verticale positie van werkbladminiaturen aan."
+
+#: prefs.js:213
+msgid "Reserve Full Screen Height/Width for Thumbnails"
+msgstr "Gehele scherm gebruiken voor miniaturen"
+
+#: prefs.js:214
+msgid ""
+"The whole screen height/width will be reserved for workspace thumbnails at "
+"the expense of space available for Dash (if the Dash is oriented in a "
+"different axis)."
+msgstr ""
+"De gehele schermhoogte en -breedte zal worden gebruikt voor "
+"werkbladminiaturen. Let op: dit gaat ten koste van de beschikbare dashruimte "
+"(als de dash op een andere oriëntatie is ingesteld)."
+
+#: prefs.js:231 prefs.js:427
+msgid "Workspace Thumbnails Max Scale"
+msgstr "Max. omvang van werkbladminiaturen"
+
+#: prefs.js:232
+msgid ""
+"Adjusts maximum size of the workspace thumbnails (% relative to display "
+"width)."
+msgstr ""
+"Pas de maximale omvang van werkbladminiaturen aan (% relatief in verhouding "
+"tot de schermbreedte)."
+
+#: prefs.js:241 prefs.js:697
+msgid "Workspace Preview"
+msgstr "Werkbladvoorvertoning"
+
+#: prefs.js:256
+msgid "Workspaces Scale"
+msgstr "Werkbladomvang verkleinen"
+
+#: prefs.js:257
+msgid ""
+"Scales down workspace previews so you can fit more of the adjacent "
+"workspaces on the screen. Default size is calculated to use all available "
+"space."
+msgstr ""
+"Maak de werkbladvoorvertoningen kleiner om meer werkbladen op het scherm te "
+"tonen. De standaardomvang maakt gebruik van alle beschikbare ruimte."
+
+#: prefs.js:274
+msgid "Workspaces Spacing"
+msgstr "Ruimte tussen werkbladen"
+
+#: prefs.js:275
+msgid ""
+"Adjusts spacing between workspace previews so you can control how much of "
+"the adjacent workspaces overlap to the current workspace overview. Default "
+"value should set the adjacent workspaces out of the screen."
+msgstr ""
+"Pas de ruimte tussen werkbladvoorvertoningen aan zodat u zelf kunt bepalen "
+"hoeveel werkbladen mogen overlappen. De standaardwaarde ligt buiten het "
+"scherm."
+
+#: prefs.js:284 prefs.js:712 prefs.js:1072
+msgid "App Grid"
+msgstr "Toepassingsrooster"
+
+#: prefs.js:290
+msgid "Center App Grid"
+msgstr "Toepassingsrooster centreren"
+
+#: prefs.js:291
+msgid ""
+"App grid in app view page will be centered to the display instead of the "
+"available space. This option may have impact on the size of the grid, more "
+"for narrower and small resolution displays, especially if workspace "
+"thumbnails are bigger."
+msgstr ""
+"Toon het toepassingsrooster op het midden van het scherm in plaats van over "
+"de gehele ruimte. Let op: deze optie kan van invloed zijn op de "
+"roosteromvang. Op kleine schermen wordt het rooster smaller, vooral als de "
+"werkbladminiaturen groter zijn."
+
+#: prefs.js:300
+msgid "Search View"
+msgstr "Zoekweergave"
+
+#: prefs.js:306
+msgid "Center Search View"
+msgstr "Zoekweergave centreren"
+
+#: prefs.js:307
+msgid ""
+"Search view will be centered to the display instead of the available space."
+msgstr ""
+"Toon de zoekweergave op het midden van het scherm in plaats van over de "
+"gehele ruimte."
+
+#: prefs.js:315
+msgid "Always Show Search Entry"
+msgstr "Zoekvak altijd tonen"
+
+#: prefs.js:316
+msgid ""
+"If disabled, the search entry field will be hidden when not in use, so the "
+"workspace preview and app grid may take up more space."
+msgstr ""
+"Schakel uit om het zoekvak te verbergen als het niet wordt gebruikt, zodat "
+"er meer ruimte voor de werkbladvoorvertoningen en het toepassingsrooster is."
+
+#: prefs.js:333
+msgid "Search Results Width"
+msgstr "Breedte van zoekresultaten"
+
+#: prefs.js:334
+msgid ""
+"Adjusts maximum width of search results view (% relative to default). This "
+"allows you to fit more (or less) app icons into the app search result."
+msgstr ""
+"Pas de breedte van zoekresultaten aan (% relatief ten opzichte van "
+"standaard). Hierdoor kunt u meer of minder pictogrammen in de resultaten "
+"tonen."
+
+#: prefs.js:342 prefs.js:1483
+msgid "Panel"
+msgstr "Bovenbalk"
+
+#: prefs.js:348
+msgid "Main Panel Position"
+msgstr "Bovenbalklocatie"
+
+#: prefs.js:349
+msgid "Allows you to place the main panel at the bottom of your monitor."
+msgstr "Verplaats de bovenbalk naar de onderkant van het scherm."
+
+#: prefs.js:354
+msgid "Top (Default)"
+msgstr "Bovenaan (standaard)"
+
+#: prefs.js:362
+msgid "Main Panel Visibility"
+msgstr "Zichtbaarheid van bovenbalk"
+
+#: prefs.js:363
+msgid "Main panel can be visible always, only in the overview or never."
+msgstr "Toon de bovenbalk altijd, alleen op het overzicht of nooit."
+
+#: prefs.js:368
+msgid "Always Visible (Default)"
+msgstr "Altijd tonen (standaard)"
+
+#: prefs.js:369
+msgid "Overview Only"
+msgstr "Alleen op het overzicht"
+
+#: prefs.js:370
+msgid "Always Hidden"
+msgstr "Altijd verbergen"
+
+#: prefs.js:378
+msgid "Secondary Monitors"
+msgstr "Meerdere beeldschermen"
+
+#: prefs.js:384
+msgid "Workspace Thumbnails Position"
+msgstr "Werkbladminiatuurlocaties"
+
+#: prefs.js:385
+msgid ""
+"Allows you to place workspace thumbnails of secondary monitors on the "
+"opposite side than on the primary monitor."
+msgstr "Plaats werkbladminiaturen op andere beeldschermen dan het hoofdscherm."
+
+#: prefs.js:390
+msgid "Same as Primary"
+msgstr "Gelijk aan hoofdscherm"
+
+#: prefs.js:391
+msgid "Left / Top"
+msgstr "Links/Bovenaan"
+
+#: prefs.js:392
+msgid "Right / Bottom"
+msgstr "Rechts/Onderaan"
+
+#: prefs.js:410
+msgid "Adjusts secondary monitors workspace thumbnails vertical position."
+msgstr "Pas de verticale miniatuurpositie op andere beeldschermen aan."
+
+#: prefs.js:428
+msgid ""
+"Adjusts maximum size of the workspace thumbnails (% relative to display "
+"width) for secondary monitors."
+msgstr ""
+"Pas de maximale omvang van werkbladminiaturen op andere beeldschermen aan (% "
+"relatief in verhouding tot de schermbreedte)."
+
+#: prefs.js:445
+msgid "Workspace Preview Scale"
+msgstr "Werkbladvoorvertoningen verkleinen"
+
+#: prefs.js:446
+msgid "Scales down workspace previews on secondary monitors."
+msgstr "Verklein de voorvertoningen op andere beeldschermen."
+
+#: prefs.js:454
+msgid "Shift Workspace Preview by Panel Height"
+msgstr "Werkbladvoorvertoningen aanpassen aan bovenbalkhoogte"
+
+#: prefs.js:455
+msgid ""
+"This option can help align overview of the secondary monitor with the "
+"primary monitor."
+msgstr ""
+"Met deze optie kunt u het overzicht op een ander beeldscherm gelijkstellen "
+"aan die op het hoofdscherm."
+
+#: prefs.js:464
+msgid "Workspace Switcher Popup"
+msgstr "Werkbladwisselaarpop-up"
+
+#: prefs.js:480
+msgid "Horizontal Position (% from left)"
+msgstr "Horizontale positie (in % vanaf linkerzijde)"
+
+#: prefs.js:481
+msgid ""
+"This popup shows up when you switch workspace using a keyboard shortcut or "
+"gesture outside of the overview. You can disable it on the Behavior tab. If "
+"you want more control over the popup, try Workspace Switcher Manager "
+"extension."
+msgstr ""
+"Deze pop-up wordt getoond als u van werkblad wisselt met behulp van een "
+"sneltoets of gebaar buiten het overzicht om. U kunt de pop-up uitschakelen "
+"op het tabblad ‘Gedrag’. Als u de pop-up naar eigen hand wilt zetten, "
+"probeer dan de Workspace Switcher Manager-uitbreiding."
+
+#: prefs.js:499
+msgid "Vertical Position (% from top)"
+msgstr "Verticale positie (in % vanaf bovenzijde)"
+
+#: prefs.js:523
+msgid "Dash Max Icon Size"
+msgstr "Max. pictogramgrootte in dash"
+
+#: prefs.js:524
+msgid "Maximum size of Dash icons in pixels. Works only with default Dash."
+msgstr ""
+"De maximale pictogramgrootte, in pixels. Let op: dit werkt alleen in "
+"combinatie met de standaarddash."
+
+#: prefs.js:529 prefs.js:732 prefs.js:752 prefs.js:853
+msgid "128"
+msgstr "128"
+
+#: prefs.js:530 prefs.js:733 prefs.js:753 prefs.js:854
+msgid "112"
+msgstr "112"
+
+#: prefs.js:531 prefs.js:734 prefs.js:754 prefs.js:855
+msgid "96"
+msgstr "96"
+
+#: prefs.js:532 prefs.js:735 prefs.js:755 prefs.js:856
+msgid "80"
+msgstr "80"
+
+#: prefs.js:533 prefs.js:676 prefs.js:736 prefs.js:756 prefs.js:857
+msgid "64"
+msgstr "64"
+
+#: prefs.js:534 prefs.js:677 prefs.js:737 prefs.js:757 prefs.js:858
+msgid "48"
+msgstr "48"
+
+#: prefs.js:535 prefs.js:678 prefs.js:758 prefs.js:859
+msgid "32"
+msgstr "32"
+
+#: prefs.js:536
+msgid "24"
+msgstr "24"
+
+#: prefs.js:537
+msgid "16"
+msgstr "16"
+
+#: prefs.js:551
+msgid "Show Apps Icon Position"
+msgstr "Locatie van ‘Toepassingen tonen’"
+
+#: prefs.js:552
+msgid "Sets the position of the \"Show Applications\" icon in the Dash."
+msgstr "Stel de locatie van het pictogram ‘Toepassingen tonen’ in de dash in."
+
+#: prefs.js:558 prefs.js:573 prefs.js:588
+msgid "Start"
+msgstr "Begin"
+
+#: prefs.js:559 prefs.js:574 prefs.js:589
+msgid "End"
+msgstr "Einde"
+
+#: prefs.js:566
+msgid "Open Windows Icon Position"
+msgstr "Locatie van ‘Geopende vensters’"
+
+#: prefs.js:567
+msgid ""
+"This option adds \"Search Open Windows\" icon into dash (if window search "
+"provider enabled on the Behavior tab) so you can directly toggle window "
+"search provider results. Even if you disable this icon, you can use the "
+"secondary mouse button click on the Show Apps Icon, or the Space hotkey to "
+"access this feature."
+msgstr ""
+"Deze optie voegt een pictogram ‘Geopende vensters doorzoeken’ toe aan de "
+"dash (als de vensterzoekdienst is ingeschakeld op het tabblad ‘Gedrag’), "
+"zodat u direct kunt zoeken. Als u dit pictogram uitschakelt, dan kunt u deze "
+"functie alsnog aanroepen met behulp van een rechtermuisklik op ‘Toepassingen "
+"tonen’ of door te drukken op de spatiebalk."
+
+#: prefs.js:581
+msgid "Recent Files Icon Position"
+msgstr "Locatie van ‘Onlangs gebruikte bestanden’"
+
+#: prefs.js:582
+msgid ""
+"This option adds \"Search Recent Files\" icon into dash (if recent files "
+"search provider enabled on the Behavior tab) so you can directly toggle "
+"recent files search provider results. Even if you disable this icon, you can "
+"use Ctrl + Space hotkey to access this feature."
+msgstr ""
+"Deze optie voegt een pictogram ‘Onlangs gebruikte bestanden doorzoeken’ toe "
+"aan de dash (als de bestandszoekdienst is ingeschakeld op het tabblad "
+"‘Gedrag’), zodat u direct kunt zoeken. Als u dit pictogram uitschakelt, dan "
+"kunt u deze functie alsnog aanroepen met behulp van de sneltoets Ctrl + "
+"spatiebalk."
+
+#: prefs.js:597
+msgid "Dash Background Opacity"
+msgstr "Doorzichtigheid van dashachtergrond"
+
+#: prefs.js:598
+msgid "Adjusts the opacity of the dash background."
+msgstr "Pas de doorzichtigheid van de dashachtergrond aan."
+
+#: prefs.js:614
+msgid "Dash Background Radius"
+msgstr "Dash-achtergrondstraal"
+
+#: prefs.js:615
+msgid ""
+"Adjusts the border radius of the dash background in pixels. 0 means default "
+"value."
+msgstr ""
+"Pas de straal van de dashachtergrond aan (in pixels). 0 = standaardwaarde."
+
+#: prefs.js:623 prefs.js:1050
+msgid "Workspace Thumbnails"
+msgstr "Werkbladminiaturen"
+
+#: prefs.js:629
+msgid "Show Workspace Thumbnail Labels"
+msgstr "Werkbladminiatuurlabels tonen"
+
+#: prefs.js:630
+msgid ""
+"Each workspace thumbnail can show its index and name (if defined in the "
+"system settings) or name/title of its most recently used app/window."
+msgstr ""
+"Toon de namen van werkbladen (indien ingesteld in de systeemvoorkeuren) of "
+"naam+titel van onlangs gebruikte toepassing/venster."
+
+#: prefs.js:635 prefs.js:680 prefs.js:1001 prefs.js:1062 prefs.js:1260
+#: prefs.js:1278 prefs.js:1296 prefs.js:1331
+msgid "Disable"
+msgstr "Uitschakelen"
+
+#: prefs.js:636
+msgid "Index"
+msgstr "Index"
+
+#: prefs.js:637
+msgid "Index + WS Name"
+msgstr "Index + Werkbladnaam"
+
+#: prefs.js:638
+msgid "Index + App Name"
+msgstr "Index + Toepassingsnaam"
+
+#: prefs.js:639
+msgid "Index + Window Title"
+msgstr "Index + Venstertitel"
+
+#: prefs.js:646
+msgid "Show WS Thumbnail Label on Hover"
+msgstr "Miniatuurlabels tonen na aanwijzen"
+
+#: prefs.js:647
+msgid "Show label only when the mouse pointer hovers over a thumbnail"
+msgstr "Toon de labels alleen als u met de aanwijzer een miniatuur aanwijst."
+
+#: prefs.js:655
+msgid "Show Wallpaper in Workspace Thumbnails"
+msgstr "Werkbladminiaturen voorzien van achtergrond"
+
+#: prefs.js:656
+msgid "All workspace thumbnails will include the current desktop background."
+msgstr "Toon de huidige bureaubladachtergrond op werkbladminiaturen."
+
+#: prefs.js:664
+msgid "Window Preview"
+msgstr "Venstervoorvertoning"
+
+#: prefs.js:670
+msgid "Window Preview App Icon Size"
+msgstr "Pictogramgrootte in venstervoorvertoning"
+
+#: prefs.js:671
+msgid "Default size is 64."
+msgstr "Standaard: 64."
+
+#: prefs.js:679
+msgid "22"
+msgstr "22"
+
+#: prefs.js:687
+msgid "Always Show Window Titles"
+msgstr "Venstertitels altijd tonen"
+
+#: prefs.js:688
+msgid ""
+"All windows on the workspace preview will show their titles, not only the "
+"one with the mouse pointer."
+msgstr ""
+"Toon venstertitels van alle vensters op de voorvertoning, niet alleen van "
+"het venster onder de aanwijzer."
+
+#: prefs.js:703
+msgid "Show Workspace Preview Background"
+msgstr "Werkbladvoorvertoning voorzien van achtergrond"
+
+#: prefs.js:704
+msgid "Allows you to hide the scaling background of the workspace preview."
+msgstr "Toon of verberg de achtergrond op de werkbladvoorvertoning."
+
+#: prefs.js:718
+msgid "Icon Size"
+msgstr "Pictogramgrootte"
+
+#: prefs.js:719
+msgid ""
+"Allows to force fixed icon size and bypass the default adaptive algorithm."
+msgstr ""
+"Stel een vaste pictogramgrootte in ter vervanging van de standaard "
+"aanpasbare grootte."
+
+#: prefs.js:724 prefs.js:751
+msgid "Adaptive (Default)"
+msgstr "Aanpasbaar (standaard)"
+
+#: prefs.js:725
+msgid "256"
+msgstr "256"
+
+#: prefs.js:726
+msgid "224"
+msgstr "224"
+
+#: prefs.js:727
+msgid "208"
+msgstr "208"
+
+#: prefs.js:728
+msgid "192"
+msgstr "192"
+
+#: prefs.js:729
+msgid "176"
+msgstr "176"
+
+#: prefs.js:730
+msgid "160"
+msgstr "160"
+
+#: prefs.js:731
+msgid "144"
+msgstr "144"
+
+#: prefs.js:745
+msgid "Folder Icon Size"
+msgstr "Pictogramgrootte van mappen"
+
+#: prefs.js:746
+msgid ""
+"Allows to disable the default adaptive algorithm and set a fixed size of "
+"icons inside folders."
+msgstr ""
+"Stel een vaste pictogramgrootte in ter vervanging van de standaard "
+"aanpasbare grootte."
+
+#: prefs.js:766
+msgid "Max App Folder Icon Grid Size"
+msgstr "Max. grootte van mappen op rooster"
+
+#: prefs.js:767
+msgid ""
+"Each folder icon shows (up to) 4 app icons as a preview of the folder "
+"content, this option allows you to increase the number to 9 icons if folder "
+"contains more than 4 or 8 apps. The latter avoids half empty folder icons."
+msgstr ""
+"Elk mappictogram toont maximaal 4 pictogrammen als voorvertoning. Met behulp "
+"van deze optie kunt u het aantal verhogen naar maximaal 9 als de map 4 of 8 "
+"toepassingen bevat. De laatste optie voorkomt halflege mappictogrammen."
+
+#: prefs.js:772
+msgid "2x2 (Default)"
+msgstr "2x2 (standaard)"
+
+#: prefs.js:773
+msgid "3x3 for 5+ apps"
+msgstr "3x3 (5 of meer toepassingen)"
+
+#: prefs.js:774
+msgid "3x3 for 9+ apps"
+msgstr "3x3 (9 of meer toepassingen)"
+
+#: prefs.js:788
+msgid "Columns per Page (0 for adaptive grid)"
+msgstr "Aantal kolommen per pagina (0 = aanpasbaar rooster)"
+
+#: prefs.js:789
+msgid ""
+"Number of columns in application grid. If set to 0 (default setting) the "
+"number will be set automatically to fit available height."
+msgstr ""
+"Het aantal kolommen van het toepassingsrooster. Stel in op 0 (standaard) om "
+"automatisch aan te passen aan de beschikbare hoogte."
+
+#: prefs.js:803
+msgid "Rows per Page (0 for adaptive grid)"
+msgstr "Aantal rijen per pagina (0 = aanpasbaar rooster)"
+
+#: prefs.js:804
+msgid ""
+"Number of rows in application grid. If set to 0 (default setting) the number "
+"will be set automatically to fit available height."
+msgstr ""
+"Het aantal rijen van het toepassingsrooster. Stel in op 0 (standaard) om "
+"automatisch aan te passen aan de beschikbare hoogte."
+
+#: prefs.js:818
+msgid "Folder Columns per Page (0 for adaptive grid)"
+msgstr "Aantal mapkolommen per pagina (0 = aanpasbaar rooster)"
+
+#: prefs.js:819
+msgid ""
+"Number of columns in folder grid. If you leave the value on 0, the number of "
+"columns will be calculated to fit all folder icons."
+msgstr ""
+"Het aantal kolommen van het mappenrooster. Stel in op 0 (standaard) om "
+"automatisch aan te passen aan de beschikbare pictogrammen."
+
+#: prefs.js:833
+msgid "Folder Rows per Page (0 for adaptive grid)"
+msgstr "Aantal maprijen per pagina (0 = aanpasbaar rooster)"
+
+#: prefs.js:834
+msgid ""
+"Number of rows in folder grid. If you leave the value on 0, the number of "
+"rows will be calculated to fit all folder icons."
+msgstr ""
+"Het aantal rijen van het mappenrooster. Stel in op 0 (standaard) om "
+"automatisch aan te passen aan de beschikbare pictogrammen."
+
+#: prefs.js:841 prefs.js:1174 prefs.js:1492
+msgid "Search"
+msgstr "Zoeken"
+
+#: prefs.js:847
+msgid "App Search Icon Size"
+msgstr "Omvang van zoekresultaten"
+
+#: prefs.js:848
+msgid "Size of results provided by the App Search Provider."
+msgstr "De omvang van toepassingszoekresultaten."
+
+#: prefs.js:878
+msgid "Max Search Results Rows"
+msgstr "Aantal zoekresultaatrijen"
+
+#: prefs.js:879
+msgid ""
+"Sets the maximum number of rows for result lists of all search providers "
+"except window search provider which always lists all results."
+msgstr ""
+"Stel het maximumaantal rijen van resultaatlijsten van alle zoekdiensten (met "
+"uitzondering van vensters) in."
+
+#: prefs.js:888
+msgid "Overview Background"
+msgstr "Overzichtsachtergrond"
+
+#: prefs.js:894
+msgid "Show Static Background"
+msgstr "Eigen achtergrond tonen"
+
+#: prefs.js:895
+msgid "Show static background wallpaper instead of the solid grey color."
+msgstr "Stel een eigen achtergrond in in plaats van de grijze kleur."
+
+#: prefs.js:911
+msgid "Blur Window Picker Background"
+msgstr "Vensterkiezerachtergrond vervagen"
+
+#: prefs.js:912
+msgid "Blur background wallpaper (if enabled) in the window picker view."
+msgstr "Vervaag de achtergrond (indien ingeschakeld) van de vensterkiezer."
+
+#: prefs.js:928
+msgid "Blur App Grid/Search View Background"
+msgstr "Toepassingsrooster-/Zoekweergave-achtergrond vervagen"
+
+#: prefs.js:929
+msgid ""
+"Blur background wallpaper (if enabled) in the app grid and search results "
+"views."
+msgstr ""
+"Vervaag de achtergrond (indien ingeschakeld) van het toepassingsrooster en "
+"de zoekweergave."
+
+#: prefs.js:937
+msgid "Smooth Blur Transitions"
+msgstr "Vloeiende vervaagovergangen"
+
+#: prefs.js:938
+msgid ""
+"Makes blur transitions smoother but can impact overall smoothness of "
+"overview animations."
+msgstr ""
+"Maak vervaagovergangen vloeiender. Let op: dit kan van invloed zijn op de "
+"overige animaties."
+
+#: prefs.js:953 prefs.js:980 prefs.js:1002
+msgid "Overview"
+msgstr "Overzicht"
+
+#: prefs.js:959
+msgid "Overview Mode"
+msgstr "Overzichtsmodus"
+
+#: prefs.js:960
+msgid ""
+"The Expose Windows on Hover mode do not expose the workspace preview windows "
+"until the mouse pointer enters any window.\n"
+"The Static Workspace mode does not scale the workspace preview, it only "
+"shows Dash and workspace thumbnails over the desktop. Clicking on a "
+"workspace thumbnail scales the ws preview and exposes its windows like in "
+"the default overview mode."
+msgstr ""
+"De modus ‘Vensters tonen na aanwijzen’ toont geen werkbladminiaturen totdat "
+"de aanwijzer een venster aanwijst.\n"
+"De statische modus toont geen verkleinde werkbladminiaturen, maar alleen de "
+"dash en miniaturen boven het bureaublad. Klik op een werkbladminiatuur om de "
+"voorvertoning te verkleinen en alle vensters te tonen, net als in de "
+"standaard overzichtsmodus."
+
+#: prefs.js:965 prefs.js:1259 prefs.js:1277 prefs.js:1317
+msgid "Default"
+msgstr "Standaard"
+
+#: prefs.js:966
+msgid "Expose Windows on Hover"
+msgstr "Vensters tonen na aanwijzen"
+
+#: prefs.js:967
+msgid "Static Workspace"
+msgstr "Statische werkbladen"
+
+#: prefs.js:974
+msgid "Startup State"
+msgstr "Opstartmodus"
+
+#: prefs.js:975
+msgid "Allows to change the state in which GNOME Shell starts a session."
+msgstr "Geef aan in welke modus GNOME Shell een sessie dient te starten."
+
+#: prefs.js:981
+msgid "Desktop"
+msgstr "Bureaublad"
+
+#: prefs.js:982 prefs.js:1003
+msgid "Applications"
+msgstr "Toepassingen"
+
+#: prefs.js:989
+msgid ""
+"Hot Corner (Install Custom Hot Corners - Extended extension for more options)"
+msgstr ""
+"Snelhoek (installeer voor meer mogelijkheden de uitbreiding ‘Custom Hot "
+"Corners - Extended)"
+
+#: prefs.js:995
+msgid "Hot corner Action"
+msgstr "Snelhoekactie"
+
+#: prefs.js:996
+msgid ""
+"Disable or change behavior of hot corner. Holding down the Ctrl key while "
+"hitting the hot corner switches between Overview/Applications actions."
+msgstr ""
+"Pas het gedrag van de snelhoek aan of schakel deze uit. Houd Ctrl ingedrukt "
+"tijdens het aanwijzen van de snelhoek om te schakelen tussen het overzicht "
+"en de toepassingen."
+
+#: prefs.js:1010
+msgid "Enable Hot Corner in Full-Screen mode"
+msgstr "Snelhoek tonen in schermvullende modus"
+
+#: prefs.js:1011
+msgid ""
+"If you often work with full-screen applications and want the hot corner to "
+"be usable."
+msgstr ""
+"Als u regelmatig met schermvullende toepassingen werkt en de snelhoek wilt "
+"blijven gebruiken."
+
+#: prefs.js:1020
+msgid "Show Ripples Animation"
+msgstr "Golfanimatie tonen"
+
+#: prefs.js:1021
+msgid "Ripples animation shows up when you trigger hot corner."
+msgstr "Toon een golfanimatie zodra u de snelhoek activeert."
+
+#: prefs.js:1036
+msgid "Dash Icon Click"
+msgstr "Klikken op dashpictogram"
+
+#: prefs.js:1037
+msgid ""
+"if the app you clicked on has more than one window and the recently used "
+"window is not on the current workspace, the overview can switch to the "
+"workspace with the recent window."
+msgstr ""
+"Als de aangeklikte toepassing meer dan dan één venster bevat en het onlangs "
+"gebruikte venster niet op het huidige werkblad staat, dan kan worden "
+"overgeschakeld naar het juiste werkblad."
+
+#: prefs.js:1042
+msgid "Activate Last Used Window Immediately"
+msgstr "Laatstgebruikte venster focussen"
+
+#: prefs.js:1043
+msgid "Switch to Workspace with Recently Used Window"
+msgstr "Overschakelen naar werkblad met laatstgebruikte venster"
+
+#: prefs.js:1056
+msgid "Close Workspace Button"
+msgstr "Werkbladsluitknop"
+
+#: prefs.js:1057
+msgid ""
+"The Close Workspace button appears on the workspace thumbnail when you hover "
+"over it and allows you to close all windows on the workspace. You can choose "
+"a safety lock to prevent accidental use."
+msgstr ""
+"De werkbladsluitknop wordt getoond zodra u een miniatuur aanwijst. Hiermee "
+"kunt u alle vensters op het desbetreffende werkblad sluiten. U kunt "
+"instellen dat u sluiten wilt voorkomen."
+
+#: prefs.js:1063
+msgid "Single Click"
+msgstr "Eenmaal klikken"
+
+#: prefs.js:1064
+msgid "Double Click"
+msgstr "Dubbelklikken"
+
+#: prefs.js:1065
+msgid "Ctrl Key + Click"
+msgstr "Ctlr+klik"
+
+#: prefs.js:1078
+msgid "Apps Order"
+msgstr "Toepassingsvolgorde"
+
+#: prefs.js:1079
+msgid ""
+"Choose sorting method for the app grid. Note that sorting by alphabet and "
+"usage ignores folders."
+msgstr ""
+"Kies de sorteermethode van het toepassingsrooster. Let op: sorteren op "
+"alfabet of gebruik negeert mappen."
+
+#: prefs.js:1084
+msgid "Custom (Default)"
+msgstr "Aangepast (standaard)"
+
+#: prefs.js:1085
+msgid "Alphabet"
+msgstr "Alfabet"
+
+#: prefs.js:1086
+msgid "Usage"
+msgstr "Gebruik"
+
+#: prefs.js:1093
+msgid "App Grid Content"
+msgstr "Inhoud van toepassingsrooster"
+
+#: prefs.js:1094
+msgid ""
+"The default Shell removes favorite apps, this option lets you duplicate them "
+"in the grid or remove also running applications. Option \"Favorites and "
+"Running First\" only works with the Alphabet and Usage sorting."
+msgstr ""
+"Standaard worden favoriete toepassingen verborgen. Met behulp van deze optie "
+"kunt u ze klonen op het rooster of ook actieve toepassingen verbergen. Let "
+"op: de optie ‘Favorieten en actieve bovenaan’ werkt alleen in combinatie met "
+"sorteren op alfabet of gebruik."
+
+#: prefs.js:1099
+msgid "Include All"
+msgstr "Alles"
+
+#: prefs.js:1100
+msgid "Include All - Favorites and Running First"
+msgstr "Alles - Favorieten en actieve bovenaan"
+
+#: prefs.js:1101
+msgid "Exclude Favorites (Default)"
+msgstr "Favorieten verbergen (standaard)"
+
+#: prefs.js:1102
+msgid "Exclude Running"
+msgstr "Actieve verbergen"
+
+#: prefs.js:1103
+msgid "Exclude Favorites and Running"
+msgstr "Favorieten en actieve verbergen"
+
+#: prefs.js:1110
+msgid "Active Icons in Folder Preview"
+msgstr "Actieve pictogrammen op mapvoorvertoning"
+
+#: prefs.js:1111
+msgid ""
+"If enabled, clicking an app icon in a folder preview directly opens the app "
+"without having to open the folder first. Middle button opens new window of "
+"the app without closing the overview, so you can open multiple apps in a row "
+"on the current workspace and secondary button opens the folder."
+msgstr ""
+"Schakel in om op een toepassingspictogram te kunnen klikken vanuit een "
+"mapvoorvertoning. Hierdoor hoeft niet eerst de map te worden geopend. Met "
+"een middelklik opent u een nieuw venster zonder het overzicht te sluiten, "
+"zodat u meerdere toepassingen per rij kunt openen. Met een rechtermuisklik "
+"wordt de map geopend."
+
+#: prefs.js:1120
+msgid "Center Open Folders"
+msgstr "Geopende mappen centreren"
+
+#: prefs.js:1121
+msgid ""
+"App folder may open in the center of the screen or above the source folder "
+"icon."
+msgstr ""
+"Toon mappen op het midden van het scherm in plaats van boven het "
+"mappictogram."
+
+#: prefs.js:1130
+msgid "Allow Incomplete Pages"
+msgstr "Onvolledige pagina's tonen"
+
+#: prefs.js:1131
+msgid ""
+"If disabled, icons from the next page (if any) are automatically moved to "
+"fill any empty slot left after an icon was (re)moved (to a folder for "
+"example)."
+msgstr ""
+"Schakel uit om pictogrammen van de volgende pagina (indien beschikbaar) "
+"automatisch te verplaatsen om gaten op te vullen als er pictogrammen "
+"verplaatst of verwijderd zijn."
+
+#: prefs.js:1140
+msgid "App Labels Behavior"
+msgstr "Toepassingslabels"
+
+#: prefs.js:1141
+msgid "Choose how and when to display app names."
+msgstr "Geef aan hoe en wanneer er toepassingsnamen dienen te worden getoond."
+
+#: prefs.js:1146
+msgid "Ellipsized - Expand Selected (Default)"
+msgstr "Ingekort - Selectie volledig tonen (standaard)"
+
+#: prefs.js:1147
+msgid "Always Expanded"
+msgstr "Altijd volledig tonen"
+
+#: prefs.js:1148
+msgid "Hidden - Show Selected Only"
+msgstr "Verborgen - Alleen selectie tonen"
+
+#: prefs.js:1154
+msgid "Reset App Grid Layout"
+msgstr "Standaardindeling herstellen"
+
+#: prefs.js:1155
+msgid ""
+"Removes all stored app grid icons positions, after the reset icons will be "
+"ordered alphabetically."
+msgstr "Wis alle pictogramlocaties en sorteer alle pictogrammen op alfabet."
+
+#: prefs.js:1163
+msgid "Remove App Grid Folders"
+msgstr "Mappen verwijderen"
+
+#: prefs.js:1164
+msgid "Removes all folders, folder apps move to root grid."
+msgstr "Verwijder alle mappen en verplaats toepassingen naar het hoofdrooster."
+
+#: prefs.js:1186
+msgid "Enable Window Search Provider"
+msgstr "Vensters doorzoeken"
+
+#: prefs.js:1187
+msgid ""
+"Activates the window search provider that adds open windows to the search "
+"results. You can search app names and window titles. You can also use \"wq/"
+"\" prefix to suppress results from other search providers."
+msgstr ""
+"Schakel de dienst om geopende vensters te zoeken in. U kunt zoeken op "
+"toepassingsnamen en venstertitels. Ook kunt u ‘wq/’ voorafgaand aan een "
+"zoekopdracht toevoegen om resultaten van andere diensten te verbergen."
+
+#: prefs.js:1195
+msgid "Enable Recent Files Search Provider"
+msgstr "Onlangs gebruikte bestanden doorzoeken"
+
+#: prefs.js:1196
+msgid ""
+"Activates the recent files search provider that can be triggered by a dash "
+"icon, Ctrl + Space hotkey or by typing \"fq//\" prefix in the search entry "
+"field. This option needs File History option enabled in the GNOME Privacy "
+"settings."
+msgstr ""
+"Schakel de dienst in om onlangs gebruikte bestanden te doorzoeken. Dit kan "
+"met behulp van een dashpictogram, Ctrl+spatiebalk of door ‘fq//’ voorafgaand "
+"aan een zoekopdracht in te vullen. Let op: voor deze optie is "
+"bestandsgeschiedenis vereist. Die optie vindt u in de GNOME-"
+"privacyvoorkeuren."
+
+#: prefs.js:1204
+msgid "Enable Fuzzy Match"
+msgstr "Onduidelijke overeenkomsten inschakelen"
+
+#: prefs.js:1205
+msgid ""
+"Enabling the fuzzy match allows you to skip letters in the pattern you are "
+"searching for and find \"Firefox\" even if you type \"ffx\". Works only for "
+"the App, Window and Recent files search providers."
+msgstr ""
+"Schakel onduidelijke overeenkomsten in om letters over te slaan. Voorbeeld: "
+"‘Firefox’ wordt gevonden als u ‘ffx’ typt. Let op: dit werkt alleen in "
+"combinatie met de diensten toepassingen, vensters en onlangs gebruikte "
+"bestanden."
+
+#: prefs.js:1223
+msgid "Animations - General"
+msgstr "Animaties - Algemeen"
+
+#: prefs.js:1238
+msgid "Animation Speed"
+msgstr "Animatiesnelheid"
+
+#: prefs.js:1239
+msgid ""
+"Adjusts the global animation speed in % of the default duration - higher "
+"value means slower animation."
+msgstr ""
+"Pas de algemene animatiesnelheid aan (in %). Hogere waarde = langzamere "
+"animatie."
+
+#: prefs.js:1247
+msgid "Animations - Overview"
+msgstr "Animaties - Overzicht"
+
+#: prefs.js:1253
+msgid "App Grid Animation"
+msgstr "Animatie van toepassingsrooster"
+
+#: prefs.js:1254
+msgid ""
+"When entering the App Grid view, the app grid animates from the edge of the "
+"screen. You can choose direction, keep it Default (direction will be chosen "
+"automatically) or disable the animation if you don't like it."
+msgstr ""
+"Toon een animatie vanaf de zijkant na het openen van het toepassingsrooster. "
+"U kunt aangeven vanuit welke richting de animatie dient te komen (standaard: "
+"automatisch) of de animatie in zijn geheel uitschakelen."
+
+#: prefs.js:1261 prefs.js:1279
+msgid "Right to Left"
+msgstr "Van rechts naar links"
+
+#: prefs.js:1262 prefs.js:1280
+msgid "Left to Right"
+msgstr "Van links naar rechts"
+
+#: prefs.js:1263 prefs.js:1281
+msgid "Bottom to Top"
+msgstr "Van boven naar onder"
+
+#: prefs.js:1264 prefs.js:1282
+msgid "Top to Bottom"
+msgstr "Van onder naar boven"
+
+#: prefs.js:1271
+msgid "Search View Animation"
+msgstr "Animatie van zoekweergave"
+
+#: prefs.js:1272
+msgid ""
+"When search is activated the search view with search results can animate "
+"from the edge of the screen. You can choose direction, keep it Default "
+"(currently Bottom to Top) or disable the animation if you don't like it."
+msgstr ""
+"Toon een animatie vanaf de zijkant na het openen van de zoekweergave. U kunt "
+"aangeven vanuit welke richting de animatie dient te komen (standaard: van "
+"onder naar boven) of de animatie in zijn geheel uitschakelen."
+
+#: prefs.js:1290
+msgid "Workspace Preview Animation"
+msgstr "Animatie van werkbladminiaturen"
+
+#: prefs.js:1291
+msgid ""
+"When entering / leaving the App Grid / Search view, the workspace preview "
+"can animate to/from workspace thumbnail."
+msgstr ""
+"Toon een animatie na het openen en sluiten van het toepassingsrooster en de "
+"zoekweergave."
+
+#: prefs.js:1297
+msgid "Enable"
+msgstr "Inschakelen"
+
+#: prefs.js:1305
+msgid "Workspace Switcher"
+msgstr "Werkbladwisselaar"
+
+#: prefs.js:1311
+msgid "Workspace Switcher Animation"
+msgstr "Animatie van werkbladwisselaar"
+
+#: prefs.js:1312
+msgid ""
+"Allows you to disable movement of the desktop background during workspace "
+"switcher animation outside of the overview. The Static Background mode also "
+"keeps Conky and desktop icons on their place during switching."
+msgstr ""
+"Hiermee kunt u de animatie van de bureaubladachtergrond op de "
+"werkbladwisselaar buiten het overzicht uitschakelen. De statische modus laat "
+"Conky en pictogrammen op hun plaats staan tijdens het wisselen."
+
+#: prefs.js:1318
+msgid "Static Background"
+msgstr "Statische achtergrond"
+
+#: prefs.js:1325
+msgid "Workspace Switcher Popup Mode"
+msgstr "Werkbladwisselaarpop-upmodus"
+
+#: prefs.js:1326
+msgid ""
+"This popup shows up when you switch workspace using a keyboard shortcut or "
+"gesture outside of the overview. You can to disable the popup at all, or "
+"show it on the current monitor (the one with mouse pointer) instead of the "
+"primary."
+msgstr ""
+"Deze pop-up wordt getoond als u van werkblad wisselt met behulp van een "
+"sneltoets of gebaar buiten het overzicht. U kunt de pop-up in zijn geheel "
+"uitschakelen of alleen op het huidige beeldscherm (het scherm met de "
+"aanwijzer) tonen."
+
+#: prefs.js:1332
+msgid "Show on Primary Monitor (Default)"
+msgstr "Tonen op hoofdscherm (standaard)"
+
+#: prefs.js:1333
+msgid "Show on Current Monitor"
+msgstr "Tonen op huidig beeldscherm"
+
+#: prefs.js:1341
+msgid "Notifications"
+msgstr "Meldingen"
+
+#: prefs.js:1347
+msgid "Notification Banner Position"
+msgstr "Meldingslocatie"
+
+#: prefs.js:1348
+msgid "Choose where the notification pop-ups appear on the screen."
+msgstr "Geef aan op welke locatie meldingen dienen te worden getoond."
+
+#: prefs.js:1353
+msgid "Top Left"
+msgstr "Linksboven"
+
+#: prefs.js:1354
+msgid "Top Middle"
+msgstr "Linksmidden"
+
+#: prefs.js:1355
+msgid "Top Right (Default)"
+msgstr "Rechtsboven (standaard)"
+
+#: prefs.js:1356
+msgid "Bottom Left"
+msgstr "Linksonder"
+
+#: prefs.js:1357
+msgid "Bottom Middle"
+msgstr "Middenonder"
+
+#: prefs.js:1358
+msgid "Bottom Right"
+msgstr "Rechtsonder"
+
+#: prefs.js:1365
+msgid "Window Attention Handler"
+msgstr "Vensterfocusafhandeling"
+
+#: prefs.js:1366
+msgid ""
+"When a window requires attention (often a new window), GNOME Shell shows you "
+"a notification about it. You can disable popups of these messages "
+"(notification will be pushed into the message tray silently) or focus the "
+"source window immediately instead."
+msgstr ""
+"Als een venster om focus vraagt (doorgaans een nieuw venster), dan toont "
+"GNOME Shell een melding. U kunt deze meldingen uitschakelen om ze direct "
+"naar het berichtenvak te sturen of het venster direct focussen."
+
+#: prefs.js:1371 prefs.js:1386
+msgid "Show Notifications (Default)"
+msgstr "Meldingen tonen (standaard)"
+
+#: prefs.js:1372
+msgid "Disable Notification Popups"
+msgstr "Meldingen uitschakelen"
+
+#: prefs.js:1373
+msgid "Immediately Focus Window"
+msgstr "Venster direct focussen"
+
+#: prefs.js:1380
+msgid "Favorites"
+msgstr "Favorieten"
+
+#: prefs.js:1381
+msgid "Disable pin/unpin app notifications."
+msgstr "Schakel meldingen omtrent favorieten uit."
+
+#: prefs.js:1387
+msgid "Disable Notifications"
+msgstr "Meldingen uitschakelen"
+
+#: prefs.js:1402
+msgid "Keyboard"
+msgstr "Toetsenbord"
+
+#: prefs.js:1408
+msgid "Override Page Up/Down Shortcuts"
+msgstr "Page Up-/Down-sneltoetsgedrag aanpassen"
+
+#: prefs.js:1409
+msgid ""
+"This option automatically overrides the (Shift +) Super + Page Up/Down "
+"keyboard shortcuts for the current workspace orientation. If you encounter "
+"any issues, check the configuration in the dconf editor."
+msgstr ""
+"Met deze optie kunt u het gedrag van de sneltoetsen (Shift +) Super + Page "
+"Up/Down binnen de huidige werkbladoriëntatie aanpassen. Let op: als u "
+"problemen ervaart, bekijk dan de configuratie in dconf-bewerker."
+
+#: prefs.js:1417
+msgid "Compatibility"
+msgstr "Compatibiliteit"
+
+#: prefs.js:1423
+msgid "Fix for Dash to Dock"
+msgstr "Dash-to-Dock-oplossing"
+
+#: prefs.js:1424
+msgid ""
+"With the default Ubuntu Dock and other Dash To Dock forks, you may "
+"experience issues with Activities overview after you change Dock position or "
+"change monitors configuration. If you are experiencing such issues, try to "
+"enable this option, or (better) disable/replace the dock extension."
+msgstr ""
+"Met het standaard Ubuntu-dock en andere Dash-to-Dock-varianten kunt u "
+"problemen met het activiteitenoverzicht ervaren als u de docklocatie of "
+"beeldschermvoorkeuren aanpast. In dat geval kunt u deze optie proberen of de "
+"dockuitbreiding in kwestie uit te schakelen/te vervangen."
+
+#: prefs.js:1432
+msgid ""
+"V-Shell Modules that can be disabled in case of conflict or misbehavior."
+msgstr ""
+"V-Shellmodules die kunnen worden uitgeschakeld bij problemen of conflicten."
+
+#: prefs.js:1438
+msgid "AppFavorites"
+msgstr "Favoriete toepassingen"
+
+#: prefs.js:1439
+msgid "Pin/unpin app notification options."
+msgstr "Opties omtrent favorietenmeldingen."
+
+#: prefs.js:1447
+msgid "AppDisplay / IconGrid"
+msgstr "Toepassingsweergave/-rooster"
+
+#: prefs.js:1448
+msgid "App grid customization and options."
+msgstr "Opties omtrent het aanpassen van het toepassingsrooster."
+
+#: prefs.js:1457
+msgid "Dash configuration options and support for vertical orientation."
+msgstr "Dashopties en ondersteuning voor verticale oriëntatie."
+
+#: prefs.js:1466
+msgid ""
+"Hot corner options, removes right panel barrier that collides with CHC-E "
+"extension."
+msgstr ""
+"Snelhoekopties. Verwijder de barrière van de rechterbalk die botst met de "
+"CHC-E-uitbreiding."
+
+#: prefs.js:1474
+msgid "MessageTray"
+msgstr "Berichtenvak"
+
+#: prefs.js:1475
+msgid "Notification position options."
+msgstr "Opties omtrent meldingslocaties."
+
+#: prefs.js:1484
+msgid "Panel options."
+msgstr "Bovenbalkopties."
+
+#: prefs.js:1493
+msgid "Search view and app search provider customization and options."
+msgstr "Zoekweergave- en zoekdienstopties."
+
+#: prefs.js:1501
+msgid "SwipeTracker"
+msgstr "Gebaar-volgsysteem"
+
+#: prefs.js:1502
+msgid "Gestures for vertical workspace orientation."
+msgstr "Gebaren in de verticale werkbladoriëntatie."
+
+#: prefs.js:1510
+msgid "WindowAttentionHandler"
+msgstr "Vensterfocusafhandeling"
+
+#: prefs.js:1511
+msgid "Window attention handler options."
+msgstr "Vensterfocusafhandelingsopties."
+
+#: prefs.js:1519
+msgid "WindowManager"
+msgstr "Vensterbeheer"
+
+#: prefs.js:1520
+msgid ""
+"Fixes an upstream bug in the minimization animation of a full-screen window."
+msgstr ""
+"Lost een bug omtrent de minimaliseeranimatie van schermvullende vensters op."
+
+#: prefs.js:1528
+msgid "WindowPreview"
+msgstr "Venstervoorvertoning"
+
+#: prefs.js:1529
+msgid ""
+"Window preview options, fixes an upstream bug that fills the system log with "
+"errors when you close a window from an overview or exit the overview with a "
+"gesture when any window is selected."
+msgstr ""
+"Venstervoorvertoningsopties. Lost een bug op omtrent het vastleggen van "
+"foutmeldingen in het systeemlogboek na het sluiten van een venster vanuit "
+"het overzicht of sluiten van het overzicht met een gebaar."
+
+#: prefs.js:1537
+msgid "Workspace"
+msgstr "Werkblad"
+
+#: prefs.js:1538
+msgid ""
+"Fixes workspace preview allocations for vertical workspaces orientation and "
+"window scaling in static overview modes."
+msgstr ""
+"Lost een bug omtrent het toewijzen van werkbladvoorvertoningen in verticale "
+"oriëntatie op, alsmede vensterschaling in de statische modus."
+
+#: prefs.js:1546
+msgid "WorkspaceAnimation"
+msgstr "Werkbladanimatie"
+
+#: prefs.js:1547
+msgid "Static workspace animation option."
+msgstr "Statische werkbladanimatie."
+
+#: prefs.js:1555
+msgid "WorkspaceSwitcherPopup"
+msgstr "Werkbladwisselaarpop-up"
+
+#: prefs.js:1556
+msgid "Workspace switcher popup position options."
+msgstr "Opties omtrent de werkbladwisselaarpop-up."
+
+#: prefs.js:1573
+msgid "Version"
+msgstr "Versie"
+
+#: prefs.js:1579
+msgid "Reset all options"
+msgstr "Standaardwaarden herstellen"
+
+#: prefs.js:1580
+msgid "Set all options to default values."
+msgstr "Herstel alle standaardvoorkeuren."
+
+#: prefs.js:1586
+msgid "Links"
+msgstr "Links"
+
+#: prefs.js:1590
+msgid "Homepage"
+msgstr "Website"
+
+#: prefs.js:1591
+msgid "Source code and more info about this extension"
+msgstr "Broncode en meer informatie over deze uitbreiding"
+
+#: prefs.js:1596
+msgid "Changelog"
+msgstr "Wijzigingslog"
+
+#: prefs.js:1597
+msgid "See what's changed."
+msgstr "Bekijk alle wijzigingen."
+
+#: prefs.js:1602
+msgid "GNOME Extensions"
+msgstr "GNOME-uitbreidingen"
+
+#: prefs.js:1603
+msgid "Rate and comment the extension on GNOME Extensions site."
+msgstr "Beoordeel deze uitbreiding op de GNOME-uitbreidingensite."
+
+#: prefs.js:1608
+msgid "Report a bug or suggest new feature"
+msgstr "Bug melden of idee delen"
+
+#: prefs.js:1614
+msgid "Buy Me a Coffee"
+msgstr "Trakteer me op koffie"
+
+#: prefs.js:1615
+msgid "If you like this extension, you can help me with my coffee expenses."
+msgstr ""
+"Als u deze uitbreiding graag gebruikt, dan kunt u me trakteren op een kopje "
+"koffie."
+
+#: recentFilesSearchProvider.js:109
+msgid "Search recent files"
+msgstr "Onlangs gebruikte bestanden doorzoeken"
+
+#: recentFilesSearchProvider.js:110
+msgid "Recent Files"
+msgstr "Onlangs gebruikte bestanden"
diff --git a/extensions/vertical-workspaces/po/vertical-workspaces.pot b/extensions/44/vertical-workspaces/po/vertical-workspaces.pot
index 44ccddb..44ccddb 100644
--- a/extensions/vertical-workspaces/po/vertical-workspaces.pot
+++ b/extensions/44/vertical-workspaces/po/vertical-workspaces.pot
diff --git a/extensions/vertical-workspaces/prefs.js b/extensions/44/vertical-workspaces/prefs.js
index 6cea321..b757b91 100644
--- a/extensions/vertical-workspaces/prefs.js
+++ b/extensions/44/vertical-workspaces/prefs.js
@@ -9,115 +9,142 @@
'use strict';
-const { Gtk, GLib } = imports.gi;
+const Gtk = imports.gi.Gtk;
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-const Settings = Me.imports.lib.settings;
+const MyExtension = ExtensionUtils.getCurrentExtension();
+const OptionsFactory = MyExtension.imports.lib.optionsFactory;
+const GObject = imports.gi.GObject;
-const ItemFactory = Me.imports.lib.optionsFactory.ItemFactory;
-const AdwPrefs = Me.imports.lib.optionsFactory.AdwPrefs;
-const LegacyPrefs = Me.imports.lib.optionsFactory.LegacyPrefs;
+let Me;
+let _;
+let opt;
-const shellVersion = Settings.shellVersion;
-
-// gettext
-const _ = Settings._;
-
-// libadwaita is available starting with GNOME Shell 42.
-let Adw = null;
-try {
- Adw = imports.gi.Adw;
-} catch (e) {}
+function init() {
+ Me = {};
-let gOptions;
-let pageList;
-let itemFactory;
+ Me.shellVersion = parseFloat(imports.misc.config.PACKAGE_VERSION);
+ Me.imports = MyExtension.imports;
+ Me.metadata = MyExtension.metadata;
+ Me.gSettings = ExtensionUtils.getSettings(Me.metadata['settings-schema']);
+ Me.Settings = MyExtension.imports.lib.settings;
+ Me.gettext = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
-function init() {
- ExtensionUtils.initTranslations(Me.metadata['gettext-domain']);
- gOptions = new Settings.Options();
+ Me.opt = new Me.Settings.Options(Me);
+ _ = Me.gettext;
+ opt = Me.opt;
- itemFactory = new ItemFactory(gOptions);
+ OptionsFactory.init(Me);
+}
- pageList = [
+function _getPageList() {
+ const itemFactory = new OptionsFactory.ItemFactory();
+ const pageList = [
+ {
+ name: 'profiles',
+ title: _('Profiles'),
+ iconName: 'open-menu-symbolic',
+ optionList: _getProfilesOptionList(itemFactory),
+ },
{
name: 'layout',
title: _('Layout'),
iconName: 'view-grid-symbolic',
- optionList: _getLayoutOptionList(),
+ optionList: _getLayoutOptionList(itemFactory),
},
{
name: 'appearance',
title: _('Appearance'),
iconName: 'view-reveal-symbolic',
- optionList: _getAppearanceOptionList(),
+ optionList: _getAppearanceOptionList(itemFactory),
},
{
name: 'behavior',
title: _('Behavior'),
iconName: 'system-run-symbolic',
- optionList: _getBehaviorOptionList(),
+ optionList: _getBehaviorOptionList(itemFactory),
+ },
+ {
+ name: 'modules',
+ title: _('Modules'),
+ iconName: 'application-x-addon-symbolic',
+ optionList: _getModulesOptionList(itemFactory),
},
{
name: 'misc',
title: _('Misc'),
iconName: 'preferences-other-symbolic',
- optionList: _getMiscOptionList(),
- },
- {
- name: 'profiles',
- title: _('Profiles'),
- iconName: 'open-menu-symbolic',
- optionList: _getProfilesOptionList(),
+ optionList: _getMiscOptionList(itemFactory),
},
{
name: 'about',
title: _('About'),
iconName: 'preferences-system-details-symbolic',
- optionList: _getAboutOptionList(),
+ optionList: _getAboutOptionList(itemFactory),
},
];
+
+ return pageList;
}
function fillPreferencesWindow(window) {
- window = new AdwPrefs(gOptions).getFilledWindow(window, pageList);
+ window = new OptionsFactory.AdwPrefs(opt).getFilledWindow(window, _getPageList());
window.connect('close-request', () => {
- gOptions.destroy();
- gOptions = null;
- itemFactory = null;
- pageList = null;
+ opt.destroy();
+ opt = null;
+ Me = null;
+ _ = null;
});
window.set_default_size(800, 800);
}
-function buildPrefsWidget() {
- const prefsWidget = new LegacyPrefs(gOptions).getPrefsWidget(pageList);
-
- prefsWidget.connect('realize', widget => {
- const window = widget.get_root ? widget.get_root() : widget.get_toplevel();
- const width = 800;
- const height = 800;
- window.set_default_size(width, height);
- const headerbar = window.get_titlebar();
- headerbar.title_widget = prefsWidget._stackSwitcher;
-
- const signal = Gtk.get_major_version() === 3 ? 'destroy' : 'close-request';
- window.connect(signal, () => {
- gOptions.destroy();
- gOptions = null;
- });
- });
+// ////////////////////////////////////////////////////////////////////
+function _getProfilesOptionList(itemFactory) {
+ const optionList = [];
+ // options item format:
+ // (text, caption, widget, settings-variable, [options for combo], sensitivity-depends-on-bool-variable)
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Custom Profiles'),
+ _('Sets of settings that can help you with the initial customization')
+ )
+ );
+
+ optionList.push(itemFactory.getRowWidget(
+ _('Profile 1'),
+ null,
+ itemFactory.newPresetButton(opt, 1)
+ ));
+
+ optionList.push(itemFactory.getRowWidget(
+ _('Profile 2'),
+ null,
+ itemFactory.newPresetButton(opt, 2)
+ ));
+
+ optionList.push(itemFactory.getRowWidget(
+ _('Profile 3'),
+ null,
+ itemFactory.newPresetButton(opt, 3)
+ ));
+
+ optionList.push(itemFactory.getRowWidget(
+ _('Profile 4'),
+ null,
+ itemFactory.newPresetButton(opt, 4)
+ ));
- return prefsWidget;
+ return optionList;
}
-// ////////////////////////////////////////////////////////////////////
-function _getLayoutOptionList() {
+function _getLayoutOptionList(itemFactory) {
const optionList = [];
// options item format:
- // [text, caption, widget, settings-variable, options for combo]
+ // (text, caption, widget, settings-variable, [options for combo], sensitivity-depends-on-bool-variable)
optionList.push(
itemFactory.getRowWidget(
@@ -129,8 +156,8 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('Dash Position'),
null,
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'dashPosition',
[
[_('Top'), 0],
@@ -138,7 +165,8 @@ function _getLayoutOptionList() {
[_('Bottom'), 2],
[_('Left'), 3],
[_('Hide'), 4],
- ]
+ ],
+ 'dashModule'
)
);
@@ -147,7 +175,9 @@ function _getLayoutOptionList() {
_('Center Horizontal Dash to Workspace'),
_('If the Dash Position is set to Top or Bottom, the position will be recalculated relative to the workspace preview instead of the screen'),
itemFactory.newSwitch(),
- 'centerDashToWs'
+ 'centerDashToWs',
+ null,
+ 'dashModule'
)
);
@@ -165,7 +195,73 @@ function _getLayoutOptionList() {
_('Fine Tune Dash Position'),
_('Adjusts the position of the dash on the axis given by the orientation of the workspaces'),
dashPositionScale,
- 'dashPositionAdjust'
+ 'dashPositionAdjust',
+ null,
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Show Apps Icon Position'),
+ _('Sets the position of the "Show Applications" icon in the Dash'),
+ // // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'showAppsIconPosition',
+ [
+ [_('Hide'), 2],
+ [_('Start'), 0],
+ [_('End'), 1],
+ ],
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Open Windows Icon Position'),
+ _('Allows to add "Search Open Windows" icon into Dash (if window search provider enabled on the Modules tab) so you can directly toggle window search provider results. You can also use the secondary mouse button click on the Show Apps Icon, or the Space hotkey'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'dashShowWindowsIcon',
+ [
+ [_('Hide'), 0],
+ [_('Start'), 1],
+ [_('End'), 2],
+ ],
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Recent Files Icon Position'),
+ _('Allows to add "Search Recent Files" icon into Dash (if recent files search provider enabled on the Modules tab) so you can directly toggle recent files search provider results. You can also use Ctrl + Space hotkey'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'dashShowRecentFilesIcon',
+ [
+ [_('Hide'), 0],
+ [_('Start'), 1],
+ [_('End'), 2],
+ ],
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Extensions Icon Position'),
+ _('Allows to add "Search Extensions" icon into Dash (if extensions search provider enabled on the Module tab) so you can directly toggle extensions search provider results. You can also use the Ctrl + Shift + Space hotkey'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'dashShowExtensionsIcon',
+ [
+ [_('Hide'), 0],
+ [_('Start'), 1],
+ [_('End'), 2],
+ ],
+ 'dashModule'
)
);
@@ -180,17 +276,17 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('Thumbnails Position / Workspaces Orientation'),
_('Position of the workspace thumbnails on the screen also sets orientation of the workspaces to vertical or horizontal. You have two options to disable workspace thumbnails, one sets workspaces to vertical orientation, the second one to horizontal.'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'workspaceThumbnailsPosition',
// this mess is just because of backward compatibility
[
- [_('Left \t Vertical Orientation'), 0],
- [_('Right \t Vertical Orientation'), 1],
- [_('Hide \t Set Vertical Orientation'), 4],
- [_('Top \t Horizontal Orientation'), 5],
+ [_('Left \t Vertical Orientation'), 0],
+ [_('Right \t Vertical Orientation'), 1],
+ [_('Hide \t Vertical Orientation'), 4],
+ [_('Top \t Horizontal Orientation'), 5],
[_('Bottom \t Horizontal Orientation'), 6],
- [_('Hide \t Set Horizontal Orientation'), 9],
+ [_('Hide \t Horizontal Orientation'), 9],
]
)
);
@@ -233,7 +329,7 @@ function _getLayoutOptionList() {
wsThumbnailScale.add_mark(13, Gtk.PositionType.TOP, null);
optionList.push(
itemFactory.getRowWidget(
- _('Workspace Thumbnails Max Scale'),
+ _('Workspace Thumbnails Max Scale - Window Picker'),
_('Adjusts maximum size of the workspace thumbnails in the overview (% relative to display width)'),
wsThumbnailScale,
'wsThumbnailScale'
@@ -248,11 +344,11 @@ function _getLayoutOptionList() {
});
const wsThumbnailAppScale = itemFactory.newScale(wsThumbnailAppScaleAdjustment);
- wsThumbnailAppScale.add_mark(0, Gtk.PositionType.TOP, null);
+ wsThumbnailAppScale.add_mark(13, Gtk.PositionType.TOP, null);
optionList.push(
itemFactory.getRowWidget(
_('Workspace Thumbnails Max Scale - App View'),
- _('Set to 0 to follow "Workspace Thumbnails Max Scale" scale. Allows you to set different thumbnails scale for the Applications view'),
+ _('Allows you to set different thumbnails scale for the Applications view'),
wsThumbnailAppScale,
'wsThumbnailScaleAppGrid'
)
@@ -330,7 +426,9 @@ function _getLayoutOptionList() {
_('App Grid Page Width Scale'),
_('Adjusts max app grid page width relative to the available space.'),
agPageWidthScale,
- 'appGridPageWidthScale'
+ 'appGridPageWidthScale',
+ null,
+ 'appDisplayModule'
)
);
@@ -372,7 +470,9 @@ function _getLayoutOptionList() {
_('Search Results Width'),
_('Adjusts maximum width of search results view (% relative to default). This allows to fit more (or less) app icons into the app search result'),
searchViewScale,
- 'searchViewScale'
+ 'searchViewScale',
+ null,
+ 'searchModule'
)
);
@@ -386,13 +486,14 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('Main Panel Position'),
_('Allows to place the main panel at the bottom of the primary display'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'panelPosition',
[
[_('Top (Default)'), 0],
[_('Bottom'), 1],
- ]
+ ],
+ 'panelModule'
)
);
@@ -400,15 +501,16 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('Main Panel Visibility'),
_('Allows to hide main panel when not needed'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'panelVisibility',
[
[_('Always Visible (Default)'), 0],
[_('Overview Only'), 1],
[_('Always Hidden'), 2],
// [_('Desktop View Only'), 3],
- ]
+ ],
+ 'panelModule'
)
);
@@ -434,7 +536,9 @@ function _getLayoutOptionList() {
_('Horizontal Position (% from left)'),
_('This popup shows up when you switch workspace using a keyboard shortcut or gesture outside of the overview. You can disable it on the "Behavior" tab. If you want more control over the popup, try the "Workspace Switcher Manager" extension'),
hScale,
- 'wsSwPopupHPosition'
+ 'wsSwPopupHPosition',
+ null,
+ 'workspaceSwitcherPopupModule'
)
);
@@ -453,7 +557,9 @@ function _getLayoutOptionList() {
_('Vertical Position (% from top)'),
null,
vScale,
- 'wsSwPopupVPosition'
+ 'wsSwPopupVPosition',
+ null,
+ 'workspaceSwitcherPopupModule'
)
);
@@ -467,17 +573,18 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('Notification Banner Position'),
_('Choose where the notification banners appear on the screen'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'notificationPosition',
[
[_('Top Left'), 0],
- [_('Top Center'), 1],
- [_('Top Right (Default)'), 2],
+ [_('Top Center (Default)'), 1],
+ [_('Top Right'), 2],
[_('Bottom Left'), 3],
[_('Bottom Center'), 4],
[_('Bottom Right'), 5],
- ]
+ ],
+ 'messageTrayModule'
)
);
@@ -485,8 +592,8 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('OSD Popup Position'),
_('Choose where the OSD pop-ups (like sound volume level) appear on the screen'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'osdPosition',
[
[_('Disable'), 0],
@@ -497,7 +604,8 @@ function _getLayoutOptionList() {
[_('Bottom Left'), 5],
[_('Bottom Center (Default)'), 6],
[_('Bottom Right'), 7],
- ]
+ ],
+ 'osdWindowModule'
)
);
@@ -511,8 +619,8 @@ function _getLayoutOptionList() {
itemFactory.getRowWidget(
_('Workspace Thumbnails Position'),
_('Allows to place workspace thumbnails of secondary monitors on the opposite side than on the primary monitor'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'secWsThumbnailsPosition',
[
[_('Same as Primary'), 2],
@@ -543,7 +651,7 @@ function _getLayoutOptionList() {
const secWsThumbnailScaleAdjustment = new Gtk.Adjustment({
upper: 30,
- lower: 5,
+ lower: 0,
step_increment: 1,
page_increment: 1,
});
@@ -591,10 +699,10 @@ function _getLayoutOptionList() {
return optionList;
}
-function _getAppearanceOptionList() {
+function _getAppearanceOptionList(itemFactory) {
const optionList = [];
// options item format:
- // [text, caption, widget, settings-variable, options for combo]
+ // (text, caption, widget, settings-variable, [options for combo], sensitivity-depends-on-bool-variable)
// ----------------------------------------------------------------
optionList.push(
@@ -607,8 +715,8 @@ function _getAppearanceOptionList() {
itemFactory.getRowWidget(
_('Dash Max Icon Size'),
_('Maximum size of Dash icons in pixels'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'dashMaxIconSize',
[
[_('128'), 128],
@@ -618,54 +726,23 @@ function _getAppearanceOptionList() {
[_('64'), 64],
[_('48'), 48],
[_('32'), 32],
- [_('24'), 24],
- [_('16'), 16],
- ]
- )
- );
-
- optionList.push(
- itemFactory.getRowWidget(
- _('Show Apps Icon Position'),
- _('Sets the position of the "Show Applications" icon in the Dash'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
- 'showAppsIconPosition',
- [
- [_('Hide'), 2],
- [_('Start'), 0],
- [_('End'), 1],
- ]
- )
- );
-
- optionList.push(
- itemFactory.getRowWidget(
- _('Open Windows Icon Position'),
- _('Allows to add "Search Open Windows" icon into Dash (if window search provider enabled on the Behavior tab) so you can directly toggle window search provider results. You can also use the secondary mouse button click on the Show Apps Icon, or the Space hotkey'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
- 'dashShowWindowsIcon',
- [
- [_('Hide'), 0],
- [_('Start'), 1],
- [_('End'), 2],
- ]
+ ],
+ 'dashModule'
)
);
optionList.push(
itemFactory.getRowWidget(
- _('Recent Files Icon Position'),
- _('Allows to add "Search Recent Files" icon into Dash (if recent files search provider enabled on the Behavior tab) so you can directly toggle recent files search provider results. You can also use Ctrl + Space hotkey'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
- 'dashShowRecentFilesIcon',
+ _('Dash Background Style'),
+ _('Allows you to change the background color of the dash to match the search results an app folders'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'dashBgColor',
[
- [_('Hide'), 0],
- [_('Start'), 1],
- [_('End'), 2],
- ]
+ [_('Default'), 0],
+ [_('Light'), 1],
+ ],
+ 'dashModule'
)
);
@@ -682,7 +759,9 @@ function _getAppearanceOptionList() {
_('Dash Background Opacity'),
_('Adjusts the opacity of the Dash background'),
dashBgOpacityScale,
- 'dashBgOpacity'
+ 'dashBgOpacity',
+ null,
+ 'dashModule'
)
);
@@ -699,7 +778,35 @@ function _getAppearanceOptionList() {
_('Dash Background Radius'),
_('Adjusts the border radius of the Dash background in pixels. 0 means the default value given by the current theme style'),
dashBgRadiusScale,
- 'dashBgRadius'
+ 'dashBgRadius',
+ null,
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Dash Background GNOME 3 Style'),
+ _('Background of the vertically oriented dash will imitate the GNOME 3 style'),
+ itemFactory.newSwitch(),
+ 'dashBgGS3Style',
+ null,
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Running App Indicator'),
+ _('Allows you to change style of the running app indicator under the app icon'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'runningDotStyle',
+ [
+ [_('Dot (Default)'), 0],
+ [_('Line'), 1],
+ ],
+ 'dashModule'
)
);
@@ -713,8 +820,8 @@ function _getAppearanceOptionList() {
itemFactory.getRowWidget(
_('Show Workspace Thumbnail Labels'),
_('Each workspace thumbnail can show label with its index and name (if defined in the system settings) or name/title of its most recently used app/window'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'showWsTmbLabels',
[
[_('Disable'), 0],
@@ -754,8 +861,8 @@ function _getAppearanceOptionList() {
itemFactory.getRowWidget(
_('Window Preview App Icon Size'),
null,
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'winPreviewIconSize',
[
[_('64 (Default)'), 0],
@@ -763,16 +870,35 @@ function _getAppearanceOptionList() {
[_('32'), 2],
[_('22'), 3],
[_('Disable'), 4],
- ]
+ ],
+ 'windowPreviewModule'
)
);
optionList.push(
itemFactory.getRowWidget(
- _('Always Show Window Titles'),
- _('All windows on the workspace preview will still show their titles, not only the one with the mouse pointer'),
+ _('Window Title Position / Visibility'),
+ _('Sets the position of the window title that is displayed when the mouse hovers over the window or can always be visible'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'winTitlePosition',
+ [
+ [_('Inside Window'), 0],
+ [_('Inside Window Always Visible'), 1],
+ [_('Below Window (Default)'), 2],
+ ],
+ 'windowPreviewModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Show Close Window Button'),
+ _('Allows you to hide close window button'),
itemFactory.newSwitch(),
- 'alwaysShowWinTitles'
+ 'winPreviewShowCloseButton',
+ null,
+ 'windowPreviewModule'
)
);
@@ -820,8 +946,8 @@ function _getAppearanceOptionList() {
itemFactory.getRowWidget(
_('Icon Size'),
_('Allows to set a fixed app grid icon size and bypass the default adaptive algorithm'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'appGridIconSize',
[
[_('Adaptive (Default)'), -1],
@@ -839,7 +965,8 @@ function _getAppearanceOptionList() {
[_('64'), 64],
[_('48'), 48],
// [_('32'), 32],
- ]
+ ],
+ 'appDisplayModule'
)
);
@@ -847,8 +974,8 @@ function _getAppearanceOptionList() {
itemFactory.getRowWidget(
_('Folder Icon Size'),
_('Allows to set a fixed icon size and bypass the default adaptive algorithm in the open folder dialog'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'appGridFolderIconSize',
[
[_('Adaptive (Default)'), -1],
@@ -859,23 +986,24 @@ function _getAppearanceOptionList() {
[_('64'), 64],
[_('48'), 48],
[_('32'), 32],
- ]
+ ],
+ 'appDisplayModule'
)
);
- const folderIconGridCombo = itemFactory.newComboBox();
+ const folderIconGridCombo = itemFactory.newDropDown();
optionList.push(
itemFactory.getRowWidget(
_('Max App Folder Icon Grid Size'),
_('Sets a grid size (number of icons) in the folder preview. 3x3 options automatically switches between 2x2 and 3x3 grid depending on the number of icons in the folder'),
folderIconGridCombo,
- // itemFactory.newDropDown(),
'appGridFolderIconGrid',
[
[_('2x2 (Default)'), 2],
[_('3x3 for 5+ apps'), 3],
[_('3x3 for 9+ apps'), 4],
- ]
+ ],
+ 'appDisplayModule'
)
);
@@ -891,7 +1019,9 @@ function _getAppearanceOptionList() {
_('Columns per Page (0 for adaptive grid)'),
_('Number of columns in the application grid. If set to 0 (the default), the number will be set automatically to fit the available width'),
columnsSpinBtn,
- 'appGridColumns'
+ 'appGridColumns',
+ null,
+ 'appDisplayModule'
));
const rowsAdjustment = new Gtk.Adjustment({
@@ -906,11 +1036,13 @@ function _getAppearanceOptionList() {
_('Rows per Page (0 for adaptive grid)'),
_('Number of rows in the application grid. If set to 0 (the default), the number will be set automatically to fit the available height'),
rowsSpinBtn,
- 'appGridRows'
+ 'appGridRows',
+ null,
+ 'appDisplayModule'
));
const folderColumnsAdjustment = new Gtk.Adjustment({
- upper: 8,
+ upper: 15,
lower: 0,
step_increment: 1,
page_increment: 1,
@@ -921,11 +1053,13 @@ function _getAppearanceOptionList() {
_('Folder Columns per Page (0 for adaptive grid)'),
_('Number of columns in folder grid. If you leave the value at 0, the number of columns will be calculated to fit all the folder icons on one page'),
folderColumnsSpinBtn,
- 'appGridFolderColumns'
+ 'appGridFolderColumns',
+ null,
+ 'appDisplayModule'
));
const folderRowsAdjustment = new Gtk.Adjustment({
- upper: 8,
+ upper: 15,
lower: 0,
step_increment: 1,
page_increment: 1,
@@ -936,7 +1070,9 @@ function _getAppearanceOptionList() {
_('Folder Rows per Page (0 for adaptive grid)'),
_('Number of rows in folder grid. If you leave the value at 0, the number of rows will be calculated to fit all the folder icons on one page'),
folderRowsSpinBtn,
- 'appGridFolderRows'
+ 'appGridFolderRows',
+ null,
+ 'appDisplayModule'
));
const appGridSpacingAdjustment = new Gtk.Adjustment({
@@ -951,9 +1087,11 @@ function _getAppearanceOptionList() {
optionList.push(
itemFactory.getRowWidget(
_('Grid Spacing'),
- _('Adjusts spacing between icons.'),
+ _('Adjusts the spacing between icons in a grid, the real impact is on folders'),
appGridSpacingScale,
- 'appGridSpacing'
+ 'appGridSpacing',
+ null,
+ 'appDisplayModule'
)
);
@@ -967,8 +1105,8 @@ function _getAppearanceOptionList() {
itemFactory.getRowWidget(
_('App Search Icon Size'),
_('Size of results provided by the App Search Provider - smaller size allows to fit more results'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'searchIconSize',
[
[_('128'), 128],
@@ -978,7 +1116,8 @@ function _getAppearanceOptionList() {
[_('64'), 64],
[_('48'), 48],
[_('32'), 32],
- ]
+ ],
+ 'searchModule'
)
);
@@ -999,7 +1138,9 @@ function _getAppearanceOptionList() {
_('Max Search Results Rows'),
_('Sets the maximum number of rows for result lists of all search providers except the window search provider which always lists all results'),
maxSearchResultsSpinButton,
- 'searchMaxResultsRows'
+ 'searchMaxResultsRows',
+ null,
+ 'searchModule'
)
);
@@ -1036,6 +1177,23 @@ function _getAppearanceOptionList() {
)
);
+ const searchBrightnessBgAdjustment = new Gtk.Adjustment({
+ upper: 100,
+ lower: 0,
+ step_increment: 1,
+ page_increment: 10,
+ });
+
+ const searchBgBrightnessScale = itemFactory.newScale(searchBrightnessBgAdjustment);
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Brightness for Search View'),
+ _('Allows you to set a lower background brightness for search view mode where text visibility is more important'),
+ searchBgBrightnessScale,
+ 'searchBgBrightness'
+ )
+ );
+
const blurBgAdjustment = new Gtk.Adjustment({
upper: 100,
lower: 0,
@@ -1079,11 +1237,36 @@ function _getAppearanceOptionList() {
)
);
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Window Thumbnails (PIP)')
+ )
+ );
+
+ const winTmbAdjustment = new Gtk.Adjustment({
+ upper: 50,
+ lower: 5,
+ step_increment: 1,
+ page_increment: 1,
+ });
+
+ const winTmbScale = itemFactory.newScale(winTmbAdjustment);
+ winTmbScale.add_mark(15, Gtk.PositionType.TOP, null);
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Default Window Thumbnail Scale (% of screen height)'),
+ _('Default scale of window thumbnail (like Picture In Picture) that you can create using the app icon menu or window preview action'),
+ winTmbScale,
+ 'windowThumbnailScale'
+ )
+ );
+
return optionList;
}
// ----------------------------------------------------------------
-function _getBehaviorOptionList() {
+function _getBehaviorOptionList(itemFactory) {
const optionList = [];
optionList.push(
@@ -1096,8 +1279,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Overview Mode'),
_('The Expose Windows on Hover mode does not expose the workspace preview windows until the mouse pointer enters any window\nThe Static Workspace mode keeps the workspace static when you activate the overview, it only shows Dash, workspace thumbnails and search entry over the workspace and only clicking on an active workspace thumbnail activates the default overview'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'overviewMode',
[
[_('Default'), 0],
@@ -1111,8 +1294,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Startup State'),
_('Allows to change the state in which GNOME Shell starts a session'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'startupState',
[
[_('Overview (Default)'), 0],
@@ -1124,23 +1307,61 @@ function _getBehaviorOptionList() {
optionList.push(
itemFactory.getRowWidget(
+ _('Escape Key Behavior'),
+ _('Allows you to close the overview with a single press of the Escape key, even from the application grid or from search, if the search entry field does not have focus'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'overviewEscBehavior',
+ [
+ [_('Default'), 0],
+ [_('Close Overview'), 1],
+ ],
+ 'searchControllerModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
_('Overlay Key (Super/Windows)')
)
);
optionList.push(
itemFactory.getRowWidget(
+ _('Single-Press Action'),
+ _('Disable or change behavior when you press and release the Super key. The "Search Windows" options requires the WindowSearchProvider module to be activated'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'overlayKeyPrimary',
+ [
+ [_('Disable'), 0],
+ [_('Follow Global Overview Mode'), 1],
+ [_('Overview (Default)'), 2],
+ [_('Applications'), 3],
+ [_('Overview - Static WS Preview'), 4],
+ [_('Overview - Static Workspace'), 5],
+ [_('Search Windows'), 6],
+ // [_('Search Recent Files'), 7],
+ ],
+ 'overlayKeyModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
_('Double-Press Action'),
- _('Disable or change behavior when you double-press the Super key. The "Search" options require the respective search provider to be activated'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ _('Disable or change behavior when you double-press the Super key. The "Search Windows" option requires the WindowSearchProvider module to be activated. The "Static WS Overview - Expose Windows" option allows you to switch to default Activities Overview window picker view if you set static workspace (preview) for the single press/release Super key action'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'overlayKeySecondary',
[
[_('Disable'), 0],
[_('Applications (Default)'), 1],
[_('Search Windows'), 2],
- [_('Search Recent Files'), 3],
- ]
+ [_('Overview - Window Picker'), 3],
+ // [_('Search Recent Files'), 4],
+ ],
+ 'overlayKeyModule'
)
);
@@ -1154,24 +1375,28 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Hot Corner Action'),
_('Disable or change behavior of the hot corner. Holding down the Ctrl key while hitting the hot corner switches between Overview/Applications actions'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'hotCornerAction',
[
[_('Disable'), 0],
- [_('Overview'), 1],
- [_('Applications'), 2],
- [_('Search Windows'), 3],
- ]
+ [_('Follow Global Overview Mode'), 1],
+ [_('Overview - Window Picker'), 2],
+ [_('Applications'), 3],
+ [_('Overview - Static WS Preview'), 4],
+ [_('Overview - Static Workspace'), 5],
+ [_('Search Windows'), 6],
+ ],
+ 'layoutModule'
)
);
optionList.push(
itemFactory.getRowWidget(
_('Hot Corner Position'),
- _('Choose which corner of your monitors will be active. If you choose "Follow Dash" option, the corner will be placed near the left or top edge of the Dash. The last option extends the hot corner barrier to cover the entire ege of the monitor where Dash is located'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ _('Choose which corner of your monitors will be active. If you choose "Follow Dash" option, the corner will be placed near the left or top edge of the Dash. The last option extends the hot corner trigger to cover the entire ege of the monitor where Dash is located'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'hotCornerPosition',
[
[_('Default'), 0],
@@ -1181,7 +1406,8 @@ function _getBehaviorOptionList() {
[_('Bottom Right'), 4],
[_('Follow Dash'), 5],
[_('Follow Dash - Hot Edge'), 6],
- ]
+ ],
+ 'layoutModule'
)
);
@@ -1190,8 +1416,9 @@ function _getBehaviorOptionList() {
_('Enable Hot Corner in Full-Screen Mode'),
_('If you often work with full-screen applications and want the hot corner to be usable'),
itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'hotCornerFullscreen'
+ 'hotCornerFullscreen',
+ null,
+ 'layoutModule'
)
);
@@ -1200,8 +1427,9 @@ function _getBehaviorOptionList() {
_('Show Ripples Animation'),
_('The ripple animation is played when the hot corner is activated. The ripple size has been reduced to be less distracting'),
itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'hotCornerRipples'
+ 'hotCornerRipples',
+ null,
+ 'layoutModule'
)
);
@@ -1213,16 +1441,29 @@ function _getBehaviorOptionList() {
optionList.push(
itemFactory.getRowWidget(
+ _('Isolate Workspaces'),
+ _('Dash will only show apps and windows from the current workspace'),
+ itemFactory.newSwitch(),
+ 'dashIsolateWorkspaces',
+ null,
+ 'dashModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
_('App Icon - Click Behavior'),
- _('if the app you clicked on has more than one window and the recently used window is not on the current workspace, the overview can switch to the workspace with the recent window'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ _('Choose your preferred behavior when clicking on an app icon. The "Prefer Current Workspace" option opens a new app window if not present in the current workspace. The "Open New Window" option also switches behavior of the middle click to "Activate" since its default behavior is to open a new window'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'dashShowWindowsBeforeActivation',
[
[_('Activate App Immediately'), 0],
[_('First Switch to Workspace'), 1],
[_('Open New Window (if supported)'), 2],
- ]
+ [_('Prefer Current Workspace'), 3],
+ ],
+ 'dashModule'
)
);
@@ -1230,14 +1471,15 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('App Icon - Scroll Action'),
_('Choose the behavior when scrolling over an app icon. The window cycler works with a list of windows sorted by the "Most Recently Used" and grouped by workspaces. Scrolling up cycles through previously used windows on the same workspace and then switches to another workspace, if any'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'dashIconScroll',
[
[_('Default'), 0],
[_('Cycle App Windows - Highlight Selected'), 1],
[_('Cycle App Windows - Highlight App'), 2],
- ]
+ ],
+ 'dashModule'
)
);
@@ -1245,14 +1487,15 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Search Windows Icon - Scroll Action'),
_('Choose the behavior when scrolling over the Search Windows icon. The window cycler works with a list of windows sorted by "Most Recently Used" of the current workspace or all workspaces. Scrolling up cycles through previously used windows on the same workspace, or all windows regardless workspace. This option is mainly useful for the static workspace overview mode.'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'searchWindowsIconScroll',
[
[_('Default'), 0],
[_('Cycle All Windows'), 1],
[_('Cycle Windows On Current WS'), 2],
- ]
+ ],
+ 'dashModule'
)
);
@@ -1266,8 +1509,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Close Workspace Button'),
_('The Close Workspace button appears on the workspace thumbnail when you hover over it and allows you to close all windows on the workspace. You can choose a "safety lock" to prevent accidental use'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'closeWsButtonMode',
[
[_('Disable'), 0],
@@ -1286,23 +1529,64 @@ function _getBehaviorOptionList() {
optionList.push(
itemFactory.getRowWidget(
- _('Always Activate Selected'),
- _('If enabled, the currently selected window will be activated when leaving the Overview even without clicking. Usage example - press Super to open the Overview, place mouse pointer over a window, press Super again to activate the window'),
- itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'alwaysActivateSelectedWindow'
+ _('Secondary Button Click Action'),
+ _('Allows you to add a secondary mouse click action to the window preview'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'winPreviewSecBtnAction',
+ [
+ [_('Activate Window (Default)'), 0],
+ [_('Close Window'), 1],
+ [_('Search For Same App Windows'), 2],
+ [_('Create Window Thumbnail - PIP'), 3],
+ ],
+ 'windowPreviewModule'
)
);
- /* optionList.push(
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Middle Button Click Action'),
+ _('Allows you to add a middle mouse click action to the window preview'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'winPreviewMidBtnAction',
+ [
+ [_('Activate Window (Default)'), 0],
+ [_('Close Window'), 1],
+ [_('Search For Same App Windows'), 2],
+ [_('Create Window Thumbnail - PIP'), 3],
+ ],
+ 'windowPreviewModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('App Icon Click Action'),
+ _('Select the action to take when the application icon on the window preview is clicked'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'windowIconClickAction',
+ [
+ [_('Activate Window (Default)'), 0],
+ [_('Search For Same App Windows'), 1],
+ [_('Create Window Thumbnail - PIP'), 2],
+ ],
+ 'windowPreviewModule'
+ )
+ );
+
+ optionList.push(
itemFactory.getRowWidget(
- _('App Icon Activates Window Search'),
- _('If enabled, clicking a window preview icon will activate a search view with the application name as the search term, so you can list all app windows from all workspaces and filter them by typing.'),
+ _('Always Activate Selected'),
+ _('If enabled, the currently selected window will be activated when leaving the Overview even without clicking. Usage example - press Super to open the Overview, place mouse pointer over a window, press Super again to activate the window'),
itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'windowIconClickSearch'
+ 'alwaysActivateSelectedWindow',
+ null,
+ 'windowPreviewModule'
)
- );*/
+ );
optionList.push(
itemFactory.getRowWidget(
@@ -1312,16 +1596,34 @@ function _getBehaviorOptionList() {
optionList.push(
itemFactory.getRowWidget(
- _('Apps Order'),
- _('Choose sorting method for the app grid. Note that sorting by alphabet and usage ignores folders'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ _('App Grid Order'),
+ _('Choose sorting method for the app grid. Note that sorting by usage ignores folders'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'appGridOrder',
[
[_('Custom (Default)'), 0],
+ [_('Alphabet - Folders First'), 1],
+ [_('Alphabet - Folders Last'), 2],
+ [_('Usage - No Folders'), 3],
+ ],
+ 'appDisplayModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('App Folder Order'),
+ _('Choose sorting method for app folders'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'appFolderOrder',
+ [
+ [_('Custom (Default)'), 0],
[_('Alphabet'), 1],
[_('Usage'), 2],
- ]
+ ],
+ 'appDisplayModule'
)
);
@@ -1329,8 +1631,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('App Grid Content'),
_('The default Shell removes favorite apps, this option allows to duplicate them in the grid or remove also running applications. Option "Favorites and Running First" only works with the Alphabet and Usage sorting'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'appGridContent',
[
[_('Include All'), 0],
@@ -1338,7 +1640,8 @@ function _getBehaviorOptionList() {
[_('Exclude Favorites (Default)'), 2],
[_('Exclude Running'), 3],
[_('Exclude Favorites and Running'), 4],
- ]
+ ],
+ 'appDisplayModule'
)
);
@@ -1347,8 +1650,9 @@ function _getBehaviorOptionList() {
_('Active Icons in Folder Preview'),
_('If enabled, icons in the folder review behaves like normal icons, you can activate or even drag them directly, without having to open the folder first'),
itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'appGridActivePreview'
+ 'appGridActivePreview',
+ null,
+ 'appDisplayModule'
)
);
@@ -1357,8 +1661,9 @@ function _getBehaviorOptionList() {
_('Center Open Folders'),
_('App folder may open in the center of the screen or above the source folder icon'),
itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'appGridFolderCenter'
+ 'appGridFolderCenter',
+ null,
+ 'appDisplayModule'
)
);
@@ -1367,8 +1672,9 @@ function _getBehaviorOptionList() {
_('Allow Incomplete Pages'),
_('If disabled, icons from the next page (if any) are automatically moved to fill any empty slot left after an icon was (re)moved (to a folder for example)'),
itemFactory.newSwitch(),
- // itemFactory.newDropDown(),
- 'appGridIncompletePages'
+ 'appGridIncompletePages',
+ null,
+ 'appDisplayModule'
)
);
@@ -1376,14 +1682,15 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('App Labels Behavior'),
_('Choose how and when to display app names'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'appGridNamesMode',
[
[_('Ellipsized - Expand Selected (Default)'), 0],
[_('Always Expanded'), 1],
[_('Hidden - Show Selected Only'), 2],
- ]
+ ],
+ 'appDisplayModule'
)
);
@@ -1391,7 +1698,7 @@ function _getBehaviorOptionList() {
_('Reset App Grid Layout'),
_('Removes all stored app grid positions, after reset icons will be sorted alphabetically, except folder contents'),
itemFactory.newResetButton(() => {
- const settings = ExtensionUtils.getSettings('org.gnome.shell');
+ const settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
settings.set_value('app-picker-layout', new GLib.Variant('aa{sv}', []));
})
));
@@ -1400,7 +1707,7 @@ function _getBehaviorOptionList() {
_('Remove App Grid Folders'),
_('Removes all folders, folder apps will move to the root grid'),
itemFactory.newResetButton(() => {
- const settings = ExtensionUtils.getSettings('org.gnome.desktop.app-folders');
+ const settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders' });
settings.set_strv('folder-children', []);
})
));
@@ -1418,21 +1725,29 @@ function _getBehaviorOptionList() {
)
);*/
- optionList.push(
+ /* optionList.push(
itemFactory.getRowWidget(
_('Enable Window Search Provider'),
_('Activates the window search provider that adds open windows to the search results. You can search app names and window titles. You can also use "wq//" prefix (also by pressing the Space hotkey in the overview, or clicking dash icon) to suppress results from other search providers'),
itemFactory.newSwitch(),
'searchWindowsEnable'
)
- );
+ );*/
optionList.push(
itemFactory.getRowWidget(
- _('Enable Recent Files Search Provider'),
- _('Activates the recent files search provider that can be triggered by a dash icon, Ctrl + Space hotkey or by typing "fq//" prefix in the search entry field. This option needs File History option enabled in the GNOME Privacy settings'),
- itemFactory.newSwitch(),
- 'searchRecentFilesEnable'
+ _('Window Search Provider - Sorting'),
+ _('Choose the window sorting method'),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
+ 'searchWindowsOrder',
+ [
+ [_('Most Recently Used (MRU)'), 0],
+ [_('MRU - Current Workspace First'), 1],
+ [_('MRU - By Workspaces'), 2],
+ [_('Stable Sequence - By Workspaces'), 3],
+ ],
+ 'windowSearchProviderModule'
)
);
@@ -1489,8 +1804,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('App Grid Animation'),
_('When entering the App Grid view, the app grid animates from the edge of the screen. You can choose the direction, keep the Default (direction will be selected automatically) or disable the animation if you don\'t like it'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'appGridAnimation',
[
[_('Default'), 4],
@@ -1507,8 +1822,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Search View Animation'),
_('When search is activated the search view with search results can animate from the edge of the screen. You can choose the direction, keep the Default (currently Bottom to Top) or disable the animation if you don\'t like it.'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'searchViewAnimation',
[
[_('Default'), 4],
@@ -1526,8 +1841,8 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Workspace Preview Animation'),
_('When entering / leaving the App Grid / Search view, the workspace preview can animate to/from workspace thumbnail.'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'workspaceAnimation',
[
[_('Disable'), 0],
@@ -1545,15 +1860,34 @@ function _getBehaviorOptionList() {
optionList.push(
itemFactory.getRowWidget(
+ _('Wraparound'),
+ _('Continue from the last workspace to the first and vice versa'),
+ itemFactory.newSwitch(),
+ 'wsSwitcherWraparound'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Ignore Last (empty) Workspace'),
+ _('In Dynamic workspaces mode, there is always one empty workspace at the end. Switcher can ignore this last workspace'),
+ itemFactory.newSwitch(),
+ 'wsSwitcherIgnoreLast'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
_('Workspace Switcher Animation'),
_('Allows you to disable movement of the desktop background during workspace switcher animation outside of the overview. The Static Background mode also keeps Conky and desktop icons on their place during switching.'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'workspaceSwitcherAnimation',
[
[_('Default'), 0],
[_('Static Background'), 1],
- ]
+ ],
+ 'workspaceAnimationModule'
)
);
@@ -1561,18 +1895,18 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Workspace Switcher Popup Mode'),
_('This popup shows up when you switch workspace using a keyboard shortcut or gesture outside of the overview. You can to disable the popup at all, or show it on the current monitor (the one with mouse pointer) instead of the primary.'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'wsSwPopupMode',
[
[_('Disable'), 0],
[_('Show on Primary Monitor (Default)'), 1],
[_('Show on Current Monitor'), 2],
- ]
+ ],
+ 'workspaceSwitcherPopupModule'
)
);
-
optionList.push(
itemFactory.getRowWidget(
_('Notifications')
@@ -1583,14 +1917,15 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Window Attention Handler'),
_('When a window requires attention (often a new window), GNOME Shell shows you a notification about it. You can disable popups of these messages (notification will be pushed into the message tray silently) or focus the source window immediately instead'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'windowAttentionMode',
[
[_('Show Notifications (Default)'), 0],
[_('Disable Notification Popups'), 1],
[_('Immediately Focus Window'), 2],
- ]
+ ],
+ 'windowAttentionHandlerModule'
)
);
@@ -1598,96 +1933,63 @@ function _getBehaviorOptionList() {
itemFactory.getRowWidget(
_('Favorites'),
_('Disable pin/unpin app notifications'),
- itemFactory.newComboBox(),
- // itemFactory.newDropDown(),
+ // itemFactory.newComboBox(),
+ itemFactory.newDropDown(),
'favoritesNotify',
[
[_('Show Notifications (Default)'), 1],
[_('Disable Notifications'), 0],
- ]
- )
- );
-
- return optionList;
-}
-
-function _getProfilesOptionList() {
- const optionList = [];
- // options item format:
- // [text, caption, widget, settings-variable, options for combo]
-
- optionList.push(
- itemFactory.getRowWidget(
- _('Custom Profiles'),
- _('Sets of settings that can help you with the initial customization')
+ ],
+ 'appFavoritesModule'
)
);
- optionList.push(itemFactory.getRowWidget(
- _('Profile 1'),
- null,
- itemFactory.newPresetButton(gOptions, 1)
- ));
-
- optionList.push(itemFactory.getRowWidget(
- _('Profile 2'),
- null,
- itemFactory.newPresetButton(gOptions, 2)
- ));
-
- optionList.push(itemFactory.getRowWidget(
- _('Profile 3'),
- null,
- itemFactory.newPresetButton(gOptions, 3)
- ));
-
- optionList.push(itemFactory.getRowWidget(
- _('Profile 4'),
- null,
- itemFactory.newPresetButton(gOptions, 4)
- ));
-
return optionList;
}
-function _getMiscOptionList() {
+function _getModulesOptionList(itemFactory) {
const optionList = [];
// options item format:
- // [text, caption, widget, settings-variable, options for combo]
-
+ // (text, caption, widget, settings-variable, [options for combo], sensitivity-depends-on-bool-variable)
optionList.push(
itemFactory.getRowWidget(
- _('Keyboard')
+ _('V-Shell Modules (allows you to disable modules that conflict with another extension)')
)
);
optionList.push(
itemFactory.getRowWidget(
- _('Override Page Up/Down Shortcuts'),
- _('This option automatically overrides the (Shift +) Super + Page Up/Down keyboard shortcuts for the current workspace orientation. If you encounter any issues, check the configuration in the dconf editor'),
+ _('WindowSearchProvider'),
+ _('Activates the window search provider that adds open windows to the search results. You can search app names and window titles. You can also use "wq//" prefix (also by pressing the Space hotkey in the overview, or clicking dash icon) to suppress results from other search providers'),
itemFactory.newSwitch(),
- 'enablePageShortcuts'
+ 'windowSearchProviderModule'
)
);
optionList.push(
itemFactory.getRowWidget(
- _('Compatibility')
+ _('RecentFilesSearchProvider'),
+ _('Activates the recent files search provider that can be triggered by a dash icon, Ctrl + Space hotkey or by typing "fq//" prefix in the search entry field. This option needs File History option enabled in the GNOME Privacy settings'),
+ itemFactory.newSwitch(),
+ 'recentFilesSearchProviderModule'
)
);
optionList.push(
itemFactory.getRowWidget(
- _('Fix for Dash to Dock'),
- _('With the default Ubuntu Dock and other Dash To Dock forks, you may experience issues with Activities overview after you change Dock position or change monitors configuration. This option is enabled automatically if a replacement for the Dash is detected'),
+ _('ExtensionsSearchProvider'),
+ _('Activates the extensions search provider that adds extensions to the search results. You can also use "eq//" prefix (also by pressing the Ctrl + Shift + Space hotkey in the overview, or clicking dash icon) to suppress results from other search providers'),
itemFactory.newSwitch(),
- 'fixUbuntuDock'
+ 'extensionsSearchProviderModule'
)
);
optionList.push(
itemFactory.getRowWidget(
- _('V-Shell Modules that can be disabled in case of conflict or misbehavior:')
+ _('AppDisplay / IconGrid'),
+ _('App grid customization and options'),
+ itemFactory.newSwitch(),
+ 'appDisplayModule'
)
);
@@ -1702,15 +2004,6 @@ function _getMiscOptionList() {
optionList.push(
itemFactory.getRowWidget(
- _('AppDisplay / IconGrid'),
- _('App grid customization and options'),
- itemFactory.newSwitch(),
- 'appDisplayModule'
- )
- );
-
- optionList.push(
- itemFactory.getRowWidget(
_('Dash'),
_('Dash customization and options, support for vertical orientation'),
itemFactory.newSwitch(),
@@ -1774,6 +2067,15 @@ function _getMiscOptionList() {
optionList.push(
itemFactory.getRowWidget(
+ _('SearchController'),
+ _('Escape key behavior options in the overview'),
+ itemFactory.newSwitch(),
+ 'searchControllerModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
_('SwipeTracker'),
_('Gestures for vertical workspace orientation'),
itemFactory.newSwitch(),
@@ -1786,7 +2088,7 @@ function _getMiscOptionList() {
_('WindowAttentionHandler'),
_('Window attention handler options'),
itemFactory.newSwitch(),
- 'winAttentionHandlerModule'
+ 'windowAttentionHandlerModule'
)
);
@@ -1810,6 +2112,15 @@ function _getMiscOptionList() {
optionList.push(
itemFactory.getRowWidget(
+ _('WindowThumbnail'),
+ _('Create Window Thumbnail (PIP) option in the app icon menu and window preview actions'),
+ itemFactory.newSwitch(),
+ 'windowThumbnailModule'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
_('Workspace'),
_('Fixes workspace preview allocations for vertical workspaces orientation and window scaling in static overview modes'),
itemFactory.newSwitch(),
@@ -1838,17 +2149,89 @@ function _getMiscOptionList() {
return optionList;
}
-function _getAboutOptionList() {
+function _getMiscOptionList(itemFactory) {
+ const optionList = [];
+ // options item format:
+ // (text, caption, widget, settings-variable, [options for combo], sensitivity-depends-on-bool-variable)
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Keyboard')
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Override Page Up/Down Shortcuts'),
+ _('This option automatically overrides the (Shift +) Super + Page Up/Down keyboard shortcuts for the current workspace orientation. If you encounter any issues, check the configuration in the dconf editor'),
+ itemFactory.newSwitch(),
+ 'enablePageShortcuts'
+ )
+ );
+
+ /* optionList.push(
+ itemFactory.getRowWidget(
+ _('Compatibility')
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Improve compatibility with Dash to Dock'),
+ _('With the default Ubuntu Dock and other Dash To Dock forks, you may experience issues with Activities overview after you change Dock position or re-enable the extension. This option is enabled automatically if a replacement for the Dash is detected. In any case, using Dash to Dock extension with V-Shell is problematic and not recommended.'),
+ itemFactory.newSwitch(),
+ 'fixUbuntuDock'
+ )
+ );*/
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Performance')
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Smooth App Grid Animations'),
+ _('This option allows V-Shell to pre-realize app grid and app folders during session startup in order to avoid stuttering animations when using them for the first time. If enabled, the session startup needs a little bit more time to finish and necessary memory will be allocated at this time'),
+ itemFactory.newSwitch(),
+ 'appGridPerformance'
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Workarounds')
+ )
+ );
+
+ optionList.push(
+ itemFactory.getRowWidget(
+ _('Fix New Window Not In Focus'),
+ _('If you often find that the app window you open from the Activities overview does not get focus, try enabling this option.'),
+ itemFactory.newSwitch(),
+ 'newWindowFocusFix'
+ )
+ );
+
+ return optionList;
+}
+
+function _getAboutOptionList(itemFactory) {
const optionList = [];
optionList.push(itemFactory.getRowWidget(
Me.metadata.name
));
+ const versionName = Me.metadata['version-name'] ?? '';
+ let version = Me.metadata['version'] ?? '';
+ version = versionName && version ? `/${version}` : version;
+ const versionStr = `${versionName}${version}`;
optionList.push(itemFactory.getRowWidget(
_('Version'),
null,
- itemFactory.newLabel(Me.metadata.version.toString())
+ itemFactory.newLabel(versionStr)
));
optionList.push(itemFactory.getRowWidget(
diff --git a/extensions/44/vertical-workspaces/schemas/org.gnome.shell.extensions.vertical-workspaces.gschema.xml b/extensions/44/vertical-workspaces/schemas/org.gnome.shell.extensions.vertical-workspaces.gschema.xml
new file mode 100644
index 0000000..0a2ae51
--- /dev/null
+++ b/extensions/44/vertical-workspaces/schemas/org.gnome.shell.extensions.vertical-workspaces.gschema.xml
@@ -0,0 +1,408 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist gettext-domain="vertical-workspaces">
+ <schema id="org.gnome.shell.extensions.vertical-workspaces" path="/org/gnome/shell/extensions/vertical-workspaces/">
+ <key type="i" name="ws-thumbnails-position">
+ <default>0</default>
+ </key>
+ <key type="b" name="ws-thumbnails-full">
+ <default>false</default>
+ </key>
+ <key type="i" name="secondary-ws-thumbnails-position">
+ <default>2</default>
+ </key>
+ <key type="i" name="ws-max-spacing">
+ <default>350</default>
+ </key>
+ <key type="i" name="ws-preview-scale">
+ <default>95</default>
+ </key>
+ <key type="i" name="secondary-ws-preview-scale">
+ <default>100</default>
+ </key>
+ <key type="b" name="secondary-ws-preview-shift">
+ <default>false</default>
+ </key>
+ <key type="i" name="dash-position">
+ <default>2</default>
+ </key>
+ <key type="i" name="dash-position-adjust">
+ <default>0</default>
+ </key>
+ <key type="i" name="show-app-icon-position">
+ <default>1</default>
+ </key>
+ <key type="i" name="dash-show-windows-icon">
+ <default>1</default>
+ </key>
+ <key type="i" name="dash-show-recent-files-icon">
+ <default>1</default>
+ </key>
+ <key type="i" name="dash-show-extensions-icon">
+ <default>1</default>
+ </key>
+ <key type="i" name="wst-position-adjust">
+ <default>0</default>
+ </key>
+ <key type="i" name="show-wst-labels">
+ <default>3</default>
+ </key>
+ <key type="b" name="show-wst-labels-on-hover">
+ <default>false</default>
+ </key>
+ <key type="i" name="sec-wst-position-adjust">
+ <default>0</default>
+ </key>
+ <key type="i" name="close-ws-button-mode">
+ <default>2</default>
+ </key>
+ <key type="b" name="center-dash-to-ws">
+ <default>false</default>
+ </key>
+ <key type="b" name="show-search-entry">
+ <default>false</default>
+ </key>
+ <key type="b" name="center-search">
+ <default>true</default>
+ </key>
+ <key type="b" name="center-app-grid">
+ <default>false</default>
+ </key>
+ <key type="i" name="ws-thumbnail-scale">
+ <default>13</default>
+ </key>
+ <key type="i" name="ws-thumbnail-scale-appgrid">
+ <default>13</default>
+ </key>
+ <key type="i" name="secondary-ws-thumbnail-scale">
+ <default>13</default>
+ </key>
+ <key type="i" name="dash-max-icon-size">
+ <default>48</default>
+ </key>
+ <key type="i" name="dash-bg-opacity">
+ <default>85</default>
+ </key>
+ <key type="i" name="dash-bg-color">
+ <default>0</default>
+ </key>
+ <key type="i" name="dash-bg-radius">
+ <default>18</default>
+ </key>
+ <key type="b" name="dash-bg-gs3-style">
+ <default>true</default>
+ </key>
+ <key type="i" name="running-dot-style">
+ <default>1</default>
+ </key>
+ <key type="b" name="enable-page-shortcuts">
+ <default>false</default>
+ </key>
+ <key type="b" name="show-ws-switcher-bg">
+ <default>true</default>
+ </key>
+ <key type="b" name="show-ws-preview-bg">
+ <default>false</default>
+ </key>
+ <key type="i" name="ws-preview-bg-radius">
+ <default>30</default>
+ </key>
+ <key type="b" name="show-bg-in-overview">
+ <default>true</default>
+ </key>
+ <key type="i" name="overview-bg-blur-sigma">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-grid-bg-blur-sigma">
+ <default>40</default>
+ </key>
+ <key type="i" name="overview-bg-brightness">
+ <default>60</default>
+ </key>
+ <key type="i" name="search-bg-brightness">
+ <default>30</default>
+ </key>
+ <key type="b" name="smooth-blur-transitions">
+ <default>false</default>
+ </key>
+ <key type="i" name="app-grid-animation">
+ <default>4</default>
+ </key>
+ <key type="i" name="search-view-animation">
+ <default>0</default>
+ </key>
+ <key type="i" name="workspace-animation">
+ <default>1</default>
+ </key>
+ <key type="i" name="workspace-switcher-animation">
+ <default>1</default>
+ </key>
+ <key type="i" name="animation-speed-factor">
+ <default>100</default>
+ </key>
+ <key type="i" name="win-preview-icon-size">
+ <default>1</default>
+ </key>
+ <key type="i" name="win-title-position">
+ <default>0</default>
+ </key>
+ <key type="i" name="startup-state">
+ <default>2</default>
+ </key>
+ <key type="i" name="overview-mode">
+ <default>0</default>
+ </key>
+ <key type="i" name="search-icon-size">
+ <default>96</default>
+ </key>
+ <key type="i" name="search-width-scale">
+ <default>104</default>
+ </key>
+ <key type="i" name="app-grid-icon-size">
+ <default>-1</default>
+ </key>
+ <key type="i" name="app-grid-columns">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-grid-rows">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-grid-order">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-folder-order">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-grid-content">
+ <default>2</default>
+ </key>
+ <key type="i" name="app-grid-folder-icon-size">
+ <default>-1</default>
+ </key>
+ <key type="i" name="app-grid-folder-columns">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-grid-folder-rows">
+ <default>0</default>
+ </key>
+ <key type="i" name="app-grid-spacing">
+ <default>12</default>
+ </key>
+ <key type="b" name="app-grid-incomplete-pages">
+ <default>true</default>
+ </key>
+ <key type="i" name="app-grid-names">
+ <default>1</default>
+ </key>
+ <key type="i" name="app-grid-folder-icon-grid">
+ <default>3</default>
+ </key>
+ <key type="b" name="app-grid-active-preview">
+ <default>false</default>
+ </key>
+ <key type="b" name="app-grid-folder-center">
+ <default>false</default>
+ </key>
+ <key type="i" name="app-grid-page-width-scale">
+ <default>90</default>
+ </key>
+ <key type="i" name="dash-show-windows-before-activation">
+ <default>1</default>
+ </key>
+ <key type="i" name="dash-icon-scroll">
+ <default>1</default>
+ </key>
+ <key type="b" name="dash-isolate-workspaces">
+ <default>false</default>
+ </key>
+ <key type="i" name="search-windows-icon-scroll">
+ <default>1</default>
+ </key>
+ <key type="b" name="search-windows-enable">
+ <default>true</default>
+ </key>
+ <key type="i" name="search-windows-order">
+ <default>1</default>
+ </key>
+ <key type="b" name="search-fuzzy">
+ <default>false</default>
+ </key>
+ <key type="i" name="search-max-results-rows">
+ <default>5</default>
+ </key>
+ <key type="i" name="panel-visibility">
+ <default>0</default>
+ </key>
+ <key type="i" name="panel-position">
+ <default>0</default>
+ </key>
+ <key type="i" name="window-attention-mode">
+ <default>0</default>
+ </key>
+ <key type="i" name="ws-sw-popup-h-position">
+ <default>50</default>
+ </key>
+ <key type="i" name="ws-sw-popup-v-position">
+ <default>95</default>
+ </key>
+ <key type="i" name="ws-sw-popup-mode">
+ <default>1</default>
+ </key>
+ <key type="b" name="ws-switcher-wraparound">
+ <default>false</default>
+ </key>
+ <key type="b" name="ws-switcher-ignore-last">
+ <default>false</default>
+ </key>
+ <key type="i" name="favorites-notify">
+ <default>1</default>
+ </key>
+ <key type="i" name="notification-position">
+ <default>2</default>
+ </key>
+ <key type="i" name="osd-position">
+ <default>6</default>
+ </key>
+ <key type="i" name="hot-corner-action">
+ <default>1</default>
+ </key>
+ <key type="i" name="hot-corner-position">
+ <default>6</default>
+ </key>
+ <key type="b" name="hot-corner-fullscreen">
+ <default>true</default>
+ </key>
+ <key type="b" name="hot-corner-ripples">
+ <default>true</default>
+ </key>
+ <key type="b" name="always-activate-selected-window">
+ <default>false</default>
+ </key>
+ <key type="i" name="win-preview-sec-mouse-btn-action">
+ <default>2</default>
+ </key>
+ <key type="i" name="win-preview-mid-mouse-btn-action">
+ <default>0</default>
+ </key>
+ <key type="b" name="win-preview-show-close-button">
+ <default>true</default>
+ </key>
+ <key type="i" name="window-icon-click-action">
+ <default>1</default>
+ </key>
+ <key type="i" name="overlay-key-primary">
+ <default>1</default>
+ </key>
+ <key type="i" name="overlay-key-secondary">
+ <default>1</default>
+ </key>
+ <key type="i" name="overview-esc-behavior">
+ <default>0</default>
+ </key>
+ <key type="b" name="new-window-focus-fix">
+ <default>false</default>
+ </key>
+ <key type="b" name="app-grid-performance">
+ <default>true</default>
+ </key>
+ <key type="i" name="window-thumbnail-scale">
+ <default>15</default>
+ </key>
+
+ <key type="b" name="workspace-switcher-popup-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="workspace-animation-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="workspace-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="window-manager-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="window-preview-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="win-attention-handler-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="window-thumbnail-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="swipe-tracker-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="search-controller-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="search-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="panel-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="overlay-key-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="osd-window-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="message-tray-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="layout-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="dash-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="app-display-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="app-favorites-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="window-search-provider-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="recent-files-search-provider-module">
+ <default>true</default>
+ </key>
+ <key type="b" name="extensions-search-provider-module">
+ <default>true</default>
+ </key>
+
+ <key type="b" name="aaa-loading-profile">
+ <default>false</default>
+ </key>
+
+ <key type="s" name="profile-name-1">
+ <default>""</default>
+ </key>
+ <key type="a{ss}" name="profile-data-1">
+ <default>{'workspaceThumbnailsPosition': '1', 'wsMaxSpacing': '350', 'wsPreviewScale': '95', 'secWsPreviewScale': '100', 'secWsPreviewShift': 'false', 'wsThumbnailsFull': 'false', 'secWsThumbnailsPosition': '2', 'dashPosition': '3', 'dashPositionAdjust': '0', 'wsTmbPositionAdjust': '-80', 'showWsTmbLabels': '3', 'showWsTmbLabelsOnHover': 'false', 'closeWsButtonMode': '2', 'secWsTmbPositionAdjust': '-80', 'dashMaxIconSize': '64', 'dashShowWindowsIcon': '2', 'dashShowRecentFilesIcon': '2', 'dashShowExtensionsIcon': '2', 'centerDashToWs': 'false', 'showAppsIconPosition': '1', 'wsThumbnailScale': '13', 'wsThumbnailScaleAppGrid': '13', 'secWsThumbnailScale': '13', 'showSearchEntry': 'true', 'centerSearch': 'true', 'centerAppGrid': 'true', 'dashBgOpacity': '80', 'dashBgColor': '0', 'dashBgRadius': '0', 'dashBgGS3Style': 'true', 'runningDotStyle': '1', 'enablePageShortcuts': 'false', 'showWsSwitcherBg': 'true', 'showWsPreviewBg': 'false', 'wsPreviewBgRadius': '30', 'showBgInOverview': 'true', 'overviewBgBrightness': '30', 'searchBgBrightness': '30', 'overviewBgBlurSigma': '0', 'appGridBgBlurSigma': '40', 'smoothBlurTransitions': 'false', 'appGridAnimation': '4', 'searchViewAnimation': '0', 'workspaceAnimation': '1', 'animationSpeedFactor': '100', 'winPreviewIconSize': '1', 'winTitlePosition': '0', 'startupState': '0', 'overviewMode': '0', 'workspaceSwitcherAnimation': '1', 'searchIconSize': '96', 'searchViewScale': '104', 'appGridIconSize': '-1', 'appGridColumns': '0', 'appGridRows': '0', 'appGridFolderIconSize': '-1', 'appGridFolderColumns': '0', 'appGridFolderRows': '0', 'appGridFolderIconGrid': '2', 'appGridContent': '2', 'appGridIncompletePages': 'false', 'appGridOrder': '0', 'appFolderOrder': '0', 'appGridNamesMode': '1', 'appGridActivePreview': 'false', 'appGridFolderCenter': 'false', 'appGridPageWidthScale': '100', 'appGridSpacing': '12', 'searchWindowsOrder': '1', 'searchFuzzy': 'false', 'searchMaxResultsRows': '5', 'dashShowWindowsBeforeActivation': '1', 'dashIconScroll': '1', 'dashIsolateWorkspaces': 'false', 'searchWindowsIconScroll': '1', 'panelVisibility': '0', 'panelPosition': '0', 'windowAttentionMode': '0', 'wsSwPopupHPosition': '50', 'wsSwPopupVPosition': '95', 'wsSwPopupMode': '1', 'wsSwitcherWraparound': 'false', 'wsSwitcherIgnoreLast': 'false', 'favoritesNotify': '1', 'notificationPosition': '1', 'osdPosition': '6', 'hotCornerAction': '1', 'hotCornerPosition': '0', 'hotCornerFullscreen': 'true', 'hotCornerRipples': 'true', 'alwaysActivateSelectedWindow': 'false', 'winPreviewSecBtnAction': '3', 'winPreviewMidBtnAction': '1', 'winPreviewShowCloseButton': 'true', 'windowIconClickAction': '1', 'overlayKeyPrimary': '1', 'overlayKeySecondary': '1', 'overviewEscBehavior': '0', 'newWindowFocusFix': 'false', 'appGridPerformance': 'true', 'windowThumbnailScale': '20', 'workspaceSwitcherPopupModule': 'true', 'workspaceAnimationModule': 'true', 'workspaceModule': 'true', 'windowManagerModule': 'true', 'windowPreviewModule': 'true', 'windowAttentionHandlerModule': 'true', 'windowThumbnailModule': 'true', 'swipeTrackerModule': 'true', 'searchControllerModule': 'true', 'searchModule': 'true', 'panelModule': 'true', 'overlayKeyModule': 'true', 'osdWindowModule': 'true', 'messageTrayModule': 'true', 'layoutModule': 'true', 'dashModule': 'true', 'appFavoritesModule': 'true', 'appDisplayModule': 'true', 'windowSearchProviderModule': 'true', 'extensionsSearchProviderModule': 'true'}</default>
+ </key>
+
+ <key type="s" name="profile-name-2">
+ <default>""</default>
+ </key>
+ <key type="a{ss}" name="profile-data-2">
+ <default>{'workspaceThumbnailsPosition': '5', 'wsMaxSpacing': '80', 'wsPreviewScale': '100', 'secWsPreviewScale': '100', 'secWsPreviewShift': 'false', 'wsThumbnailsFull': 'false', 'secWsThumbnailsPosition': '2', 'dashPosition': '2', 'dashPositionAdjust': '0', 'wsTmbPositionAdjust': '0', 'showWsTmbLabels': '0', 'showWsTmbLabelsOnHover': 'false', 'closeWsButtonMode': '2', 'secWsTmbPositionAdjust': '0', 'dashMaxIconSize': '64', 'dashShowWindowsIcon': '2', 'dashShowRecentFilesIcon': '2', 'dashShowExtensionsIcon': '2', 'centerDashToWs': 'false', 'showAppsIconPosition': '1', 'wsThumbnailScale': '5', 'wsThumbnailScaleAppGrid': '15', 'secWsThumbnailScale': '5', 'showSearchEntry': 'true', 'centerSearch': 'true', 'centerAppGrid': 'true', 'dashBgOpacity': '20', 'dashBgColor': '1', 'dashBgRadius': '0', 'dashBgGS3Style': 'false', 'runningDotStyle': '1', 'enablePageShortcuts': 'true', 'showWsSwitcherBg': 'false', 'showWsPreviewBg': 'true', 'wsPreviewBgRadius': '30', 'showBgInOverview': 'true', 'overviewBgBrightness': '50', 'searchBgBrightness': '30', 'overviewBgBlurSigma': '50', 'appGridBgBlurSigma': '40', 'smoothBlurTransitions': 'false', 'appGridAnimation': '4', 'searchViewAnimation': '4', 'workspaceAnimation': '1', 'animationSpeedFactor': '100', 'winPreviewIconSize': '1', 'winTitlePosition': '0', 'startupState': '0', 'overviewMode': '0', 'workspaceSwitcherAnimation': '0', 'searchIconSize': '96', 'searchViewScale': '104', 'appGridIconSize': '-1', 'appGridColumns': '0', 'appGridRows': '0', 'appGridFolderIconSize': '-1', 'appGridFolderColumns': '0', 'appGridFolderRows': '0', 'appGridFolderIconGrid': '2', 'appGridContent': '2', 'appGridIncompletePages': 'false', 'appGridOrder': '0', 'appFolderOrder': '0', 'appGridNamesMode': '1', 'appGridActivePreview': 'false', 'appGridFolderCenter': 'true', 'appGridPageWidthScale': '90', 'appGridSpacing': '12', 'searchWindowsOrder': '1', 'searchFuzzy': 'false', 'searchMaxResultsRows': '5', 'dashShowWindowsBeforeActivation': '1', 'dashIconScroll': '1', 'dashIsolateWorkspaces': 'false', 'searchWindowsIconScroll': '1', 'panelVisibility': '0', 'panelPosition': '0', 'windowAttentionMode': '0', 'wsSwPopupHPosition': '50', 'wsSwPopupVPosition': '95', 'wsSwPopupMode': '1', 'wsSwitcherWraparound': 'false', 'wsSwitcherIgnoreLast': 'false', 'favoritesNotify': '1', 'notificationPosition': '1', 'osdPosition': '6', 'hotCornerAction': '1', 'hotCornerPosition': '6', 'hotCornerFullscreen': 'true', 'hotCornerRipples': 'false', 'alwaysActivateSelectedWindow': 'false', 'winPreviewSecBtnAction': '2', 'winPreviewMidBtnAction': '1', 'winPreviewShowCloseButton': 'true', 'windowIconClickAction': '1', 'overlayKeyPrimary': '1', 'overlayKeySecondary': '1', 'overviewEscBehavior': '0', 'newWindowFocusFix': 'false', 'appGridPerformance': 'true', 'windowThumbnailScale': '20', 'workspaceSwitcherPopupModule': 'true', 'workspaceAnimationModule': 'true', 'workspaceModule': 'true', 'windowManagerModule': 'true', 'windowPreviewModule': 'true', 'windowAttentionHandlerModule': 'true', 'windowThumbnailModule': 'true', 'swipeTrackerModule': 'true', 'searchControllerModule': 'true', 'searchModule': 'true', 'panelModule': 'true', 'overlayKeyModule': 'true', 'osdWindowModule': 'true', 'messageTrayModule': 'true', 'layoutModule': 'true', 'dashModule': 'true', 'appFavoritesModule': 'true', 'appDisplayModule': 'true', 'windowSearchProviderModule': 'true', 'extensionsSearchProviderModule': 'true'}</default>
+ </key>
+
+ <key type="s" name="profile-name-3">
+ <default>""</default>
+ </key>
+ <key type="a{ss}" name="profile-data-3">
+ <default>{'workspaceThumbnailsPosition': '0', 'wsMaxSpacing': '350', 'wsPreviewScale': '95', 'secWsPreviewScale': '100', 'secWsPreviewShift': 'false', 'wsThumbnailsFull': 'false', 'secWsThumbnailsPosition': '2', 'dashPosition': '0', 'dashPositionAdjust': '-100', 'wsTmbPositionAdjust': '-100', 'showWsTmbLabels': '3', 'showWsTmbLabelsOnHover': 'false', 'closeWsButtonMode': '2', 'secWsTmbPositionAdjust': '0', 'dashMaxIconSize': '48', 'dashShowWindowsIcon': '1', 'dashShowRecentFilesIcon': '1', 'dashShowExtensionsIcon': '1', 'centerDashToWs': 'false', 'showAppsIconPosition': '0', 'wsThumbnailScale': '13', 'wsThumbnailScaleAppGrid': '13', 'secWsThumbnailScale': '13', 'showSearchEntry': 'false', 'centerSearch': 'true', 'centerAppGrid': 'false', 'dashBgOpacity': '20', 'dashBgColor': '1', 'dashBgRadius': '0', 'dashBgGS3Style': 'false', 'runningDotStyle': '1', 'enablePageShortcuts': 'true', 'showWsSwitcherBg': 'false', 'showWsPreviewBg': 'true', 'wsPreviewBgRadius': '30', 'showBgInOverview': 'true', 'overviewBgBrightness': '60', 'searchBgBrightness': '30', 'overviewBgBlurSigma': '30', 'appGridBgBlurSigma': '80', 'smoothBlurTransitions': 'false', 'appGridAnimation': '4', 'searchViewAnimation': '4', 'workspaceAnimation': '1', 'animationSpeedFactor': '100', 'winPreviewIconSize': '1', 'winTitlePosition': '0', 'startupState': '2', 'overviewMode': '1', 'workspaceSwitcherAnimation': '1', 'searchIconSize': '96', 'searchViewScale': '104', 'appGridIconSize': '-1', 'appGridColumns': '0', 'appGridRows': '0', 'appGridFolderIconSize': '-1', 'appGridFolderColumns': '0', 'appGridFolderRows': '0', 'appGridFolderIconGrid': '3', 'appGridContent': '0', 'appGridIncompletePages': 'false', 'appGridOrder': '0', 'appFolderOrder': '0', 'appGridNamesMode': '1', 'appGridActivePreview': 'true', 'appGridFolderCenter': 'false', 'appGridPageWidthScale': '90', 'appGridSpacing': '12', 'searchWindowsOrder': '1', 'searchFuzzy': 'false', 'searchMaxResultsRows': '5', 'dashShowWindowsBeforeActivation': '1', 'dashIconScroll': '1', 'dashIsolateWorkspaces': 'false', 'searchWindowsIconScroll': '1', 'panelVisibility': '0', 'panelPosition': '0', 'windowAttentionMode': '0', 'wsSwPopupHPosition': '50', 'wsSwPopupVPosition': '95', 'wsSwPopupMode': '1', 'wsSwitcherWraparound': 'false', 'wsSwitcherIgnoreLast': 'false', 'favoritesNotify': '0', 'notificationPosition': '2', 'osdPosition': '6', 'hotCornerAction': '1', 'hotCornerPosition': '1', 'hotCornerFullscreen': 'true', 'hotCornerRipples': 'true', 'alwaysActivateSelectedWindow': 'false', 'winPreviewSecBtnAction': '2', 'winPreviewMidBtnAction': '1', 'winPreviewShowCloseButton': 'true', 'windowIconClickAction': '1', 'overlayKeyPrimary': '1', 'overlayKeySecondary': '1', 'overviewEscBehavior': '0', 'newWindowFocusFix': 'false', 'appGridPerformance': 'true', 'windowThumbnailScale': '20', 'workspaceSwitcherPopupModule': 'true', 'workspaceAnimationModule': 'true', 'workspaceModule': 'true', 'windowManagerModule': 'true', 'windowPreviewModule': 'true', 'windowAttentionHandlerModule': 'true', 'windowThumbnailModule': 'true', 'swipeTrackerModule': 'true', 'searchControllerModule': 'true', 'searchModule': 'true', 'panelModule': 'true', 'overlayKeyModule': 'true', 'osdWindowModule': 'true', 'messageTrayModule': 'true', 'layoutModule': 'true', 'dashModule': 'true', 'appFavoritesModule': 'true', 'appDisplayModule': 'true', 'windowSearchProviderModule': 'true', 'extensionsSearchProviderModule': 'true'}</default>
+ </key>
+
+ <key type="s" name="profile-name-4">
+ <default>""</default>
+ </key>
+ <key type="a{ss}" name="profile-data-4">
+ <default>{'workspaceThumbnailsPosition': '6', 'wsMaxSpacing': '65', 'wsPreviewScale': '95', 'secWsPreviewScale': '100', 'secWsPreviewShift': 'false', 'wsThumbnailsFull': 'false', 'secWsThumbnailsPosition': '2', 'dashPosition': '2', 'dashPositionAdjust': '0', 'wsTmbPositionAdjust': '0', 'showWsTmbLabels': '3', 'showWsTmbLabelsOnHover': 'false', 'closeWsButtonMode': '2', 'secWsTmbPositionAdjust': '0', 'dashMaxIconSize': '48', 'dashShowWindowsIcon': '1', 'dashShowRecentFilesIcon': '1', 'dashShowExtensionsIcon': '1', 'centerDashToWs': 'false', 'showAppsIconPosition': '1', 'wsThumbnailScale': '10', 'wsThumbnailScaleAppGrid': '10', 'secWsThumbnailScale': '10', 'showSearchEntry': 'false', 'centerSearch': 'true', 'centerAppGrid': 'false', 'dashBgOpacity': '100', 'dashBgColor': '0', 'dashBgRadius': '0', 'dashBgGS3Style': 'false', 'runningDotStyle': '1', 'enablePageShortcuts': 'true', 'showWsSwitcherBg': 'true', 'showWsPreviewBg': 'true', 'wsPreviewBgRadius': '30', 'showBgInOverview': 'true', 'overviewBgBrightness': '60', 'searchBgBrightness': '30', 'overviewBgBlurSigma': '80', 'appGridBgBlurSigma': '80', 'smoothBlurTransitions': 'false', 'appGridAnimation': '4', 'searchViewAnimation': '4', 'workspaceAnimation': '1', 'animationSpeedFactor': '100', 'winPreviewIconSize': '1', 'winTitlePosition': '0', 'startupState': '2', 'overviewMode': '2', 'workspaceSwitcherAnimation': '1', 'searchIconSize': '96', 'searchViewScale': '104', 'appGridIconSize': '-1', 'appGridColumns': '0', 'appGridRows': '0', 'appGridFolderIconSize': '-1', 'appGridFolderColumns': '0', 'appGridFolderRows': '0', 'appGridFolderIconGrid': '3', 'appGridContent': '0', 'appGridIncompletePages': 'false', 'appGridOrder': '0', 'appFolderOrder': '0', 'appGridNamesMode': '1', 'appGridActivePreview': 'true', 'appGridFolderCenter': 'false', 'appGridPageWidthScale': '90', 'appGridSpacing': '5', 'searchWindowsOrder': '1', 'searchFuzzy': 'false', 'searchMaxResultsRows': '5', 'dashShowWindowsBeforeActivation': '1', 'dashIconScroll': '1', 'dashIsolateWorkspaces': 'false', 'searchWindowsIconScroll': '1', 'panelVisibility': '0', 'panelPosition': '0', 'windowAttentionMode': '0', 'wsSwPopupHPosition': '50', 'wsSwPopupVPosition': '95', 'wsSwPopupMode': '1', 'wsSwitcherWraparound': 'false', 'wsSwitcherIgnoreLast': 'false', 'favoritesNotify': '0', 'notificationPosition': '1', 'osdPosition': '6', 'hotCornerAction': '1', 'hotCornerPosition': '6', 'hotCornerFullscreen': 'true', 'hotCornerRipples': 'false', 'alwaysActivateSelectedWindow': 'false', 'winPreviewSecBtnAction': '2', 'winPreviewMidBtnAction': '1', 'winPreviewShowCloseButton': 'true', 'windowIconClickAction': '1', 'overlayKeyPrimary': '1', 'overlayKeySecondary': '1', 'overviewEscBehavior': '0', 'newWindowFocusFix': 'false', 'appGridPerformance': 'true', 'windowThumbnailScale': '20', 'workspaceSwitcherPopupModule': 'true', 'workspaceAnimationModule': 'true', 'workspaceModule': 'true', 'windowManagerModule': 'true', 'windowPreviewModule': 'true', 'windowAttentionHandlerModule': 'true', 'windowThumbnailModule': 'true', 'swipeTrackerModule': 'true', 'searchControllerModule': 'true', 'searchModule': 'true', 'panelModule': 'true', 'overlayKeyModule': 'true', 'osdWindowModule': 'true', 'messageTrayModule': 'true', 'layoutModule': 'true', 'dashModule': 'true', 'appFavoritesModule': 'true', 'appDisplayModule': 'true', 'windowSearchProviderModule': 'true', 'extensionsSearchProviderModule': 'true'}</default>
+ </key>
+
+ </schema>
+</schemalist>
diff --git a/extensions/vertical-workspaces/screenshots/screenshot.jpg b/extensions/44/vertical-workspaces/screenshots/screenshot.jpg
index b10585e..b10585e 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot.jpg
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot.jpg
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot0.jpg b/extensions/44/vertical-workspaces/screenshots/screenshot0.jpg
index 866298b..866298b 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot0.jpg
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot0.jpg
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot0.png b/extensions/44/vertical-workspaces/screenshots/screenshot0.png
index b6af4b9..b6af4b9 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot0.png
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot0.png
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot1.png b/extensions/44/vertical-workspaces/screenshots/screenshot1.png
index a23c76f..a23c76f 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot1.png
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot1.png
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot2.png b/extensions/44/vertical-workspaces/screenshots/screenshot2.png
index 58b2887..58b2887 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot2.png
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot2.png
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot3.png b/extensions/44/vertical-workspaces/screenshots/screenshot3.png
index 3d8f48a..3d8f48a 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot3.png
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot3.png
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot4.png b/extensions/44/vertical-workspaces/screenshots/screenshot4.png
index e4e5f4f..e4e5f4f 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot4.png
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot4.png
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/screenshot5.png b/extensions/44/vertical-workspaces/screenshots/screenshot5.png
index e6ecb55..e6ecb55 100644
--- a/extensions/vertical-workspaces/screenshots/screenshot5.png
+++ b/extensions/44/vertical-workspaces/screenshots/screenshot5.png
Binary files differ
diff --git a/extensions/vertical-workspaces/screenshots/vertical-workspaces.gif b/extensions/44/vertical-workspaces/screenshots/vertical-workspaces.gif
index c97c653..c97c653 100644
--- a/extensions/vertical-workspaces/screenshots/vertical-workspaces.gif
+++ b/extensions/44/vertical-workspaces/screenshots/vertical-workspaces.gif
Binary files differ
diff --git a/extensions/44/vertical-workspaces/stylesheet.css b/extensions/44/vertical-workspaces/stylesheet.css
new file mode 100644
index 0000000..2febbb7
--- /dev/null
+++ b/extensions/44/vertical-workspaces/stylesheet.css
@@ -0,0 +1,307 @@
+/*
+* V-Shell (Vertical Workspaces)
+* stylesheet.css
+*/
+
+/* General dash */
+#dash.vertical {
+ margin: 0px;
+ padding: 0px;
+}
+
+#dash.vertical .app-well-app,
+#dash.vertical .show-apps {
+ /* left/right padding exceeds dash bg by 6px to
+ cover spacing between dash and the edge of the screen
+ so the icons will be selectable even at the edge
+ this spacing must be accounted for in overview allocate() */
+ padding-right: 16px;
+ padding-left: 16px;
+ /*spacing between icons*/
+ padding-top: 1px;
+ padding-bottom: 1px;
+ margin: 0px;
+}
+
+#dash.vertical .dash-separator {
+ height: 1px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ background-color: transparentize(#eeeeec, 0.7);
+}
+
+#dash.vertical .overview-icon {
+ padding: 5px 0;
+}
+
+#dash.vertical .app-well-app-running-dot {
+ margin: 4px 0px;
+}
+
+#dash.vertical .app-well-app-running-dot-custom {
+ margin: 4px 0px;
+ width: 2px;
+ height: 16px;
+}
+
+#dash.vertical .dash-background {
+ margin: 0px;
+}
+
+#dash.vertical-gs3-left .dash-background {
+ border-radius: 0 18px 18px 0;
+ border-left: 0px;
+ padding: 8px 12px 8px 4px;
+ margin-left: 0;
+}
+
+#dash.vertical-gs3-right .dash-background {
+ border-radius: 18px 0 0 18px;
+ border-right: 0px;
+ padding: 8px 4px 8px 12px;
+ margin-right: 0;
+}
+
+#dash.vertical-gs3-left {
+ margin-right: 6px;
+ margin-left: 0px;
+ padding: 0px;
+}
+
+#dash.vertical-gs3-right {
+ margin-right: 0px;
+ margin-left: 6px;
+ padding: 0px;
+}
+
+#dash.vertical-gs3-left .app-well-app,
+#dash.vertical-gs3-left .show-apps,
+#dash.vertical-gs3-right .app-well-app,
+#dash.vertical-gs3-right .show-apps {
+ /* left/right padding exceeds dash bg by 6px to
+ cover spacing between dash and the edge of the screen
+ so the icons will be selectable even at the edge
+ this spacing must be accounted for in overview allocate() */
+ padding-right: 9px;
+ padding-left: 9px;
+}
+
+.dash-background-light {
+ background-color: rgb(200, 200, 200);
+ border-color: rgba(150, 150, 150, 0.4);
+}
+
+.dash-background-reduced {
+ padding: 10px;
+}
+
+.app-well-app-running-dot {
+ margin-bottom: 12px;
+}
+
+.app-well-app-running-dot-custom {
+ margin-bottom: 12px;
+ width: 16px;
+ height: 2px;
+}
+
+/* add shadow to the app grid app label to be readable if it overlaps light icon below */
+.overview-icon-with-label, .folder-name-label {
+ text-shadow: 1px 1px 3px rgba(33, 33, 33, 0.5);
+}
+
+/* adjustment for the vertical ws switcher indicator popup*/
+.ws-switcher-indicator {
+ padding: 3px;
+ margin: 5px;
+}
+
+.ws-switcher-indicator:active {
+ padding: 5px;
+ margin: 3px;
+}
+
+/* ws thumbnails captions */
+.ws-tmb-label {
+ padding: 2px;
+ color: rgb(255, 255, 255);
+ background-color: rgba(40,40,40,0.8);
+ text-align: center;
+}
+
+.workspace-thumbnail-indicator {
+ border-radius: 6px;
+}
+
+.ws-tmb-labeled {
+ border: 0px;
+}
+
+.ws-tmb-transparent {
+ border: 0px;
+ background-color: rgba(200, 200, 200, 0.2);
+}
+
+/* app grid page indicatos */
+.page-indicator-icon {
+ margin: 10px 10px 10px 10px;
+}
+
+.page-indicator {
+ padding: 0px;
+}
+
+/* GS 43 App Grid - indicators that show up when dragging icon */
+.prevPageIndicator {
+ background: rgba(255, 255, 255, 0.1);
+ background-gradient-start: rgba(255, 255, 255, 0.1);
+ background-gradient-end: transparent;
+ background-gradient-direction: vertical;
+ border-radius: 100px 100px 0px 0px;
+}
+.nextPageIndicator {
+ background: rgba(255, 255, 255, 0.1);
+ background-gradient-start: transparent;
+ background-gradient-end: rgba(255, 255, 255, 0.1);
+ background-gradient-direction: vertical;
+ border-radius: 0px 0px 100px 100px;
+
+}
+/*
+.search-entry{
+ background-color: rgba(200, 200, 200, 0.1);
+ color: white;
+ border-color: rgba(160, 160, 160, 0.4);
+}
+
+.search-entry:hover,
+.search-entry:focus {
+ background-color: rgba(200, 200, 200, 0.2);
+}*/
+
+.search-entry-om2 {
+ color: white;
+ background-color: rgba(40, 40, 40, 1);
+}
+
+.search-entry-om2:hover,
+.search-entry-om2:focus {
+ background-color: rgba(50, 50, 50, 1);
+}
+
+/* for static ws mode */
+/*.search-section-content-bg,*/
+.search-section-content-bg-om2 {
+ border-radius: 26px;
+ border: 1px, rgb(60, 60, 60);
+ padding-top: 15px;
+}
+
+.search-section-content-bg-om2 {
+ background-color: rgb(40, 40, 40);
+}
+
+.search-section-content {
+ background-color: rgba(200, 200, 200, 0.1);
+}
+
+/* "no results" / "searching..." text*/
+.search-statustext, .search-statustext-om2 {
+ background-color: rgba(200, 200, 200, 0.1);
+ color: white;
+ margin-top: 50px;
+ padding: 30px;
+ border-radius: 20px;
+ text-shadow: 0px 0px 5px rgb(23, 23, 23);
+}
+
+.search-statustext-om2 {
+ background-color: rgb(40, 40, 40);
+ border: 1px rgba(200, 200, 200, 0.1);
+}
+
+#panel:overview, .transparent-panel {
+ background-color: transparent;
+}
+
+/* reduce spacing between app icons in search results */
+.grid-search-results {
+ spacing: 4px;
+}
+
+/* hide vertical scroll bar, it's distracting in the search results */
+StButton#vhandle {
+ background-color: transparent;
+}
+
+.show-apps-icon-horizontal-hide {
+ width: 0;
+ margin: 0;
+ spacing: 0;
+}
+
+.show-apps-icon-vertical-hide {
+ height: 0;
+ margin: 0;
+ spacing: 0;
+}
+
+.workspace-close-button {
+ color: white;
+ background-color: dimgrey;
+ width: 18px;
+ height: 18px;
+ padding: 2px;
+ margin: 2px;
+ box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2);
+ border: 0px;
+ border-radius: 35px;
+}
+
+.workspace-close-button-hover {
+ background-color: rgb(255, 0, 0);
+}
+
+/* ws tmb placeholder */
+.placeholder-vertical {
+ background-size: contain;
+ height: 18px;
+}
+
+/* reduce size of hot corner ripples to half */
+.ripple-box {
+ width: 26px;
+ height: 26px;
+}
+
+.osd-window {
+ margin: 4em;
+}
+
+.app-folder .overview-icon,
+.edit-folder-button,
+.folder-name-entry {
+ background-color: rgba(200, 200, 200, 0.08);
+}
+
+.app-folder-dialog-vshell {
+ background-color: rgba(200, 200, 200, 0.08);
+}
+
+.app-folder-dialog {
+ border-color: rgba(160, 160, 160, 0.3);
+}
+
+.edit-folder-button:hover,
+.app-folder:hover .overview-icon,
+.app-folder:focus .overview-icon {
+ background-color: rgba(200, 200, 200, 0.15);
+}
+
+/* reduce quick menu buttons height in GS44 */
+/*.quick-toggle,
+.quick-menu-toggle {
+ min-height: 42px;
+}*/