From e87faee1798c0e7da026dedfd5336d7b05143149 Mon Sep 17 00:00:00 2001 From: nemof_san Date: Sun, 4 Dec 2022 13:01:25 +0300 Subject: [PATCH] Add profile gnome 42 --- .../Manifest | 2 + ...ome-shell-extension-dash-to-dock-72.ebuild | 63 + .../Manifest | 4 + ...sion-maximize-to-empty-workspace-11.ebuild | 49 + ...sion-maximize-to-empty-workspace-12.ebuild | 49 + .../Manifest | 2 + ...nome-shell-extension-no-overview-11.ebuild | 49 + .../Manifest | 3 + .../files/remove-app-menu-makefile-9.0.patch | 38 + ...shell-extension-remove-app-menu-9.0.ebuild | 54 + .../Manifest | 6 + .../tweaks-system-menu-build-meson.patch | 69 + .../tweaks-system-menu-gse-build-meson.patch | 58 + ...tweaks-system-menu-gse-meson_options.patch | 9 + .../tweaks-system-menu-meson_options.patch | 9 + ...ell-extension-tweaks-system-menu-18.ebuild | 71 + metadata/layout.conf | 15 + net-misc/yandex-disk/Manifest | 2 + .../yandex-disk-0.1.6.1080_p1.ebuild | 50 + net-wireless/rtl88x2bu/Manifest | 4 + .../rtl88x2bu/rtl88x2bu-20211010.ebuild | 47 + .../rtl88x2bu/rtl88x2bu-20220523.ebuild | 48 + profiles/CLDG/amd64/20/calculate.env | 3 + profiles/CLDG/amd64/20/parent | 2 + profiles/CLDG/amd64/parent | 2 + profiles/CLDG/calculate.env | 6 + profiles/CLDG/make.defaults | 3 + profiles/CLDG/package.accept_keywords | 4 + profiles/CLDG/package.mask | 5 + profiles/CLDG/package.use | 124 + profiles/CLDG/parent | 1 + profiles/arch.list | 1 + profiles/calculate.env | 7 + profiles/profiles.desc | 13 + profiles/repo_name | 1 + .../2_ac_install_merge/.calculate_directory | 1 + .../Depends/.calculate_directory | 1 + .../templates/2_ac_install_merge/Depends/gdm | 1 + .../2_ac_install_merge/README-eng.txt | 13 + .../2_ac_install_merge/README-rus.txt | 13 + .../gnome-base/.calculate_directory | 1 + .../gnome-base/gdm/.calculate_directory | 1 + .../gdm/PostLogin/.calculate_directory | 1 + .../gnome-base/gdm/PostLogin/Default | 7 + .../gdm/PostSession/.calculate_directory | 1 + .../gnome-base/gdm/PostSession/Default | 7 + .../gnome-base/gdm/gdm-launch-environment | 23 + .../net-wireless/.calculate_directory | 1 + .../gnome-bluetooth/.calculate_directory | 1 + .../gnome-bluetooth/61-gnome-bluetooth.rules | 12 + .../3_ac_install_live/.calculate_directory | 1 + .../1-merge/.calculate_directory | 1 + .../1-merge/gnome-base/.calculate_directory | 1 + .../gnome-base/gdm/.calculate_directory | 1 + .../1-merge/gnome-base/gdm/0-custom.conf | 19 + .../1-merge/gnome-base/gdm/1-custom.conf | 12 + .../gnome-base/gdm/logo/.calculate_directory | 1 + .../gdm/logo/db/.calculate_directory | 1 + .../1-merge/gnome-base/gdm/logo/db/gdm | Bin 0 -> 264 bytes .../logo/db/gdm.d/02-calculate-gdm-branding | 2 + .../gdm/logo/profile/.calculate_directory | 1 + .../1-merge/gnome-base/gdm/logo/profile/gdm | 3 + .../gnome-base/gdm/logo/zzz-update-dconf | 6 + .../gdm/themes/.calculate_directory | 1 + .../gdm/themes/dim-gray/.calculate_directory | 1 + .../dim-gray/gnome-shell/.calculate_directory | 1 + .../gnome-shell/gnome-shell-theme.gresource | Bin 0 -> 327345 bytes .../gdm/wallpapers/.calculate_directory | 1 + .../gdm/wallpapers/calculate-logo.png | Bin 0 -> 13314 bytes .../1-merge/gui-libs/.calculate_directory | 1 + .../display-manager-init/.calculate_directory | 2 + .../conf.d/display-manager | 39 + .../1-merge/sys-apps/.calculate_directory | 1 + .../calculate-utils/.calculate_directory | 2 + .../ini.example/.calculate_directory | 1 + .../calculate-utils/ini.example/0-example | 18 + .../ini.example/1-example.system | 25 + .../ini.example/2-example.theme | 324 ++ .../ini.example/3-example.profile | 172 + .../ini.example/4-example.container | 36 + .../1-merge/x11-base/.calculate_directory | 1 + .../x11-base/xorg-server/.calculate_directory | 2 + .../xorg-server/conf.d/.calculate_directory | 1 + .../1-merge/x11-base/xorg-server/conf.d/xdm | 39 + .../wallpapers/.calculate_directory | 1 + .../wallpapers/calculate-gnome.xml | 97 + .../calculate-gnome/.calculate_directory | 1 + .../Calculate Linux 11 Blue.jpg | 1 + .../Calculate Linux 11 Brown.jpg | 1 + .../Calculate Linux 12 Blue.jpg | 1 + .../Calculate Linux 12 Brown.jpg | 1 + .../Calculate Linux 13 Blue.jpg | 1 + .../Calculate Linux 13 Brown.jpg | 1 + .../Calculate Linux 13 Green.jpg | 1 + .../Calculate Linux 13 Magenta.jpg | 1 + .../calculate-gnome/Calculate Linux 14.jpg | 1 + .../calculate-gnome/Calculate Linux 15.jpg | 1 + .../calculate-gnome/Calculate Linux 17.jpg | 1 + .../calculate-gnome/Calculate Linux.jpg | 1 + .../wallpapers/calculate.xml.remove | 1 + .../templates/3_ac_install_live/Depends/gdm | 1 + .../3_ac_install_live/README-eng.txt | 15 + .../3_ac_install_live/README-rus.txt | 14 + .../6_ac_desktop_profile/.calculate_directory | 1 + .../2-user/.calculate_directory | 1 + .../2-user/gnome-base/.calculate_directory | 1 + .../Gnome-40.0/.cache/.calculate_directory | 1 + .../Gnome-40.0/.calculate_directory | 1 + .../Gnome-40.0/Desktop/.calculate_directory | 1 + .../gnome-base/Gnome-40.0/Desktop/FTP.desktop | 9 + .../Gnome-40.0/Desktop/Home.desktop | 9 + .../Gnome-40.0/Desktop/README.desktop | 28 + .../Gnome-40.0/Desktop/Share.desktop | 9 + .../Desktop/calculate-community.desktop | 1 + .../Desktop/calculate-install.desktop | 3 + .../applications/.calculate_directory | 1 + .../cl-console-gui-update.desktop | 11 + .../applications/cl-console-gui.desktop | 10 + .../desktop-directories/.calculate_directory | 1 + .../SystemSettings.directory | 12 + .../extensions/.calculate_directory | 1 + .../extensions/ShutdownTimer@deminder/LICENSE | 674 ++++ .../ShutdownTimer@deminder/extension.js | 546 +++ .../icons/shutdown-timer-symbolic.svg | 4 + .../lib/CheckCommand.js | 95 + .../ShutdownTimer@deminder/lib/Convenience.js | 163 + .../lib/EndSessionDialogAware.js | 113 + .../ShutdownTimer@deminder/lib/InfoFetcher.js | 120 + .../ShutdownTimer@deminder/lib/Install.js | 89 + .../ShutdownTimer@deminder/lib/MenuItem.js | 444 +++ .../ShutdownTimer@deminder/lib/RootMode.js | 279 ++ .../lib/ScheduleInfo.js | 84 + .../lib/SessionModeAware.js | 33 + .../ShutdownTimer@deminder/lib/Textbox.js | 119 + .../ShutdownTimer@deminder/lib/Timer.js | 118 + .../locale/cs/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1871 bytes .../locale/de/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 10074 bytes .../locale/el/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1993 bytes .../locale/es/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 980 bytes .../locale/fr/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1834 bytes .../locale/it/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1873 bytes .../locale/nl/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 3371 bytes .../locale/pl/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1977 bytes .../locale/pt/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1801 bytes .../locale/ru/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1147 bytes .../locale/zh_CN/LC_MESSAGES/ShutdownTimer.mo | Bin 0 -> 1620 bytes .../ShutdownTimer@deminder/metadata.json | 17 + .../10-dem.shutdowntimer.settimers.rules | 8 + ...0-dem.shutdowntimer.settimers.rules.legacy | 12 + .../polkit/dem.shutdowntimer.policy.in | 20 + .../ShutdownTimer@deminder/prefs.js | 229 ++ .../schemas/gschemas.compiled | Bin 0 -> 1820 bytes ...ensions.shutdowntimer-deminder.gschema.xml | 135 + .../ShutdownTimer@deminder/stylesheet.css | 28 + .../ShutdownTimer@deminder/tool/installer.sh | 261 ++ .../tool/shutdowntimerctl | 53 + .../ShutdownTimer@deminder/ui/prefs.ui | 456 +++ .../extensions/Vitals@CoreCoding.com/LICENSE | 339 ++ .../Vitals@CoreCoding.com/extension.js | 564 +++ .../Vitals@CoreCoding.com/helpers/file.js | 85 + .../helpers/polyfills.js | 184 + .../icons/battery-symbolic.svg | 8 + .../icons/cpu-symbolic.svg | 1 + .../icons/fan-symbolic.svg | 133 + .../icons/memory-symbolic.svg | 1 + .../icons/network-download-symbolic.svg | 1 + .../icons/network-symbolic.svg | 1 + .../icons/network-upload-symbolic.svg | 1 + .../icons/storage-symbolic.svg | 3 + .../icons/system-symbolic.svg | 3 + .../icons/temperature-symbolic.svg | 45 + .../icons/voltage-symbolic.svg | 125 + .../locale/ca/LC_MESSAGES/vitals.mo | Bin 0 -> 3343 bytes .../locale/cs/LC_MESSAGES/vitals.mo | Bin 0 -> 8410 bytes .../locale/es/LC_MESSAGES/vitals.mo | Bin 0 -> 3298 bytes .../locale/fi_FI/LC_MESSAGES/vitals.mo | Bin 0 -> 4004 bytes .../locale/fr/LC_MESSAGES/vitals.mo | Bin 0 -> 7332 bytes .../locale/it/LC_MESSAGES/vitals.mo | Bin 0 -> 3076 bytes .../locale/nl/LC_MESSAGES/vitals.mo | Bin 0 -> 6980 bytes .../locale/oc/LC_MESSAGES/vitals.mo | Bin 0 -> 3817 bytes .../locale/pl/LC_MESSAGES/vitals.mo | Bin 0 -> 3543 bytes .../locale/pt/LC_MESSAGES/vitals.mo | Bin 0 -> 3935 bytes .../locale/pt_BR/LC_MESSAGES/vitals.mo | Bin 0 -> 3654 bytes .../locale/ru/LC_MESSAGES/vitals.mo | Bin 0 -> 3116 bytes .../locale/sk/LC_MESSAGES/vitals.mo | Bin 0 -> 8624 bytes .../locale/tr/LC_MESSAGES/vitals.mo | Bin 0 -> 3338 bytes .../locale/uk/LC_MESSAGES/vitals.mo | Bin 0 -> 11046 bytes .../locale/zh_CN/LC_MESSAGES/vitals.mo | Bin 0 -> 7963 bytes .../Vitals@CoreCoding.com/menuItem.js | 77 + .../Vitals@CoreCoding.com/metadata.json | 17 + .../extensions/Vitals@CoreCoding.com/prefs.js | 149 + .../Vitals@CoreCoding.com/prefs.legacy.ui | 1669 ++++++++ .../extensions/Vitals@CoreCoding.com/prefs.ui | 1111 ++++++ .../schemas/gschemas.compiled | Bin 0 -> 1676 bytes .../Vitals@CoreCoding.com/sensors.js | 629 ++++ .../Vitals@CoreCoding.com/stylesheet.css | 16 + .../Vitals@CoreCoding.com/values.js | 337 ++ .../components/appfolders.js | 265 ++ .../components/applications.js | 541 +++ .../components/dash_to_dock.js | 320 ++ .../components/lockscreen.js | 171 + .../components/overview.js | 294 ++ .../blur-my-shell@aunetx/components/panel.js | 660 ++++ .../components/screenshot.js | 166 + .../components/window_list.js | 165 + .../conveniences/connections.js | 104 + .../blur-my-shell@aunetx/conveniences/keys.js | 131 + .../conveniences/settings.js | 185 + .../blur-my-shell@aunetx/dbus/client.js | 60 + .../blur-my-shell@aunetx/dbus/iface.xml | 12 + .../blur-my-shell@aunetx/dbus/services.js | 93 + .../effects/color_effect.glsl | 13 + .../effects/color_effect.js | 186 + .../effects/noise_effect.glsl | 18 + .../effects/noise_effect.js | 106 + .../effects/paint_signals.js | 90 + .../blur-my-shell@aunetx/extension.js | 642 ++++ .../scalable/actions/add-window-symbolic.svg | 4 + .../actions/applications-symbolic.svg | 56 + .../actions/bottom-panel-symbolic.svg | 44 + .../scalable/actions/dash-symbolic.svg | 44 + .../scalable/actions/general-symbolic.svg | 64 + .../actions/heart-filled-symbolic.svg | 40 + .../scalable/actions/other-symbolic.svg | 1 + .../scalable/actions/overview-symbolic.svg | 56 + .../actions/remove-window-symbolic.svg | 3 + .../scalable/actions/reset-symbolic.svg | 7 + .../scalable/actions/select-mode-symbolic.svg | 2 + .../actions/select-window-symbolic.svg | 2 + .../ar/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 5625 bytes .../cs/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 7850 bytes .../de/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 8265 bytes .../es/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 7998 bytes .../fr/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 8067 bytes .../hu/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 1013 bytes .../it/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 8009 bytes .../ko/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 4504 bytes .../nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 3918 bytes .../nl/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 8008 bytes .../pl/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 7888 bytes .../pt/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 7796 bytes .../ru/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 10050 bytes .../sv/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 326 bytes .../ta/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 13483 bytes .../tr/LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 6084 bytes .../LC_MESSAGES/blur-my-shell@aunetx.mo | Bin 0 -> 7158 bytes .../blur-my-shell@aunetx/metadata.json | 16 + .../preferences/applications.js | 175 + .../preferences/customize_row.js | 168 + .../blur-my-shell@aunetx/preferences/dash.js | 45 + .../preferences/general.js | 50 + .../blur-my-shell@aunetx/preferences/menu.js | 64 + .../blur-my-shell@aunetx/preferences/other.js | 51 + .../preferences/overview.js | 49 + .../blur-my-shell@aunetx/preferences/panel.js | 62 + .../preferences/window_row.js | 108 + .../extensions/blur-my-shell@aunetx/prefs.js | 43 + .../schemas/gschemas.compiled | Bin 0 -> 7773 bytes ...shell.extensions.blur-my-shell.gschema.xml | 457 +++ .../blur-my-shell@aunetx/stylesheet.css | 257 ++ .../blur-my-shell@aunetx/ui/applications.ui | 163 + .../blur-my-shell@aunetx/ui/customize-row.ui | 143 + .../blur-my-shell@aunetx/ui/dash.ui | 73 + .../blur-my-shell@aunetx/ui/general.ui | 234 ++ .../blur-my-shell@aunetx/ui/menu.ui | 37 + .../blur-my-shell@aunetx/ui/other.ui | 62 + .../blur-my-shell@aunetx/ui/overview.ui | 94 + .../blur-my-shell@aunetx/ui/panel.ui | 126 + .../blur-my-shell@aunetx/ui/window-row.ui | 43 + .../LICENSE | 674 ++++ .../extension.js | 1330 +++++++ .../locale/ar/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 5544 bytes .../locale/ca/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4969 bytes .../locale/de/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4688 bytes .../locale/es/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4757 bytes .../locale/fr/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4711 bytes .../locale/gl/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4648 bytes .../locale/it/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4395 bytes .../locale/lt/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 1724 bytes .../locale/nb_NO/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 2827 bytes .../locale/nl/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4859 bytes .../locale/ru/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 5773 bytes .../locale/sk/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4488 bytes .../locale/tr/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4641 bytes .../zh_Hans/LC_MESSAGES/desktop-cube.mo | Bin 0 -> 4119 bytes .../metadata.json | 16 + .../prefs.js | 263 ++ .../resources/desktop-cube.gresource | Bin 0 -> 63704 bytes .../schemas/gschemas.compiled | Bin 0 -> 1464 bytes .../src/DragGesture.js | 317 ++ .../src/ImageChooserButton.js | 97 + .../src/Skybox.js | 154 + .../src/utils.js | 50 + .../stylesheet.css | 20 + .../CHANGELOG.md | 420 +++ .../LICENSE | 675 ++++ .../bin/close-button.svg | 50 + .../extension.js | 121 + .../lib/API.js | 3354 +++++++++++++++++ .../lib/Manager.js | 1463 +++++++ .../lib/Prefs/Prefs.js | 805 ++++ .../lib/Prefs/PrefsKeys.js | 888 +++++ .../locale/af/LC_MESSAGES/just-perfection.mo | Bin 0 -> 10741 bytes .../locale/ar/LC_MESSAGES/just-perfection.mo | Bin 0 -> 12947 bytes .../locale/be/LC_MESSAGES/just-perfection.mo | Bin 0 -> 14608 bytes .../locale/bg/LC_MESSAGES/just-perfection.mo | Bin 0 -> 15371 bytes .../locale/ca/LC_MESSAGES/just-perfection.mo | Bin 0 -> 11790 bytes .../locale/de/LC_MESSAGES/just-perfection.mo | Bin 0 -> 11459 bytes .../locale/es/LC_MESSAGES/just-perfection.mo | Bin 0 -> 12105 bytes .../locale/fr/LC_MESSAGES/just-perfection.mo | Bin 0 -> 12149 bytes .../locale/gl/LC_MESSAGES/just-perfection.mo | Bin 0 -> 12036 bytes .../locale/it/LC_MESSAGES/just-perfection.mo | Bin 0 -> 11713 bytes .../locale/ne/LC_MESSAGES/just-perfection.mo | Bin 0 -> 16446 bytes .../locale/nl/LC_MESSAGES/just-perfection.mo | Bin 0 -> 10848 bytes .../pt_BR/LC_MESSAGES/just-perfection.mo | Bin 0 -> 11686 bytes .../locale/ru/LC_MESSAGES/just-perfection.mo | Bin 0 -> 14268 bytes .../locale/sv/LC_MESSAGES/just-perfection.mo | Bin 0 -> 10722 bytes .../zh_CN/LC_MESSAGES/just-perfection.mo | Bin 0 -> 10340 bytes .../zh_TW/LC_MESSAGES/just-perfection.mo | Bin 0 -> 10325 bytes .../metadata.json | 18 + .../prefs.js | 79 + .../schemas/gschemas.compiled | Bin 0 -> 4309 bytes ...ell.extensions.just-perfection.gschema.xml | 407 ++ .../stylesheet.css | 809 ++++ .../ui/adw/behavior.ui | 123 + .../ui/adw/customize.ui | 732 ++++ .../ui/adw/icons.ui | 169 + .../ui/adw/profile.ui | 161 + .../ui/adw/visibility.ui | 368 ++ .../ui/behavior.ui | 616 +++ .../ui/customize.ui | 1586 ++++++++ .../ui/icons.ui | 550 +++ .../ui/intro.ui | 35 + .../ui/main.ui | 176 + .../ui/no-results-found.ui | 35 + .../ui/override.ui | 131 + .../ui/profile.ui | 104 + .../ui/visibility.ui | 2078 ++++++++++ .../extension.js | 435 +++ .../metadata.json | 14 + .../prefs.js | 492 +++ .../schemas/gschemas.compiled | Bin 0 -> 925 bytes ...ions.round-system-menu-buttons.gschema.xml | 69 + .../stylesheet.css | 13 + .../base.js | 759 ++++ .../convenience.js | 357 ++ .../extension.js | 290 ++ .../icons/blank.png | Bin 0 -> 133 bytes .../license | 674 ++++ .../sound-output-device-chooser.mo | Bin 0 -> 1582 bytes .../sound-output-device-chooser.mo | Bin 0 -> 1661 bytes .../sound-output-device-chooser.mo | Bin 0 -> 1594 bytes .../sound-output-device-chooser.mo | Bin 0 -> 2891 bytes .../sound-output-device-chooser.mo | Bin 0 -> 3129 bytes .../sound-output-device-chooser.mo | Bin 0 -> 1642 bytes .../sound-output-device-chooser.mo | Bin 0 -> 1632 bytes .../sound-output-device-chooser.mo | Bin 0 -> 1883 bytes .../sound-output-device-chooser.mo | Bin 0 -> 4780 bytes .../metadata.json | 20 + .../prefs.js | 328 ++ .../schemas/gschemas.compiled | Bin 0 -> 1248 bytes ...ns.sound-output-device-chooser.gschema.xml | 101 + .../ui/prefs-dialog.glade | 956 +++++ .../ui/prefs-dialog40.glade | 655 ++++ .../libpulse_introspect.cpython-310.pyc | Bin 0 -> 9746 bytes .../libpulse_introspect.cpython-39.pyc | Bin 0 -> 9907 bytes .../utils/libpulse_introspect.py | 544 +++ .../utils/pa_helper.py | 141 + .../2-user/gnome-base/Gnome-40.0/gnome | 156 + .../2-user/gnome-base/Gnome-40.0/ini.env | 11 + .../gnome-base/Gnome-40.0/user-folders.lst | 1 + .../6_ac_desktop_profile/README-eng.txt | 8 + .../6_ac_desktop_profile/README-rus.txt | 8 + .../.calculate_directory | 1 + .../6_ac_install_configure/README-eng.txt | 7 + .../6_ac_install_configure/README-rus.txt | 8 + .../templates/6_ac_install_configure/session | 7 + .../6_ac_update_sync/.calculate_directory | 1 + .../templates/6_ac_update_sync/README-eng.txt | 7 + .../templates/6_ac_update_sync/README-rus.txt | 7 + .../world/.calculate_directory | 1 + .../templates/6_ac_update_sync/world/0-ini | 4 + .../world/create/.calculate_directory | 1 + .../world/create/applications | 13 + .../6_ac_update_sync/world/create/base | 11 + .../6_ac_update_sync/world/create/decoration | 23 + .../6_ac_update_sync/world/create/gnome | 18 + .../6_ac_update_sync/world/create/graphics | 10 + .../6_ac_update_sync/world/create/multimedia | 8 + .../6_ac_update_sync/world/create/netapps | 22 + .../6_ac_update_sync/world/create/network | 17 + .../6_ac_update_sync/world/create/printer | 22 + .../6_ac_update_sync/world/create/tools | 87 + .../6_ac_update_sync/world/create/wireless | 15 + .../6_ac_update_sync/world/create/xorg | 13 + .../world/update/.calculate_directory | 1 + .../world/update/2022/.calculate_directory | 1 + .../world/update/2022/20220204 | 5 + .../world/update/2022/20220420 | 5 + .../world/update/2022/20220805 | 5 + .../world/update/2022/20220905 | 7 + sys-power/power-profiles-daemon/Manifest | 7 + .../files/power-profiles-daemon.confd | 3 + .../files/power-profiles-daemon.initd | 13 + .../files/power-profiles-daemon.tmpfiles | 1 + .../power-profiles-daemon-0.11.1.ebuild | 50 + .../power-profiles-daemon-0.12.ebuild | 50 + 407 files changed, 43938 insertions(+) create mode 100644 gnome-extra/gnome-shell-extension-dash-to-dock/Manifest create mode 100644 gnome-extra/gnome-shell-extension-dash-to-dock/gnome-shell-extension-dash-to-dock-72.ebuild create mode 100644 gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/Manifest create mode 100644 gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-11.ebuild create mode 100644 gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-12.ebuild create mode 100644 gnome-extra/gnome-shell-extension-no-overview/Manifest create mode 100644 gnome-extra/gnome-shell-extension-no-overview/gnome-shell-extension-no-overview-11.ebuild create mode 100644 gnome-extra/gnome-shell-extension-remove-app-menu/Manifest create mode 100644 gnome-extra/gnome-shell-extension-remove-app-menu/files/remove-app-menu-makefile-9.0.patch create mode 100644 gnome-extra/gnome-shell-extension-remove-app-menu/gnome-shell-extension-remove-app-menu-9.0.ebuild create mode 100644 gnome-extra/gnome-shell-extension-tweaks-system-menu/Manifest create mode 100644 gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-build-meson.patch create mode 100644 gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-build-meson.patch create mode 100644 gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-meson_options.patch create mode 100644 gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-meson_options.patch create mode 100644 gnome-extra/gnome-shell-extension-tweaks-system-menu/gnome-shell-extension-tweaks-system-menu-18.ebuild create mode 100644 metadata/layout.conf create mode 100644 net-misc/yandex-disk/Manifest create mode 100644 net-misc/yandex-disk/yandex-disk-0.1.6.1080_p1.ebuild create mode 100644 net-wireless/rtl88x2bu/Manifest create mode 100644 net-wireless/rtl88x2bu/rtl88x2bu-20211010.ebuild create mode 100644 net-wireless/rtl88x2bu/rtl88x2bu-20220523.ebuild create mode 100644 profiles/CLDG/amd64/20/calculate.env create mode 100644 profiles/CLDG/amd64/20/parent create mode 100644 profiles/CLDG/amd64/parent create mode 100644 profiles/CLDG/calculate.env create mode 100644 profiles/CLDG/make.defaults create mode 100644 profiles/CLDG/package.accept_keywords create mode 100644 profiles/CLDG/package.mask create mode 100644 profiles/CLDG/package.use create mode 100644 profiles/CLDG/parent create mode 100644 profiles/arch.list create mode 100644 profiles/calculate.env create mode 100644 profiles/profiles.desc create mode 100644 profiles/repo_name create mode 100644 profiles/templates/2_ac_install_merge/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/Depends/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/Depends/gdm create mode 100644 profiles/templates/2_ac_install_merge/README-eng.txt create mode 100644 profiles/templates/2_ac_install_merge/README-rus.txt create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/gdm/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/Default create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/Default create mode 100644 profiles/templates/2_ac_install_merge/gnome-base/gdm/gdm-launch-environment create mode 100644 profiles/templates/2_ac_install_merge/net-wireless/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/.calculate_directory create mode 100644 profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/61-gnome-bluetooth.rules create mode 100644 profiles/templates/3_ac_install_live/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/0-custom.conf create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/1-custom.conf create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm.d/02-calculate-gdm-branding create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/gdm create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/zzz-update-dconf create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/gnome-shell-theme.gresource create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/calculate-logo.png create mode 100644 profiles/templates/3_ac_install_live/1-merge/gui-libs/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/conf.d/display-manager create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/0-example create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/1-example.system create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/2-example.theme create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/3-example.profile create mode 100644 profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/4-example.container create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/xdm create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome.xml create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/.calculate_directory create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Blue.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Brown.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Blue.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Brown.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Blue.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Brown.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Green.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Magenta.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 14.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 15.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 17.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux.jpg create mode 100644 profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate.xml.remove create mode 100644 profiles/templates/3_ac_install_live/Depends/gdm create mode 100644 profiles/templates/3_ac_install_live/README-eng.txt create mode 100644 profiles/templates/3_ac_install_live/README-rus.txt create mode 100644 profiles/templates/6_ac_desktop_profile/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.cache/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/FTP.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Home.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/README.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Share.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-community.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-install.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui-update.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui.desktop create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/SystemSettings.directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/.calculate_directory create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/LICENSE create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/icons/shutdown-timer-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/CheckCommand.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Convenience.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/EndSessionDialogAware.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/InfoFetcher.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Install.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/MenuItem.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/RootMode.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/ScheduleInfo.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/SessionModeAware.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Textbox.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Timer.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/cs/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/de/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/el/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/es/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/fr/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/it/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/nl/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/pl/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/pt/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/ru/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/zh_CN/LC_MESSAGES/ShutdownTimer.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules.legacy create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/dem.shutdowntimer.policy.in create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/org.gnome.shell.extensions.shutdowntimer-deminder.gschema.xml create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/stylesheet.css create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/installer.sh create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/shutdowntimerctl create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/ui/prefs.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/LICENSE create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/file.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/polyfills.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/battery-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/cpu-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/fan-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/memory-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-download-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-upload-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/storage-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/system-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/temperature-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/voltage-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/ca/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/cs/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/es/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/fi_FI/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/fr/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/it/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/nl/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/oc/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pl/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pt/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/ru/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/sk/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/tr/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/uk/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/zh_CN/LC_MESSAGES/vitals.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/menuItem.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.legacy.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/sensors.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/stylesheet.css create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/values.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/appfolders.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/applications.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/dash_to_dock.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/lockscreen.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/overview.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/panel.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/screenshot.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/window_list.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/connections.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/keys.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/settings.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/client.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/iface.xml create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/services.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.glsl create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.glsl create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/paint_signals.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-window-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/general-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-filled-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-window-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-mode-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/cs/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/hu/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/it/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ko/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/pl/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/pt/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/sv/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/tr/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/zh_Hans/LC_MESSAGES/blur-my-shell@aunetx.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/applications.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/customize_row.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/dash.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/general.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/menu.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/other.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/overview.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/panel.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/window_row.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/stylesheet.css create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/applications.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/customize-row.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/dash.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/general.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/menu.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/other.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/overview.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/panel.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/window-row.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/LICENSE create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/ar/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/ca/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/de/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/es/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/fr/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/gl/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/it/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/lt/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/nb_NO/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/nl/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/ru/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/sk/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/tr/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/zh_Hans/LC_MESSAGES/desktop-cube.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/resources/desktop-cube.gresource create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/DragGesture.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/ImageChooserButton.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/Skybox.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/utils.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/stylesheet.css create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/CHANGELOG.md create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/LICENSE create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/bin/close-button.svg create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/API.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Manager.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/Prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/PrefsKeys.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/af/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/ar/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/be/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/bg/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/ca/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/de/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/es/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/fr/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/gl/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/it/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/ne/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/nl/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/pt_BR/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/ru/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/sv/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/zh_CN/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/zh_TW/LC_MESSAGES/just-perfection.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/schemas/org.gnome.shell.extensions.just-perfection.gschema.xml create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/stylesheet.css create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/behavior.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/customize.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/icons.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/profile.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/visibility.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/behavior.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/customize.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/icons.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/intro.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/main.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/no-results-found.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/override.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/profile.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/visibility.ui create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/org.gnome.shell.extensions.round-system-menu-buttons.gschema.xml create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/stylesheet.css create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/base.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/convenience.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/extension.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/icons/blank.png create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/license create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/de_DE/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/it_IT/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/ko/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/nl/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/pt_BR/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/pt_PT/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/sk/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/sv/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/ta/LC_MESSAGES/sound-output-device-chooser.mo create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/metadata.json create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/prefs.js create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/schemas/gschemas.compiled create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/schemas/org.gnome.shell.extensions.sound-output-device-chooser.gschema.xml create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog.glade create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog40.glade create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/__pycache__/libpulse_introspect.cpython-310.pyc create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/__pycache__/libpulse_introspect.cpython-39.pyc create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/pa_helper.py create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/gnome create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/ini.env create mode 100644 profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/user-folders.lst create mode 100644 profiles/templates/6_ac_desktop_profile/README-eng.txt create mode 100644 profiles/templates/6_ac_desktop_profile/README-rus.txt create mode 100644 profiles/templates/6_ac_install_configure/.calculate_directory create mode 100644 profiles/templates/6_ac_install_configure/README-eng.txt create mode 100644 profiles/templates/6_ac_install_configure/README-rus.txt create mode 100644 profiles/templates/6_ac_install_configure/session create mode 100644 profiles/templates/6_ac_update_sync/.calculate_directory create mode 100644 profiles/templates/6_ac_update_sync/README-eng.txt create mode 100644 profiles/templates/6_ac_update_sync/README-rus.txt create mode 100644 profiles/templates/6_ac_update_sync/world/.calculate_directory create mode 100644 profiles/templates/6_ac_update_sync/world/0-ini create mode 100644 profiles/templates/6_ac_update_sync/world/create/.calculate_directory create mode 100644 profiles/templates/6_ac_update_sync/world/create/applications create mode 100644 profiles/templates/6_ac_update_sync/world/create/base create mode 100644 profiles/templates/6_ac_update_sync/world/create/decoration create mode 100644 profiles/templates/6_ac_update_sync/world/create/gnome create mode 100644 profiles/templates/6_ac_update_sync/world/create/graphics create mode 100644 profiles/templates/6_ac_update_sync/world/create/multimedia create mode 100644 profiles/templates/6_ac_update_sync/world/create/netapps create mode 100644 profiles/templates/6_ac_update_sync/world/create/network create mode 100644 profiles/templates/6_ac_update_sync/world/create/printer create mode 100644 profiles/templates/6_ac_update_sync/world/create/tools create mode 100644 profiles/templates/6_ac_update_sync/world/create/wireless create mode 100644 profiles/templates/6_ac_update_sync/world/create/xorg create mode 100644 profiles/templates/6_ac_update_sync/world/update/.calculate_directory create mode 100644 profiles/templates/6_ac_update_sync/world/update/2022/.calculate_directory create mode 100644 profiles/templates/6_ac_update_sync/world/update/2022/20220204 create mode 100644 profiles/templates/6_ac_update_sync/world/update/2022/20220420 create mode 100644 profiles/templates/6_ac_update_sync/world/update/2022/20220805 create mode 100644 profiles/templates/6_ac_update_sync/world/update/2022/20220905 create mode 100644 sys-power/power-profiles-daemon/Manifest create mode 100644 sys-power/power-profiles-daemon/files/power-profiles-daemon.confd create mode 100644 sys-power/power-profiles-daemon/files/power-profiles-daemon.initd create mode 100644 sys-power/power-profiles-daemon/files/power-profiles-daemon.tmpfiles create mode 100644 sys-power/power-profiles-daemon/power-profiles-daemon-0.11.1.ebuild create mode 100644 sys-power/power-profiles-daemon/power-profiles-daemon-0.12.ebuild diff --git a/gnome-extra/gnome-shell-extension-dash-to-dock/Manifest b/gnome-extra/gnome-shell-extension-dash-to-dock/Manifest new file mode 100644 index 0000000..187e342 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-dash-to-dock/Manifest @@ -0,0 +1,2 @@ +DIST gnome-shell-extension-dash-to-dock-72.tar.gz 309825 BLAKE2B be1fcfd11930125bda4befa9d2508c0773812aa5fdfafe4c67797ecbf8c6a95fc3173da21801c1804c0ab71da74e8249d937e072d15fe185d651ab0a634b2ba5 SHA512 a4d2017b9d28c46145cf9cde3e641a7188f0e9febd2a7089973cfacf5b4b5f6f2e402079785b47799e0766d931037bb078ddc37923ae2d4356f764b57f046d28 +EBUILD gnome-shell-extension-dash-to-dock-72.ebuild 1186 BLAKE2B 8b7230e5660737e3c2928098725d571b21b9d1f6221781a5b2150382ef561cbd85da36b81456b3143bc3aba6b3686fa1ab3d301a91da8172ebfd0b6b6978bc33 SHA512 74fbd351566a5dfd436df85795806447c6e16f3deb265b5c0f80c24ebc2264e2e6f8313b2998d09fc7419d54be7b9822df822799ec0895a3201ec899d7f05a8a diff --git a/gnome-extra/gnome-shell-extension-dash-to-dock/gnome-shell-extension-dash-to-dock-72.ebuild b/gnome-extra/gnome-shell-extension-dash-to-dock/gnome-shell-extension-dash-to-dock-72.ebuild new file mode 100644 index 0000000..b5315bb --- /dev/null +++ b/gnome-extra/gnome-shell-extension-dash-to-dock/gnome-shell-extension-dash-to-dock-72.ebuild @@ -0,0 +1,63 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 +inherit gnome2-utils + +MY_PN="${PN/gnome-shell-extension-/}" + +COMMIT="19cc612c53d33e7c529c116a096bf78c66caae29" + +DESCRIPTION="A dock for the Gnome Shell" +HOMEPAGE="https://github.com/micheleg/dash-to-dock" +SRC_URI="https://github.com/micheleg/dash-to-dock/archive/${COMMIT}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="" + +COMMON_DEPEND=" + dev-libs/glib:2 + dev-lang/sassc +" +RDEPEND="${COMMON_DEPEND} + app-eselect/eselect-gnome-shell-extensions + >=gnome-base/gnome-shell-40 +" +DEPEND="${COMMON_DEPEND}" + +BDEPEND="" + +S="${WORKDIR}/${MY_PN}-${COMMIT}" +extension_uuid="dash-to-dock@micxgx.gmail.com" + +src_prepare() { + default + + # Set correct version + export VERSION="${PV}" + + # Don't install README and COPYING in unwanted locations + sed -i -e 's/COPYING//g' -e 's/README.md//g' Makefile || die +} + +src_install() { + default +} + +pkg_preinst() { + gnome2_schemas_savelist +} + +pkg_postinst() { + gnome2_schemas_update + ebegin "Updating list of installed extensions" + eselect gnome-shell-extensions update + eend $? +} + +pkg_postrm() { + gnome2_schemas_update +} + diff --git a/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/Manifest b/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/Manifest new file mode 100644 index 0000000..a004934 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/Manifest @@ -0,0 +1,4 @@ +DIST gnome-shell-extension-maximize-to-empty-workspace-11.tar.gz 15373 BLAKE2B e513b91493c6625404160752b7ea38439f958bf0019d4f2e2c66959e4e2ffad8ec15c9924356d534ea42425f585879e115335af15221ed4f607488efa5fafb80 SHA512 4e66ef00ea3ac8818bcdd0b324521f14c75171a9269e706d9246133c467a12deea5f22642ee86b8cce4fd9eb3ecf1faa06974699bfd414105dec4e3a4c83239d +DIST gnome-shell-extension-maximize-to-empty-workspace-12.tar.gz 15366 BLAKE2B ff91113fdf4208fd2dbe8d244ef3eb4856c23b22490973af87034efefd55a4ce1cfd9a41e3232318243c3890f5f7238a02c198201263a4df587615ecab3740eb SHA512 6350d94755174f9ba8494ce0d181c02802ebc64c041bf02d5dee496e8b3d68b8518b097466026df43ed7617e01935fa5a09134a6297d78e182bb08b9336c58a4 +EBUILD gnome-shell-extension-maximize-to-empty-workspace-11.ebuild 1121 BLAKE2B c7c7dd51422df430bb3c8243ac26e1619007139b04097dae709bcb6dc0306e0fbea931fc0f958cba27849a7235d978524c2908b353163f1de0fbc01881d871b4 SHA512 54ccfe218342a1144173a389f2dcd2f2e0ccaecf75fdd30b9054a78ca5b5f47fdefc5077382f8e9101d3e408bd2db9ecd9769fe405ea33ddb97cf1b1d9d15af5 +EBUILD gnome-shell-extension-maximize-to-empty-workspace-12.ebuild 1121 BLAKE2B de1cce69d2f136752739e78140cde649ea87db92db57ef61438653f116704ea373907ec5f0dff71bc3ba9a27736622e538e0976a4c3d25de208ca9a3e4a04a26 SHA512 744dd737ae0e4cf79d9ef31acaa89dd62e09946dc37f8acd53d7ba1f49ad54bbcc0bcd9d7dae4fd9a45454770134875fd3ed988cf2c74593c6dd1a7e76333d84 diff --git a/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-11.ebuild b/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-11.ebuild new file mode 100644 index 0000000..c50078c --- /dev/null +++ b/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-11.ebuild @@ -0,0 +1,49 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 +inherit gnome2-utils + +COMMIT="4edcb61b47d7169ce809513e58d7814990e1f09a" + +DESCRIPTION="New and maximized windows will be moved to empty workspaces.Supports multiple monitors" +HOMEPAGE="https://github.com/kaiseracm/gnome-shell-extension-maximize-to-empty-workspace" +SRC_URI="https://github.com/kaiseracm/gnome-shell-extension-maximize-to-empty-workspace/archive/${COMMIT}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3+" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="" + +RDEPEND=" + app-eselect/eselect-gnome-shell-extensions + >=gnome-base/gnome-shell-3.38 +" +DEPEND="" +BDEPEND="" + +S="${WORKDIR}/${PN}-${COMMIT}" +extension_uuid="MaximizeToEmptyWorkspace-extension@kaisersite.de" + +src_compile() { :; } + +src_install() { + einstalldocs + insinto /usr/share/gnome-shell/extensions/ + doins -r "${extension_uuid}" +} + +pkg_preinst() { + gnome2_schemas_savelist +} + +pkg_postinst() { + gnome2_schemas_update + ebegin "Updating list of installed extensions" + eselect gnome-shell-extensions update + eend $? +} + +pkg_postrm() { + gnome2_schemas_update +} diff --git a/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-12.ebuild b/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-12.ebuild new file mode 100644 index 0000000..9ee2565 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-maximize-to-empty-workspace/gnome-shell-extension-maximize-to-empty-workspace-12.ebuild @@ -0,0 +1,49 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 +inherit gnome2-utils + +COMMIT="a9c046d66aeaa142ff7e9382001bfc6a004b1dbb" + +DESCRIPTION="New and maximized windows will be moved to empty workspaces.Supports multiple monitors" +HOMEPAGE="https://github.com/kaiseracm/gnome-shell-extension-maximize-to-empty-workspace" +SRC_URI="https://github.com/kaiseracm/gnome-shell-extension-maximize-to-empty-workspace/archive/${COMMIT}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3+" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="" + +RDEPEND=" + app-eselect/eselect-gnome-shell-extensions + >=gnome-base/gnome-shell-3.38 +" +DEPEND="" +BDEPEND="" + +S="${WORKDIR}/${PN}-${COMMIT}" +extension_uuid="MaximizeToEmptyWorkspace-extension@kaisersite.de" + +src_compile() { :; } + +src_install() { + einstalldocs + insinto /usr/share/gnome-shell/extensions/ + doins -r "${extension_uuid}" +} + +pkg_preinst() { + gnome2_schemas_savelist +} + +pkg_postinst() { + gnome2_schemas_update + ebegin "Updating list of installed extensions" + eselect gnome-shell-extensions update + eend $? +} + +pkg_postrm() { + gnome2_schemas_update +} diff --git a/gnome-extra/gnome-shell-extension-no-overview/Manifest b/gnome-extra/gnome-shell-extension-no-overview/Manifest new file mode 100644 index 0000000..f667878 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-no-overview/Manifest @@ -0,0 +1,2 @@ +DIST gnome-shell-extension-no-overview-11.tar.gz 13077 BLAKE2B cfb1c2ab062996798210f13d176f70394e90238ce7487eb420a05d928ddf510965de2f59905d453bfd42fbdfde02ed32e46f33855b82fbac70730238b6c99b85 SHA512 3ec6491ad354ff7f77a28d92f6ba99f14b477bd50b4aa6c9bc148f7c2baf5ff3be69dea4faf11eae4c2a92510509f070cda8329cdbfb73657e77e9172a9447a9 +EBUILD gnome-shell-extension-no-overview-11.ebuild 986 BLAKE2B c28141b28b7f551bb13b001c96dad14413918f34e94900e8cf07b0f621eaab0e753eb9ae9381f30d8c5e0c1d4b01baf7287e4c799245cfbd116f761ee1ae6c70 SHA512 58a0137f9bc8ffe041f361929cb5e554aa4c0a830b0c0fcfa445c1b2d3e043fa942a94e462123884fd116c177a93a686dd2fbf12973b5705c54b8f0ef36b2f01 diff --git a/gnome-extra/gnome-shell-extension-no-overview/gnome-shell-extension-no-overview-11.ebuild b/gnome-extra/gnome-shell-extension-no-overview/gnome-shell-extension-no-overview-11.ebuild new file mode 100644 index 0000000..c562edc --- /dev/null +++ b/gnome-extra/gnome-shell-extension-no-overview/gnome-shell-extension-no-overview-11.ebuild @@ -0,0 +1,49 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 +inherit gnome2-utils + +DESCRIPTION="No overview at start-up. For GNOME Shell 40+" +HOMEPAGE="https://github.com/fthx/no-overview" +SRC_URI="https://github.com/fthx/no-overview/archive/v${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="" + +COMMON_DEPEND=" + dev-libs/glib:2 +" +RDEPEND="${COMMON_DEPEND} + app-eselect/eselect-gnome-shell-extensions + >=gnome-base/gnome-shell-40.0 +" +DEPEND="${COMMON_DEPEND}" +BDEPEND="" + +S="${WORKDIR}/no-overview-${PV}" +extension_uuid="no-overview@fthx" + +src_install() { + einstalldocs + rm -f README.md LICENSE || die + insinto /usr/share/gnome-shell/extensions/"${extension_uuid}" + doins -r * +} + +pkg_preinst() { + gnome2_schemas_savelist +} + +pkg_postinst() { + gnome2_schemas_update + ebegin "Updating list of installed extensions" + eselect gnome-shell-extensions update + eend $? +} + +pkg_postrm() { + gnome2_schemas_update +} diff --git a/gnome-extra/gnome-shell-extension-remove-app-menu/Manifest b/gnome-extra/gnome-shell-extension-remove-app-menu/Manifest new file mode 100644 index 0000000..b52ec12 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-remove-app-menu/Manifest @@ -0,0 +1,3 @@ +AUX remove-app-menu-makefile-9.0.patch 928 BLAKE2B 466c172b90a799d19c01d023173e858b103b74c3edb0ecc661221c51a2b6422fb18e85d1238de83424ef636533a9c42e6671c60fbf0900e94652aac7b297946d SHA512 4d774264e3f35af75518c88a7a7a85df47d34e2a83f24b51f7372a0146c4c47ad16a6709984ca78d3f549a4d6620127131a335a7d67d69d2eaf0a8144a8a47e4 +DIST gnome-shell-extension-remove-app-menu-9.0.tar.gz 18273 BLAKE2B ad710144138a0fc38954db52214564ca2488ad627f91134871c73321961526300f524b0746ff995205ea120aa71031e95bcb8da27adcf0a53db5773792bec071 SHA512 f5dd97f2d0fe2422d595ed143619dd22d57e196fcf478122060c33d0d290258a5e1379cd32536a4672e6eb67b09e988b009da0efcee66fade25eda755df10069 +EBUILD gnome-shell-extension-remove-app-menu-9.0.ebuild 1080 BLAKE2B fda2fa31c0e30f7b8ac6c71f334f89f9fee933344fd4b65fae4b7f279ec30aa54d9bc1bd0106024041d3331c48b7d59e9d2f740ad397bbaa285c29b04d69ecef SHA512 fd443e3943a9e9a2fd541914ef19be709d72c93d49b3cc5a481e93f300c9921ea6fb07bd8b92c86c52dad2b554c912c83b5dc31051a4e06a3505de1adb486fbd diff --git a/gnome-extra/gnome-shell-extension-remove-app-menu/files/remove-app-menu-makefile-9.0.patch b/gnome-extra/gnome-shell-extension-remove-app-menu/files/remove-app-menu-makefile-9.0.patch new file mode 100644 index 0000000..e3e2c17 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-remove-app-menu/files/remove-app-menu-makefile-9.0.patch @@ -0,0 +1,38 @@ + +diff --git a/Makefile b/Makefile + +--- a/Makefile 2022-03-12 14:06:41.000000000 +0300 ++++ b/Makefile 2022-07-03 17:18:34.966377020 +0300 +@@ -4,6 +4,13 @@ + + PNG_FILES=$(wildcard ./docs/*.png) + ++ifeq ($(strip $(DESTDIR)), ) ++ INSTALL_DIR_TYPE = local ++else ++ INSTALL_DIR_TYPE = system ++ SHARE_PREFIX = $(DESTDIR)/usr/share ++endif ++ + .PHONY: build check prune compress install uninstall clean $(PNG_FILES) + + build: +@@ -20,8 +27,17 @@ + $(MAKE) $(PNG_FILES) + $(PNG_FILES): + optipng "$(COMPRESSLEVEL)" -strip all "$@" +-install: ++install: install-local ++ ++install-local: + gnome-extensions install "$(UUID).shell-extension.zip" --force ++ ++ifeq ($(INSTALL_DIR_TYPE), system) ++ mkdir -p $(SHARE_PREFIX)/gnome-shell ++ mkdir -p $(SHARE_PREFIX)/gnome-shell/extensions ++ mv $(HOME)/.local/share/gnome-shell/extensions/$(UUID) $(SHARE_PREFIX)/gnome-shell/extensions/ ++endif ++ + uninstall: + gnome-extensions uninstall "$(UUID)" + clean: diff --git a/gnome-extra/gnome-shell-extension-remove-app-menu/gnome-shell-extension-remove-app-menu-9.0.ebuild b/gnome-extra/gnome-shell-extension-remove-app-menu/gnome-shell-extension-remove-app-menu-9.0.ebuild new file mode 100644 index 0000000..ec7574d --- /dev/null +++ b/gnome-extra/gnome-shell-extension-remove-app-menu/gnome-shell-extension-remove-app-menu-9.0.ebuild @@ -0,0 +1,54 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 +inherit gnome2-utils + +MY_PN="${PN/gnome-shell-extension-/}-extension" +MY_P="${MY_PN}-${PV}" + +DESCRIPTION="Remove the application menu from the top bar" +HOMEPAGE="https://github.com/stuarthayhurst/remove-app-menu-extension" +SRC_URI="https://github.com/stuarthayhurst/${MY_PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3+" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="" + +COMMON_DEPEND="dev-libs/glib:2" +RDEPEND="${COMMON_DEPEND} + app-eselect/eselect-gnome-shell-extensions + >=gnome-base/gnome-shell-3.36 +" +DEPEND="${COMMON_DEPEND}" +BDEPEND="" + +S="${WORKDIR}/${MY_P}" +extension_uuid="RemoveAppMenu@Dragon8oy.com" + +src_prepare() { + eapply "${FILESDIR}"/remove-app-menu-makefile-9.0.patch + eapply_user +} + +src_install() { + default +} + +pkg_preinst() { + gnome2_schemas_savelist +} + +pkg_postinst() { + gnome2_schemas_update + ebegin "Updating list of installed extensions" + eselect gnome-shell-extensions update + eend $? +} + +pkg_postrm() { + gnome2_schemas_update +} + + diff --git a/gnome-extra/gnome-shell-extension-tweaks-system-menu/Manifest b/gnome-extra/gnome-shell-extension-tweaks-system-menu/Manifest new file mode 100644 index 0000000..4e1ca67 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-tweaks-system-menu/Manifest @@ -0,0 +1,6 @@ +AUX tweaks-system-menu-build-meson.patch 2564 BLAKE2B 4831129b6c9b4b316c817a9b1d1a1cfc8cd7813ae5e2ff7db5a7e509f60331cf9fe96b04652b5a430c23cae7bc6e0b623efa3a150617a75e44bd2aab35591640 SHA512 9d793bb2f678f96b3ec7fbe8fe0210a4c3abf10af6e6c61dccbbfecc311d4a819c69fd95f2bbfffe66c99b2f1f3570da97dad16df96c077eb469a56ee225c02f +AUX tweaks-system-menu-gse-build-meson.patch 2243 BLAKE2B 085b5b0651307aaff01c750d0e56fccfa38b7aa54cd32cf1c8a084a21967f96f8fc70ff4eb6584c376b88c962e87af45a782b9a6a58a41440c249d2dafe7e95c SHA512 e41227849b6d026ad47ac5d6184b25242e52d77ae944ee50d8aed5529987a976aec2976de93ec23e58b78ecede90dedf43512b4cfb32570e880bb7e77dd51d45 +AUX tweaks-system-menu-gse-meson_options.patch 297 BLAKE2B 94a9df1ba090c9272a308b5d884d661a6adfbc081a7327bf6e5eb62db3db4e669ba22afe4df91935207c697d119c51193cfb129863ddf9fdc5f36d805dc914f9 SHA512 c3fc14844402374d333c3011e125160df63ea86ba80245688ef0ecc11abb632d788dd269c7bc9c85571493c1c73d47f988dab2df793c20a046422b10ce015670 +AUX tweaks-system-menu-meson_options.patch 257 BLAKE2B 66eb68534d431eba2f3886871a894fe124d76977562a04cc401decd613df26eba9833f27f0998bc25e57db3d57c9eca75d04581728eae3d7e2950a79c72e88cc SHA512 c4d1c3b31f13f1e3f887575b9bbc493a981d0444febfd315a01b6fd4e4706e3046d3bf3ca0a5a057cd7d63be20d0582a2d199d795c756dacba5cfd7a1c1d13a9 +DIST gnome-shell-extension-tweaks-system-menu-18.tar.gz 155621 BLAKE2B 0af570b8112bf5907626b631fd92e897edacbcd7f0ccb0e7903ef315fb0d98a97ae21a519fd4e9353dfb84515916759fc47b17c50f17a9ffb2ca5205204bea87 SHA512 346b5309af290e511464e9b84ffd5f7471298009613d0806bcd2f2137795a6079a14b97e73d83ad9c337c0342778b5a7b2bf339943a83835ff530aad5a49252d +EBUILD gnome-shell-extension-tweaks-system-menu-18.ebuild 1532 BLAKE2B e7a9289aee446b8aea5a264459f3a2959e250c158001bd4d003e05f1e4c8228a6f2277b18e1ace23a3c4d7666b938ca43c95d7e356ef78b204be0c35125d0f16 SHA512 1bbec8bed4c68cedbc29d4f5886cf7b24fb8ff3e03f2fe8da5061f4a7b3917100f22c39d483237e7ee25d77a82b5da45a3bc0d9aa3ffaca023e6c93499dea650 diff --git a/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-build-meson.patch b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-build-meson.patch new file mode 100644 index 0000000..8770bfe --- /dev/null +++ b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-build-meson.patch @@ -0,0 +1,69 @@ + +diff --git a/meson.build b/meson.build + +--- a/meson.build 2022-03-13 02:03:28.000000000 +0300 ++++ b/meson.build 2022-07-03 00:10:51.622845000 +0300 +@@ -43,6 +43,15 @@ + gnome = import('gnome') + i18n = import('i18n') + ++if get_option('local_install').auto() ++ gse_local_install = false ++ if get_option('prefix') == '/usr/local' ++ gse_local_install = run_command(find_program('id'), '-u').stdout().strip() != '0' ++ endif ++else ++ gse_local_install = get_option('local_install').enabled() ++endif ++ + gse_lib_convenience = files('meson-gse/lib/convenience.js') + gse_lib_logger = files('meson-gse/lib/logger.js') + +@@ -69,6 +78,7 @@ + gse_schemas += files(gse_schema_main) + endif + ++gse_js91 = find_program('js91', required: false) + gse_js78 = find_program('js78', required: false) + gse_js68 = find_program('js68', required: false) + gse_js60 = find_program('js60', required: false) +@@ -84,17 +94,28 @@ + # End of extension-specific settings + + # Boilerplate +-gse_run_command_obj = run_command('sh', '-c', 'echo $HOME') +-if gse_run_command_obj.returncode() != 0 +- error('HOME not found, exit=@0@'.format(gse_run_command_obj.returncode())) +-endif +-home = gse_run_command_obj.stdout().strip() +- +-gse_uuid = meson.project_name() + '@extensions.gnome-shell.fifi.org' +-gse_target_dir = home + '/.local/share/gnome-shell/extensions/' + gse_uuid +-gse_target_dir_schemas = join_paths(gse_target_dir, 'schemas') +-gse_target_locale_dir = join_paths(gse_target_dir, 'locale') +-gse_target_dir_dbus_intf = join_paths(gse_target_dir, 'dbus-interfaces') ++if gse_local_install ++ gse_run_command_obj = run_command('sh', '-c', 'echo $HOME') ++ if gse_run_command_obj.returncode() != 0 ++ error('HOME not found, exit=@0@'.format(gse_run_command_obj.returncode())) ++ endif ++ prefix = gse_run_command_obj.stdout().strip() / '.local' ++else ++ prefix = get_option('prefix') ++endif ++ ++gse_uuid = meson.project_name() + '@extensions.gnome-shell.fifi.org' ++gse_target_dir = prefix + '/share/gnome-shell/extensions/' + gse_uuid ++ ++if gse_local_install ++ gse_target_dir_schemas = join_paths(gse_target_dir, 'schemas') ++ gse_target_locale_dir = join_paths(gse_target_dir, 'locale') ++ gse_target_dir_dbus_intf = join_paths(gse_target_dir, 'dbus-interfaces') ++else ++ gse_target_dir_schemas = prefix / get_option('datadir') / 'glib-2.0' / 'schemas' ++ gse_target_locale_dir = prefix / get_option('localedir') ++ gse_target_dir_dbus_intf = join_paths(gse_target_dir, 'dbus-interfaces') ++endif + + meson_extra_scripts = 'meson-gse/meson-scripts' + diff --git a/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-build-meson.patch b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-build-meson.patch new file mode 100644 index 0000000..5ca60f4 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-build-meson.patch @@ -0,0 +1,58 @@ + +diff --git a/meson-gse/meson.build.m4 b/meson-gse/meson.build.m4 + +--- a/meson-gse/meson.build.m4 2022-03-13 02:03:28.000000000 +0300 ++++ b/meson-gse/meson.build.m4 2022-07-03 10:19:07.080321000 +0300 +@@ -63,6 +63,15 @@ + gnome = import('gnome') + i18n = import('i18n') + ++if get_option('local_install').auto() ++ gse_local_install = false ++ if get_option('prefix') == '/usr/local' ++ gse_local_install = run_command(find_program('id'), '-u').stdout().strip() != '0' ++ endif ++else ++ gse_local_install = get_option('local_install').enabled() ++endif ++ + gse_lib_convenience = files('meson-gse/lib/convenience.js') + gse_lib_logger = files('meson-gse/lib/logger.js') + +@@ -97,17 +106,28 @@ + # End of extension-specific settings + + # Boilerplate +-gse_run_command_obj = run_command('sh', '-c', 'echo $HOME') +-if gse_run_command_obj.returncode() != 0 +- error('HOME not found, exit=@0@'.format(gse_run_command_obj.returncode())) ++if gse_local_install ++ gse_run_command_obj = run_command('sh', '-c', 'echo $HOME') ++ if gse_run_command_obj.returncode() != 0 ++ error('HOME not found, exit=@0@'.format(gse_run_command_obj.returncode())) ++ endif ++ prefix = gse_run_command_obj.stdout().strip() / '.local' ++else ++ prefix = get_option('prefix') + endif +-home = gse_run_command_obj.stdout().strip() + + gse_uuid = meson.project_name() + '@$2' +-gse_target_dir = home + '/.local/share/gnome-shell/extensions/' + gse_uuid +-gse_target_dir_schemas = join_paths(gse_target_dir, 'schemas') +-gse_target_locale_dir = join_paths(gse_target_dir, 'locale') +-gse_target_dir_dbus_intf = join_paths(gse_target_dir, 'dbus-interfaces') ++gse_target_dir = prefix + '/share/gnome-shell/extensions/' + gse_uuid ++ ++if gse_local_install ++ gse_target_dir_schemas = join_paths(gse_target_dir, 'schemas') ++ gse_target_locale_dir = join_paths(gse_target_dir, 'locale') ++ gse_target_dir_dbus_intf = join_paths(gse_target_dir, 'dbus-interfaces') ++else ++ gse_target_dir_schemas = prefix / get_option('datadir') / 'glib-2.0' / 'schemas' ++ gse_target_locale_dir = prefix / get_option('localedir') ++ gse_target_dir_dbus_intf = join_paths(gse_target_dir, 'dbus-interfaces') ++endif + + meson_extra_scripts = 'meson-gse/meson-scripts' + diff --git a/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-meson_options.patch b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-meson_options.patch new file mode 100644 index 0000000..a99bb22 --- /dev/null +++ b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-gse-meson_options.patch @@ -0,0 +1,9 @@ + +diff --git a/meson-gse/meson_options.txt b/meson-gse/meson_options.txt + +--- a/meson-gse/meson_options.txt 2022-07-03 09:46:05.402049000 +0300 ++++ b/meson-gse/meson_options.txt 2022-07-02 21:36:21.250190000 +0300 +@@ -0,0 +1,3 @@ ++option('local_install', ++ type: 'feature', ++ value : 'auto') diff --git a/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-meson_options.patch b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-meson_options.patch new file mode 100644 index 0000000..3ca3bfc --- /dev/null +++ b/gnome-extra/gnome-shell-extension-tweaks-system-menu/files/tweaks-system-menu-meson_options.patch @@ -0,0 +1,9 @@ + +diff --git a/meson_options.txt b/meson_options.txt + +--- a/meson_options.txt 2022-07-03 09:46:05.402049893 +0300 ++++ b/meson_options.txt 2022-07-02 21:36:21.250190000 +0300 +@@ -0,0 +1,3 @@ ++option('local_install', ++ type: 'feature', ++ value : 'auto') diff --git a/gnome-extra/gnome-shell-extension-tweaks-system-menu/gnome-shell-extension-tweaks-system-menu-18.ebuild b/gnome-extra/gnome-shell-extension-tweaks-system-menu/gnome-shell-extension-tweaks-system-menu-18.ebuild new file mode 100644 index 0000000..6c65f2c --- /dev/null +++ b/gnome-extra/gnome-shell-extension-tweaks-system-menu/gnome-shell-extension-tweaks-system-menu-18.ebuild @@ -0,0 +1,71 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 +inherit gnome2-utils meson + +MY_PN="${PN/gnome-shell-extension-/}" + +DESCRIPTION="Put Gnome Tweaks and Extensions (on Shell 40 and later) in the System menu" +HOMEPAGE="https://github.com/F-i-f/tweaks-system-menu" +SRC_URI="https://github.com/F-i-f/${MY_PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3+" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="" + +COMMON_DEPEND="dev-libs/glib:2" +RDEPEND="${COMMON_DEPEND} + app-eselect/eselect-gnome-shell-extensions + >=gnome-base/gnome-shell-40.0 +" +DEPEND="${COMMON_DEPEND}" +BDEPEND=" + virtual/pkgconfig + >=dev-util/meson-0.50.0 +" + +S="${WORKDIR}/${MY_PN}-${PV}" +extension_uuid="tweaks-system-menu@extensions.gnome-shell.fifi.org" + + +src_prepare() { + eapply "${FILESDIR}"/${MY_PN}-build-meson.patch + eapply "${FILESDIR}"/${MY_PN}-gse-build-meson.patch + eapply "${FILESDIR}"/${MY_PN}-meson_options.patch + eapply "${FILESDIR}"/${MY_PN}-gse-meson_options.patch + eapply_user +} + +src_configure() { + meson_src_configure +} + +src_compile() { + meson_src_compile +} + +src_install() { + meson_src_install + + # Install schemas system-wide + dodir /usr/share/glib-2.0/schemas + rm "${ED}/usr/share/glib-2.0/schemas/gschemas.compiled" || die +} + +pkg_preinst() { + gnome2_schemas_savelist +} + +pkg_postinst() { + gnome2_schemas_update + ebegin "Updating list of installed extensions" + eselect gnome-shell-extensions update + eend $? +} + +pkg_postrm() { + gnome2_schemas_update +} + diff --git a/metadata/layout.conf b/metadata/layout.conf new file mode 100644 index 0000000..3fb1bc6 --- /dev/null +++ b/metadata/layout.conf @@ -0,0 +1,15 @@ +# Slave repository rather than stand-alone +masters = gentoo + +# Use thin manifests +thin-manifests = true + +# Dont sign thin manifests. There is no current policy for git commit signing +sign-manifests = false + +# Make egencache generate newer (more reliable) +# md5-dict cache format +cache-formats = md5-dict + +# Support package.* directories as well as files +profile-formats = portage-2 diff --git a/net-misc/yandex-disk/Manifest b/net-misc/yandex-disk/Manifest new file mode 100644 index 0000000..1794e9f --- /dev/null +++ b/net-misc/yandex-disk/Manifest @@ -0,0 +1,2 @@ +DIST yandex-disk-0.1.6.1080-1.fedora.i386.rpm 4613067 BLAKE2B 1d893b0420d6146aea7d10d4603c28fccd6e6c93eb3c6c414d5c91b3ebd77dd770fc20445b5c0e5892994a32d9fdfa18d3aa5cc011be3894381e63b833b76630 SHA512 68f8952556b822d1de0b99827f4667257caab8ff3c744c280da682d7bf9647877dcbad5547946f92d230bd8dd27b50f5695e5af6cdd6c8c4ed20ca22cbe5e914 +DIST yandex-disk-0.1.6.1080-1.fedora.x86_64.rpm 4799367 BLAKE2B cc0fabe1479c0c66b06dd7fab943de32e1ad9477b3c03bc39c0859ba5b802bad8909d721b5fc2445943e86213bcc9ce68bf5f37eb6c151d5c211243176ae126c SHA512 d0845a825b1d4db773947c1101fa6aee38df43167486e4fae1d2db1e7fc7a49326882848eb742b069b3b2f6c1e9d617f6203dd8a3f67dd136dfa1f7bc1c8bfea diff --git a/net-misc/yandex-disk/yandex-disk-0.1.6.1080_p1.ebuild b/net-misc/yandex-disk/yandex-disk-0.1.6.1080_p1.ebuild new file mode 100644 index 0000000..b8c324f --- /dev/null +++ b/net-misc/yandex-disk/yandex-disk-0.1.6.1080_p1.ebuild @@ -0,0 +1,50 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +inherit bash-completion-r1 rpm + +MY_P="${PN}-${PV/_p/-}" + +DESCRIPTION="CLI to access Yandex Disk file storage service" +HOMEPAGE="https://disk.yandex.ru" +SRC_URI=" + amd64? ( https://repo.yandex.ru/yandex-disk/rpm/stable/x86_64/${MY_P}.fedora.x86_64.rpm ) + x86? ( https://repo.yandex.ru/yandex-disk/rpm/stable/i386/${MY_P}.fedora.i386.rpm ) +" + +LICENSE="YDSLA" +SLOT="0" +KEYWORDS="-* ~amd64 ~x86" + +DEPEND="app-arch/gzip" +RDEPEND="sys-libs/zlib" + +S="${WORKDIR}" + +QA_PREBUILT="opt/bin/yandex-disk" + +src_prepare() { + # bug #526312 + sed -i \ + -e '/have /d' \ + -e 's/+o nospace/-o nospace/' \ + -e '/^complete/s/-X //' \ + etc/bash_completion.d/yandex-disk-completion.bash || die + + # Uncompress man pages to prevent QA warnings, bug #731684 + find usr/share/man -type f -name *.gz | xargs gunzip + + eapply_user +} + +src_install() { + exeinto /opt/bin + doexe usr/bin/yandex-disk + newbashcomp etc/bash_completion.d/yandex-disk-completion.bash "${PN}" + insinto /usr/share/man + doins -r usr/share/man/* + insinto /usr/share + doins -r usr/share/locale +} diff --git a/net-wireless/rtl88x2bu/Manifest b/net-wireless/rtl88x2bu/Manifest new file mode 100644 index 0000000..6ecd047 --- /dev/null +++ b/net-wireless/rtl88x2bu/Manifest @@ -0,0 +1,4 @@ +DIST rtl88x2bu-20211010.tar.gz 4029432 BLAKE2B d94c623f746c8d3ecc235d06b16c1b266017f4aa0f558d8c64095b943c3595f040979e444f95623589ac468dd86ba3365fcffa90e5f362b58a50b2637f8fd0ec SHA512 5b75b7d9529efab3f6c53278f5b3399f228bb6de63f8fdf79a80f8b8482ce50a15a82d8ed4af58a50218657346eead4d3ad367e06d2542d0b2e5c2767f7e6879 +DIST rtl88x2bu-20220523.tar.gz 4029989 BLAKE2B 11a37518810412d16156aa76d58031e2da8547cb76ed7d1bcf1df97fe2ed1f02aeec109a273c75e8a25ef5647b0cec1f4332fd6c8a6bc6fa4264215d7b6845ea SHA512 a084fc8fd20e48e777e5ff8813d28dc0ed7935e7bcc6cd2cb404f4f700cdfb6a1aa1fe171685bd1661386885aa1f0f4571d9b57d93ce7743499b750e1e195a3a +EBUILD rtl88x2bu-20211010.ebuild 934 BLAKE2B 002be5bc5f70417e4c41011c0f9921dce368b85b0dd344ee4bf0857151a50f70ff4232bab309f071fa062d8331279febeefc8895c8107bee18cb0911089f838f SHA512 37f48027ae8c3af0617eb68e1911dc1e69f2025d0dec389499d161e20aef0ddbd3744e9aeab726208bada9885861791c8916e3495f1efb2ec7e7a62b4d67d8ed +EBUILD rtl88x2bu-20220523.ebuild 966 BLAKE2B 6acdb78643321286cb738ff87447710e28999c425d1084eab2db26d1908ca2604e690a0f65746378b363cf801fd83b7d55dac20c5dbfb21012bf0a1f1c7a9f28 SHA512 eb480d1641a8187b1f48fb3b8132e10cb230b061b9e27b971c072ffa51ad21532157f670c0f54c3ac974847c7e000825bec6017ff9a4755096b3ca3e65b05ead diff --git a/net-wireless/rtl88x2bu/rtl88x2bu-20211010.ebuild b/net-wireless/rtl88x2bu/rtl88x2bu-20211010.ebuild new file mode 100644 index 0000000..d153c7c --- /dev/null +++ b/net-wireless/rtl88x2bu/rtl88x2bu-20211010.ebuild @@ -0,0 +1,47 @@ +# Copyright 2021 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +inherit linux-mod + +COMMIT="e8ad266af883b60e88012957e89bf361924ea5ec" + +DESCRIPTION="rtl88x2bu driver updated for current kernels" +HOMEPAGE="https://github.com/cilynx/rtl88x2bu" +SRC_URI="https://github.com/cilynx/rtl88x2bu/archive/${COMMIT}.tar.gz -> rtl88x2bu-${PV}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64" + +RDEPEND="virtual/linux-sources" +DEPEND="${RDEPEND}" + +S="${WORKDIR}/rtl88x2bu-${COMMIT}" + +MODULE_NAMES="88x2bu(net/wireless)" +BUILD_TARGETS="all" +BUILD_TARGET_ARCH="${ARCH}" + +pkg_setup() { + if ! use kernel_linux ; then + die "Unable to install" + fi + + linux-mod_pkg_setup + BUILD_PARAMS="KERN_DIR=${KV_DIR} KSRC=${KV_DIR} KERN_VER=${KV_FULL} O=${KV_OUT_DIR} V=1 KBUILD_VERBOSE=1" +} + +src_compile(){ + linux-mod_src_compile +} + +src_install() { + linux-mod_src_install +} + +pkg_postinst() { + linux-mod_pkg_postinst +} + diff --git a/net-wireless/rtl88x2bu/rtl88x2bu-20220523.ebuild b/net-wireless/rtl88x2bu/rtl88x2bu-20220523.ebuild new file mode 100644 index 0000000..b50d125 --- /dev/null +++ b/net-wireless/rtl88x2bu/rtl88x2bu-20220523.ebuild @@ -0,0 +1,48 @@ +# Copyright 2022 Calculate Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +inherit linux-mod + +COMMIT="9957138ac30529a06bfcbc36eb51006a948b0967" + +DESCRIPTION="rtl88x2bu driver updated for current kernels" +HOMEPAGE="https://github.com/cilynx/rtl88x2bu" +SRC_URI="https://github.com/cilynx/rtl88x2bu/archive/${COMMIT}.tar.gz -> rtl88x2bu-${PV}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64" +IUSE="dist-kernel" + +RDEPEND="virtual/linux-sources" +DEPEND="${RDEPEND}" + +S="${WORKDIR}/rtl88x2bu-${COMMIT}" + +MODULE_NAMES="88x2bu(net/wireless)" +BUILD_TARGETS="clean modules" +BUILD_TARGET_ARCH="${ARCH}" + +pkg_setup() { + if ! use kernel_linux ; then + die "Unable to install" + fi + + linux-mod_pkg_setup + BUILD_PARAMS="KERN_DIR=${KV_DIR} KSRC=${KV_DIR} KERN_VER=${KV_FULL} O=${KV_OUT_DIR} V=1 KBUILD_VERBOSE=1" +} + +src_compile(){ + linux-mod_src_compile +} + +src_install() { + linux-mod_src_install +} + +pkg_postinst() { + linux-mod_pkg_postinst +} + diff --git a/profiles/CLDG/amd64/20/calculate.env b/profiles/CLDG/amd64/20/calculate.env new file mode 100644 index 0000000..7e8a26d --- /dev/null +++ b/profiles/CLDG/amd64/20/calculate.env @@ -0,0 +1,3 @@ +[main] +cl_template_location = calculate,distros,gnome-distro,local,remote +cl_template_path = /var/db/repos/calculate/profiles/templates,/var/db/repos/distros/profiles/templates,/var/db/repos/gnome-distro/profiles/templates,/var/calculate/templates,/var/calculate/remote/templates diff --git a/profiles/CLDG/amd64/20/parent b/profiles/CLDG/amd64/20/parent new file mode 100644 index 0000000..42d0e62 --- /dev/null +++ b/profiles/CLDG/amd64/20/parent @@ -0,0 +1,2 @@ +calculate:default/amd64/20/desktop +../.. diff --git a/profiles/CLDG/amd64/parent b/profiles/CLDG/amd64/parent new file mode 100644 index 0000000..410f9d0 --- /dev/null +++ b/profiles/CLDG/amd64/parent @@ -0,0 +1,2 @@ +../../../../calculate/profiles/default/amd64/18/desktop +.. diff --git a/profiles/CLDG/calculate.env b/profiles/CLDG/calculate.env new file mode 100644 index 0000000..8a9bafc --- /dev/null +++ b/profiles/CLDG/calculate.env @@ -0,0 +1,6 @@ +[main] +os_linux_name = 'Calculate Linux Desktop' +os_linux_subname = 'GNOME' +os_linux_shortname = CLDG +[update] +cl_update_with_bdeps_set = on diff --git a/profiles/CLDG/make.defaults b/profiles/CLDG/make.defaults new file mode 100644 index 0000000..690b993 --- /dev/null +++ b/profiles/CLDG/make.defaults @@ -0,0 +1,3 @@ +# Calculate Linux Gnome +USE="-systemd -consolekit" +THEMES="CLDG" diff --git a/profiles/CLDG/package.accept_keywords b/profiles/CLDG/package.accept_keywords new file mode 100644 index 0000000..c35e27a --- /dev/null +++ b/profiles/CLDG/package.accept_keywords @@ -0,0 +1,4 @@ +# required by net-wireless/rtl88x2bu (argument) +=net-wireless/rtl88x2bu-20220523 ~amd64 +# required by sys-power/power-profiles-daemon (argument) +=sys-power/power-profiles-daemon-0.11.1 ~amd64 diff --git a/profiles/CLDG/package.mask b/profiles/CLDG/package.mask new file mode 100644 index 0000000..c91cfcc --- /dev/null +++ b/profiles/CLDG/package.mask @@ -0,0 +1,5 @@ +# gnome-base/gnome-control-center +>=gnome-base/gnome-control-center-43.1 + +# x11-terms/gnome-terminal +>=x11-terms/gnome-terminal-3.46.3 diff --git a/profiles/CLDG/package.use b/profiles/CLDG/package.use new file mode 100644 index 0000000..8010239 --- /dev/null +++ b/profiles/CLDG/package.use @@ -0,0 +1,124 @@ +# Calculate +sys-apps/calculate-utils client qt5 + +# GNOME + +# Recommended by Gentoo Foundation + +# Copyright 1999-2021 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# Mart Raudsepp (2022-01-05) +# gnome-boxes requires spice-gtk[vala] +# net-misc/spice-gtk vala + +# Mart Raudsepp (2021-08-13) +# evolution-data-server requires libical[vala] and libgdata[vala] by default +# dev-libs/libical vala +# dev-libs/libgdata vala + +# Marek Szuba (2021-03-18) +# FUSE cannot be built with multiple audio drivers, and desktop/gnome +# profiles set both USE=pulseaudio (directly) and USE=alsa (inherited +# from desktop). Default to the latter for now because PulseAudio support +# in FUSE is currently considered experimental. +# app-emulation/fuse -pulseaudio + +# REQUIRED_USE constraint when pulseaudio is enabled +# dev-libs/efl sound + +# Needed by gnome-photos +# media-libs/gegl raw + +# Needed by a global USE=wayland right now; some REQUIRED_USE may be outdated and need review +# >=media-libs/cogl-1.18.2-r1 gles2 +# >=media-libs/clutter-1.20 egl +# media-libs/cogl kms +# media-libs/libsdl2 gles2 + +# Needed by mutter defaults and USE=wayland, bug #547300 +>=media-libs/mesa-10.3 gbm gles2 + +# For eautoreconf in =app-crypt/seahorse-3.10.2-r1 +# app-crypt/gcr vala + +# Required by folks, needed by empathy +# >=gnome-extra/evolution-data-server-3.8 vala + +# Required for cheese in gnome3 +# >=media-libs/gst-plugins-base-1.0 theora + +# Required for gnome-base/gnome-2.32 to be merged directly, for +# gnome-extra/hamster-applet-2.32 and x11-misc/alacarte-0.13 +# dev-lang/python sqlite + +# Required by app-accessibility/orca-3 +# app-accessibility/speech-dispatcher python + +# Pulled in by grilo-plugins which is needed for gnome-music +# media-libs/grilo playlist + +# Pulled in by tracker and grilo-plugins, has REQUIRED_USE="?? ( gtk qt5 )" +# media-libs/libmediaart gtk -qt5 + +# For gnome-boxes +# net-misc/spice-gtk gtk3 + +# Recommended by Adrian. URI https://github.com/aaaaadrien/adrien-overlay + +# Extra by Adrien +gnome-extra/evolution-data-server oauth + +# Elogind +# net-misc/networkmanager -elogind +# media-sound/pulseaudio elogind + +# GNOME without games by default +gnome-base/gnome-extra-apps -games + +# GNOME Software only for extensions - Пакет не установлен +# gnome-extra/gnome-software -firmware + +# Garde binaires +net-libs/webkit-gtk -gnome-keyring +www-client/chromium -gnome-keyring +media-gfx/gimp -gnome +media-video/vlc -gnome-keyring + +# Recommended by Jksf + +# Transmission +net-p2p/transmission -qt5 gtk + +# Recommended USE +gnome-base/nautilus gnome +gnome-base/gvfs gnome-online-accounts +dev-vcs/git gnome-keyring +net-libs/libproxy gnome +net-misc/remmina gnome-keyring +net-libs/glib-networking gnome +net-libs/gnome-online-accounts gnome + +# Пакет может не собираться с USE = gnome +x11-wm/mutter gnome + +x11-misc/xdg-utils gnome +x11-themes/adwaita-qt gnome +x11-terms/gnome-terminal gnome-shell nautilus + +# Происходит циклическая зависимость пакетов с USE = gnome +media-libs/libcanberra -gnome sound + +media-plugins/grilo-plugins gnome-online-accounts +sys-auth/polkit gtk +sys-auth/pambase gnome-keyring +sys-apps/gnome-disk-utility gnome +app-cdr/brasero nautilus tracker +app-arch/file-roller nautilus +app-text/evince gnome gnome-keyring nautilus +app-admin/system-config-printer gnome-keyring +virtual/notification-daemon gnome + +# For game +sys-kernel/calculate-sources fsync + diff --git a/profiles/CLDG/parent b/profiles/CLDG/parent new file mode 100644 index 0000000..f3229c5 --- /dev/null +++ b/profiles/CLDG/parent @@ -0,0 +1 @@ +.. diff --git a/profiles/arch.list b/profiles/arch.list new file mode 100644 index 0000000..21d5bd8 --- /dev/null +++ b/profiles/arch.list @@ -0,0 +1 @@ +amd64 diff --git a/profiles/calculate.env b/profiles/calculate.env new file mode 100644 index 0000000..9bc8fa8 --- /dev/null +++ b/profiles/calculate.env @@ -0,0 +1,7 @@ +[main] +cl_template_location = calculate,distros,gnome-distro,local +cl_template_path = /var/db/repos/calculate/profiles/templates,/var/db/repos/distros/profiles/templates,/var/db/repos/gnome-distro/profiles/templates,/var/calculate/templates + +[update] +cl_update_rep_name = gentoo,calculate,distros,gnome-distro +cl_update_rep_url = https://git.calculate-linux.org/calculate/gentoo-overlay,https://git.calculate-linux.org/calculate/calculate-overlay,https://git.calculate-linux.org/calculate/distros-overlay,https://disk.yandex.ru/d/A1EbLu_OvbGxdg diff --git a/profiles/profiles.desc b/profiles/profiles.desc new file mode 100644 index 0000000..4b7220b --- /dev/null +++ b/profiles/profiles.desc @@ -0,0 +1,13 @@ +############################################# +# This is a list of valid profiles for each architecture. This file is used by +# repoman when doing a repoman scan or repoman full. +# DO NOT ADD PROFILES WITH A "die" or "exit" IN THEM OR IT KILLS REPOMAN +# +#layout: +#arch profile_directory status + + +# AMD64 Profiles +amd64 CLDG/amd64/20 stable + +# vim: set ts=8 diff --git a/profiles/repo_name b/profiles/repo_name new file mode 100644 index 0000000..24274af --- /dev/null +++ b/profiles/repo_name @@ -0,0 +1 @@ +gnome-distro diff --git a/profiles/templates/2_ac_install_merge/.calculate_directory b/profiles/templates/2_ac_install_merge/.calculate_directory new file mode 100644 index 0000000..6aa2084 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip env=install ac_install_merge==on diff --git a/profiles/templates/2_ac_install_merge/Depends/.calculate_directory b/profiles/templates/2_ac_install_merge/Depends/.calculate_directory new file mode 100644 index 0000000..dfccc15 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/Depends/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip cl_merge_pkg!= diff --git a/profiles/templates/2_ac_install_merge/Depends/gdm b/profiles/templates/2_ac_install_merge/Depends/gdm new file mode 100644 index 0000000..8c5cb09 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/Depends/gdm @@ -0,0 +1 @@ +# Calculate append=skip merge(gnome-base/gdm)!= merge=gui-libs/display-manager-init diff --git a/profiles/templates/2_ac_install_merge/README-eng.txt b/profiles/templates/2_ac_install_merge/README-eng.txt new file mode 100644 index 0000000..92d938f --- /dev/null +++ b/profiles/templates/2_ac_install_merge/README-eng.txt @@ -0,0 +1,13 @@ +# Calculate append=skip + +The ac_install_merge event: +- package installation +- package removal +- system setup* +- system installation +- Portages syncing + +*When cl-setup-system is run with the defaul '--live=off' option. + +Action: package configuration +env: install diff --git a/profiles/templates/2_ac_install_merge/README-rus.txt b/profiles/templates/2_ac_install_merge/README-rus.txt new file mode 100644 index 0000000..d1af3c7 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/README-rus.txt @@ -0,0 +1,13 @@ +# Calculate append=skip + +Событие ac_install_merge: +- установка пакета +- удаление пакета +- настройка системы* +- установка системы +- обновление портежей + +*При выполнении команды cl-setup-system со значением по умолчанию '--live=off'. + +Действие: настройка пакета +env: install \ No newline at end of file diff --git a/profiles/templates/2_ac_install_merge/gnome-base/.calculate_directory b/profiles/templates/2_ac_install_merge/gnome-base/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/2_ac_install_merge/gnome-base/gdm/.calculate_directory b/profiles/templates/2_ac_install_merge/gnome-base/gdm/.calculate_directory new file mode 100644 index 0000000..ec55664 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/gdm/.calculate_directory @@ -0,0 +1 @@ +# Calculate mergepkg()!= path=/etc name=pam.d diff --git a/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/.calculate_directory b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/.calculate_directory new file mode 100644 index 0000000..5b53f75 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/etc/gdm diff --git a/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/Default b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/Default new file mode 100644 index 0000000..3e7cbb9 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostLogin/Default @@ -0,0 +1,7 @@ +# Calculate append=replace chmod=0755 +#!/bin/sh +# PostLogin - + +#?pkg(sys-apps/calculate-utils:3[desktop])!=# +/usr/share/calculate/xdm/xdm --login +#pkg# diff --git a/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/.calculate_directory b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/.calculate_directory new file mode 100644 index 0000000..5b53f75 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/etc/gdm diff --git a/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/Default b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/Default new file mode 100644 index 0000000..83ca214 --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/gdm/PostSession/Default @@ -0,0 +1,7 @@ +# Calculate append=replace chmod=0755 +#!/bin/sh +# PostSession - + +#?pkg(sys-apps/calculate-utils:3[desktop])!=# +/usr/share/calculate/xdm/xdm --logout +#pkg# diff --git a/profiles/templates/2_ac_install_merge/gnome-base/gdm/gdm-launch-environment b/profiles/templates/2_ac_install_merge/gnome-base/gdm/gdm-launch-environment new file mode 100644 index 0000000..737891c --- /dev/null +++ b/profiles/templates/2_ac_install_merge/gnome-base/gdm/gdm-launch-environment @@ -0,0 +1,23 @@ +# Calculate +#%PAM-1.0 + +auth required pam_succeed_if.so audit quiet_success user = gdm +auth required pam_env.so +auth optional pam_permit.so + +account required pam_succeed_if.so audit quiet_success user = gdm +account optional pam_permit.so + +password required pam_deny.so + +session optional pam_loginuid.so +session optional pam_keyinit.so force revoke +session required pam_succeed_if.so audit quiet_success user = gdm + +session optional pam_permit.so +#?pkg(sys-apps/systemd)!=# +-session optional pam_systemd.so +#pkg# +#?pkg(sys-auth/elogind)!=# +-session optional pam_elogind.so +#pkg# diff --git a/profiles/templates/2_ac_install_merge/net-wireless/.calculate_directory b/profiles/templates/2_ac_install_merge/net-wireless/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/2_ac_install_merge/net-wireless/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/.calculate_directory b/profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/.calculate_directory new file mode 100644 index 0000000..f08367b --- /dev/null +++ b/profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/lib/udev name=rules.d mergepkg()!= diff --git a/profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/61-gnome-bluetooth.rules b/profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/61-gnome-bluetooth.rules new file mode 100644 index 0000000..b366b6d --- /dev/null +++ b/profiles/templates/2_ac_install_merge/net-wireless/gnome-bluetooth/61-gnome-bluetooth.rules @@ -0,0 +1,12 @@ +# Calculate +# Get access to /dev/rfkill for users +# See https://bugzilla.redhat.com/show_bug.cgi?id=514798 +# +# Updated for udev >= 154 +# http://bugs.debian.org/582188 +# https://bugzilla.redhat.com/show_bug.cgi?id=588660 + +ENV{ACL_MANAGE}=="0", GOTO="gnome_bluetooth_end" +ACTION!="add|change", GOTO="gnome_bluetooth_end" +KERNEL=="rfkill", GROUP="plugdev", MODE="0664", TAG+="udev-acl" +LABEL="gnome_bluetooth_end" diff --git a/profiles/templates/3_ac_install_live/.calculate_directory b/profiles/templates/3_ac_install_live/.calculate_directory new file mode 100644 index 0000000..7223aa3 --- /dev/null +++ b/profiles/templates/3_ac_install_live/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip env=install ac_install_live==on diff --git a/profiles/templates/3_ac_install_live/1-merge/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/.calculate_directory new file mode 100644 index 0000000..1480412 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/.calculate_directory @@ -0,0 +1 @@ +# Calculate mergepkg()!= path=/etc diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/0-custom.conf b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/0-custom.conf new file mode 100644 index 0000000..c1b7864 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/0-custom.conf @@ -0,0 +1,19 @@ +# Calculate pkg(sys-apps/calculate-utils:3[desktop])!= format=kde path=/etc/gdm name=custom.conf + +[daemon] +# Uncomment the line below to force the login screen to use Xorg +#WaylandEnable=false + +#?module(client)!=&&client.os_remote_auth!=# +AutomaticLoginEnable=false +AutomaticLogin= +#!module# +#?cl_autologin!=# +AutomaticLoginEnable=true +AutomaticLogin=#-cl_autologin-# +#!cl_autologin# +AutomaticLoginEnable=false +AutomaticLogin= +#cl_autologin# +#module# + diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/1-custom.conf b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/1-custom.conf new file mode 100644 index 0000000..db754fa --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/1-custom.conf @@ -0,0 +1,12 @@ +# Calculate format=raw path=/etc/gdm name=custom.conf append=after + +[security] + +[xdmcp] + +[chooser] + +[debug] +# Uncomment the line below to turn on debugging +#Enable=true + diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/.calculate_directory new file mode 100644 index 0000000..d75b705 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/.calculate_directory @@ -0,0 +1 @@ +# Calculate pkg(gnome-base/gnome-shell)>=40.0&&pkg(gnome-base/dconf)>=0.40.0 path=/etc/dconf diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm new file mode 100644 index 0000000000000000000000000000000000000000..c151a9d9af766d45df04a52b5a2efb78c6eebd09 GIT binary patch literal 264 zcmXwzK@I^y5Jk&qA`#XOU|}=bEi71A*|$k&NLtUNdxjI(y9Wyk!a>9ZScnr?NchF5 zjB6;K||Vsd*~t_lXBq&E$9S)h0ce7 z-Wc{J^l#uDT5ax4zRSLW{0Y9G-Lc&RzP^fFl!$6j;$q2tlf;S4y_0^boR&*vOsZ1t myo{8Ia-%XGa;KZxn8-`Mg?(m2A33cp2RKKuP39U4|NH?IOE?h# literal 0 HcmV?d00001 diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm.d/02-calculate-gdm-branding b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm.d/02-calculate-gdm-branding new file mode 100644 index 0000000..9ca1c53 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/db/gdm.d/02-calculate-gdm-branding @@ -0,0 +1,2 @@ +[org/gnome/login-screen] +logo='/usr/share/wallpapers/calculate-logo.png' diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/.calculate_directory new file mode 100644 index 0000000..d75b705 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/.calculate_directory @@ -0,0 +1 @@ +# Calculate pkg(gnome-base/gnome-shell)>=40.0&&pkg(gnome-base/dconf)>=0.40.0 path=/etc/dconf diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/gdm b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/gdm new file mode 100644 index 0000000..817afc5 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/profile/gdm @@ -0,0 +1,3 @@ +user-db:user +system-db:gdm +file-db:/usr/share/gdm/greeter-dconf-defaults diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/zzz-update-dconf b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/zzz-update-dconf new file mode 100644 index 0000000..b5b29c5 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/logo/zzz-update-dconf @@ -0,0 +1,6 @@ +# Calculate pkg(gnome-base/dconf)>=0.40.0 exec=/bin/bash + +# Обновление dconf +/usr/bin/dconf update + +true diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/.calculate_directory new file mode 100644 index 0000000..a079428 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/.calculate_directory @@ -0,0 +1 @@ +# Calculate pkg(gnome-base/gnome-shell)=>42.0,43.0 path=/usr/share/ diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/gnome-shell-theme.gresource b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/themes/dim-gray/gnome-shell/gnome-shell-theme.gresource new file mode 100644 index 0000000000000000000000000000000000000000..beb71f1aa2e4a49d2d066a2918d6554a8ad927c4 GIT binary patch literal 327345 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

Cm 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/.calculate_directory new file mode 100644 index 0000000..65d4c03 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/usr/share name=wallpapers pkg(gnome-base/gdm)>=40.0 diff --git a/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/calculate-logo.png b/profiles/templates/3_ac_install_live/1-merge/gnome-base/gdm/wallpapers/calculate-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6b40bb7f2e9bf463e1da57b2a875ae2b98cb2820 GIT binary patch literal 13314 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 E0pr&QO8@`> literal 0 HcmV?d00001 diff --git a/profiles/templates/3_ac_install_live/1-merge/gui-libs/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gui-libs/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gui-libs/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/.calculate_directory new file mode 100644 index 0000000..637ef86 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/.calculate_directory @@ -0,0 +1,2 @@ +# Calculate mergepkg()!= name=etc + diff --git a/profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/conf.d/display-manager b/profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/conf.d/display-manager new file mode 100644 index 0000000..d914ace --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/gui-libs/display-manager-init/conf.d/display-manager @@ -0,0 +1,39 @@ +# Calculate comment=# + +CHECKVT=7 + +#?module(client)!=&&client.os_remote_auth!=# +#?pkg(gnome-base/gdm)!=# +DISPLAYMANAGER="gdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)!=&&pkg(gnome-base/gdm)==# +DISPLAYMANAGER="lightdm" +START_STOP_ARGS= +#pkg# +#!module# +#?cl_autologin!=# +#?pkg(gnome-base/gdm)!=# +DISPLAYMANAGER="gdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)!=&&pkg(gnome-base/gdm)==# +DISPLAYMANAGER="lightdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)==&&pkg(gnome-base/gdm)==# +XUSER=#-cl_autologin-# +DISPLAYMANAGER="bash" +START_STOP_ARGS="--background -- /usr/bin/xautologin $XUSER $CHECKVT" +#pkg# +#!cl_autologin# +#?pkg(gnome-base/gdm)!=# +DISPLAYMANAGER="gdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)!=&&pkg(gnome-base/gdm)==# +DISPLAYMANAGER="lightdm" +START_STOP_ARGS= +#pkg# +#cl_autologin# +#module# diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/sys-apps/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/.calculate_directory new file mode 100644 index 0000000..38b058b --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/.calculate_directory @@ -0,0 +1,2 @@ +# Calculate mergepkg()!= append=skip + diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/.calculate_directory new file mode 100644 index 0000000..d032440 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/etc name=calculate diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/0-example b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/0-example new file mode 100644 index 0000000..8a06fba --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/0-example @@ -0,0 +1,18 @@ +# Calculate comment=# name=ini.env.example +#?os_install_locale_language==ru# +# Это файл настройки параметров шаблонов участвующих в настройке системы +# и профиля пользователя. +# +#os_install_locale_language# +#?os_install_locale_language!=ru# +# Any line which starts with a ; (semi-colon) or a # (hash) is a comment and +# is ignored. In this example we will use a # for commentry and a ; for parts +# of the config file that you may wish to enable +#os_install_locale_language# +#?os_install_locale_language==ru# +# Все строки, начинающиеся с ";" (точка с запятой) или "#" (хэш) являются +# комментариями, а # игнорируется. В этом примере мы будем использовать "#" +# для комментариев, а ";" для частей конфигурационного файла, которые вы +# можете включить +#os_install_locale_language# +# diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/1-example.system b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/1-example.system new file mode 100644 index 0000000..7acfec0 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/1-example.system @@ -0,0 +1,25 @@ +# Calculate comment=# name=ini.env.example append=after +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +#============================= System settings =============================== +#os_install_locale_language# +#?os_install_locale_language==ru# +#============================ Настройки системы ============================== +#os_install_locale_language# +#?os_install_locale_language==fr# +#============================ Paramètres système ============================= +#os_install_locale_language# +[system] +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Kernel and modules to be removed once sys-kernel/calculate-sources has been +# uninstalled +#os_install_locale_language# +#?os_install_locale_language==ru# +# Удалить ядро и модули при удалении пакета sys-kernel/calculate-sources +#os_install_locale_language# +#?os_install_locale_language==fr# +# Le noyau ainsi que les modules de celui-ci seront supprimés dès que le +# paquet sys-kernel/calculate-sources aura été installé +#os_install_locale_language# +; remove_old_kernel = on + + diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/2-example.theme b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/2-example.theme new file mode 100644 index 0000000..a6c4ce4 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/2-example.theme @@ -0,0 +1,324 @@ +# Calculate comment=# name=ini.env.example append=after +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +#============================== Theme settings =============================== +#os_install_locale_language# +#?os_install_locale_language==ru# +#============================== Настройки темы =============================== +#os_install_locale_language# +#?os_install_locale_language==fr# +#============================ Paramètres du thème ============================ +#os_install_locale_language# +[theme] + +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Authorization screen image. Preferred size 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==ru# +# Фоновое изображение экрана авторизации. Предпочтительный размер - 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==fr# +# Écran d’autorisation. Taille préférée : 4266x2048 +#os_install_locale_language# +; dm-login-background = /usr/share/themes/Calculate/dm-login.jpg + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Login screen image. Preferred size 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==ru# +# Фоновое изображение входа в сеанс. Предпочтительный размер - 4266х2048 +# 4266x2048. +#os_install_locale_language# +#?os_install_locale_language==fr# +# Écran d’identification. Taille préférée : 4266x2048 +#os_install_locale_language# +; dm-splash-background = /usr/share/themes/Calculate/dm-splash.jpg + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Background color on the login screen, if screen image not defined +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет фона во время входа в сеанс при отсутствии изображения +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur d’arrière-plan sur l’écran d’identification avec fond d’écran désactivé +#os_install_locale_language# +; dm-splash-color = 30648b + +#in# +#?in(os_linux_pkglist, calculate)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Live USB boot menu screen +#os_install_locale_language# +#?os_install_locale_language==ru# +# Фоновое изображение меню Live USB +#os_install_locale_language# +#?os_install_locale_language==fr# +# Écran du menu Live USB +#os_install_locale_language# +; gfxboot-background = /usr/share/themes/Calculate/gfxboot.jpg + +#in# +#?in(os_linux_pkglist, calculate)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Live USB menu selection color +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет выделения в меню Live USB +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur de sélection du menu Live USB +#os_install_locale_language# +; gfxboot-select-color = 461804 + +#in# +#?in(os_linux_pkglist, calculate)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Live USB menu text color +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет текста в Live USB меню +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur de texte du menu Live USB +#os_install_locale_language# +; gfxboot-text-color = 958490 + +#in# +#?in(os_linux_pkglist, calculate)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Live USB menu selected text color +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет выделенного текста в меню Live USB +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur du texte sélectionné du menu Live USB +#os_install_locale_language# +; gfxboot-text-highlight-color = fbcc89 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Calculate load screen image +#os_install_locale_language# +#?os_install_locale_language==ru# +# Фоновое изображения загрузчика системы +#os_install_locale_language# +#?os_install_locale_language==fr# +# Fond d’écran de chargement de Calculate +#os_install_locale_language# +; grub-background = /usr/share/themes/Calculate/grub.jpg + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Bootloader foreground/background text color if screen image defined. +# Accepted values: 'black', 'blue', 'green', 'cyan', 'red', 'magenta', +# 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет текста/фона загрузчика системы при наличии фонового изображения. +# Допустимые значения: 'black', 'blue', 'green', 'cyan', 'red', 'magenta', +# 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur de texte de premier plan / arrière-plan lors du chargement avec +# fond d’écran activé. Valeurs acceptées : 'black', 'blue', 'green', 'cyan', +# 'red', 'magenta', 'brown', 'light-gray', 'dark-gray', 'light-blue', +# 'light-green', 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +; grub-gfx-text-color = white/black + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Bootloader foreground/background selected text color if screen image +# defined. Accepted values: 'black', 'blue', 'green', 'cyan', 'red', +# 'magenta', 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет выделенного текста/фона загрузчика системы при наличии фонового +# изображения. +# Допустимые значения: 'black', 'blue', 'green', 'cyan', 'red', 'magenta', +# 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur du texte sélectionné de premier plan / arrière-plan lors du +# chargement avec fond d’écran activé. Valeurs acceptées : 'black', 'blue', +# 'green', 'cyan', 'red', 'magenta', 'brown', 'light-gray', 'dark-gray', +# 'light-blue', 'light-green', 'light-cyan', 'light-red', 'light-magenta', +# 'yellow', 'white' +#os_install_locale_language# +; grub-gfx-text-highlight-color = black/light-gray + +#in# +#?in(os_linux_pkglist, calculate)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Bootloader foreground/background text color if screen image not defined. +# Accepted values: 'black', 'blue', 'green', 'cyan', 'red', 'magenta', +# 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет текста/фона загрузчика системы при отсутствии фонового изображения. +# Допустимые значения: 'black', 'blue', 'green', 'cyan', 'red', 'magenta', +# 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur de texte de premier plan / arrière-plan lors du chargement avec +# fond d’écran désactivé. Valeurs acceptées : 'black', 'blue', 'green', +# 'cyan', 'red', 'magenta', 'brown', 'light-gray', 'dark-gray', 'light-blue', +# 'light-green', 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +; grub-text-color = white/black + +#in# +#?in(os_linux_pkglist, calculate)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Bootloader foreground/background selected text color if screen image not +# defined. Accepted values: 'black', 'blue', 'green', 'cyan', 'red', 'magenta', +# 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет выделенного текста/фона загрузчика системы при отсутствии фонового +# изображения. Допустимые значения: 'black', 'blue', 'green', 'cyan', 'red', +# 'magenta', 'brown', 'light-gray', 'dark-gray', 'light-blue', 'light-green', +# 'light-cyan', 'light-red', 'light-magenta', 'yellow', 'white' +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur du texte sélectionné de premier plan / arrière-plan lors du +# chargement avec fond d’écran désactivé. Valeurs acceptées : 'black', 'blue', +# 'green', 'cyan', 'red', 'magenta', 'brown', 'light-gray', 'dark-gray', +# 'light-blue', 'light-green', 'light-cyan', 'light-red', 'light-magenta', +# 'yellow', 'white' +#os_install_locale_language# +; grub-text-highlight-color = black/light-gray + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Desktop wallpaper. Preferred size 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==ru# +# Фоновое изображение рабочего стола. Предпочтительный размер - 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==fr# +# Fond d’écran utilisateur. Taille préférée : 4266x2048 +#os_install_locale_language# +; profile-background = /usr/share/themes/Calculate/wallpaper.jpg + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# Vertical gradient begin color for shutdown screen +#os_install_locale_language# +#?os_install_locale_language==ru# +# Начальный цвет вертикального градиента, +# используемого для фона экрана завершения работы +#os_install_locale_language# +; splash-shutdown-background-color-begin = 000000 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# Vertical gradient end color for shutdown screen +#os_install_locale_language# +#?os_install_locale_language==ru# +# Конечный цвет вертикального градиента, +# используемого для фона экрана завершения работы +#os_install_locale_language# +; splash-shutdown-background-color-end = 000000 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# Shutdown screen image. Background image preferred size is 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==ru# +# Изображение для экрана завершения работы. +# Для фонового изображения предпочтительный размер - 4266x2048 +#os_install_locale_language# +; splash-shutdown-picture = /usr/share/themes/Calculate/splash-shutdown.jpg + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# The way to display the image for shutdown screen: +# 'logo' or 'background' +#os_install_locale_language# +#?os_install_locale_language==ru# +# Способ отображения изображения для экрана завершения работы: +# логотип ('logo') или фоновое изображение ('background') +#os_install_locale_language# +; splash-shutdown-type = background + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Shutdown notification text color +#os_install_locale_language# +#?os_install_locale_language==ru# +# Цвет текста сообщения о завершении работы компьютера +#os_install_locale_language# +#?os_install_locale_language==fr# +# Couleur du texte de notification d'arrêt +#os_install_locale_language# +; splash-shutdown-text-color = ffff9c + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# Vertical gradient begin color for boot screen +#os_install_locale_language# +#?os_install_locale_language==ru# +# Начальный цвет вертикального градиента, +# используемого для фона экрана загрузки системы +#os_install_locale_language# +; splash-silent-background-color-begin = 090500 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# Vertical gradient end color for boot screen +#os_install_locale_language# +#?os_install_locale_language==ru# +# Конечный цвет вертикального градиента, +# используемого для фона экрана загрузки системы +#os_install_locale_language# +; splash-silent-background-color-end = 090500 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# Boot screen image. Background image preferred size is 4266x2048 +#os_install_locale_language# +#?os_install_locale_language==ru# +# Изображение для экрана загрузки системы. +# Для фонового изображения предпочтительный размер - 4266x2048 +#os_install_locale_language# +; splash-silent-picture = /usr/share/themes/Calculate/splash-silent.png + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru# +# The way to display the image for boot screen: +# 'logo' or 'background' +#os_install_locale_language# +#?os_install_locale_language==ru# +# Способ отображения изображения для экрана загрузки компьютера: +# логотип ('logo') или фоновое изображение ('background') +#os_install_locale_language# +; splash-silent-type = logo + +#in# diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/3-example.profile b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/3-example.profile new file mode 100644 index 0000000..56b76fa --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/3-example.profile @@ -0,0 +1,172 @@ +# Calculate comment=# name=ini.env.example append=after in(os_linux_pkglist,CLDG)!= +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +#=========================== User profile settings =========================== +#os_install_locale_language# +#?os_install_locale_language==ru# +#======================= Настройки профиля пользователя ====================== +#os_install_locale_language# +#?os_install_locale_language==fr# +#======================= Paramètres de profil utilisateur ==================== +#os_install_locale_language# +[profile] + +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Window border size +#os_install_locale_language# +#?os_install_locale_language==ru# +# Размер границы окна +#os_install_locale_language# +#?os_install_locale_language==fr# +# Épaisseur de la bordure des fenêtres +#os_install_locale_language# +; appearance-border = + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Mouse cursor theme +#os_install_locale_language# +#?os_install_locale_language==ru# +# Тема курсора мышки +#os_install_locale_language# +#?os_install_locale_language==fr# +# Thème du curseur de la souris +#os_install_locale_language# +; appearance-cursor = Calculate + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Icon theme +#os_install_locale_language# +#?os_install_locale_language==ru# +# Тема иконок +#os_install_locale_language# +#?os_install_locale_language==fr# +# Thème des icônes +#os_install_locale_language# +; appearance-icons = Calculate + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Look and feel +#os_install_locale_language# +#?os_install_locale_language==ru# +# Внешний вид +#os_install_locale_language# +#?os_install_locale_language==fr# +# Apparence +#os_install_locale_language# +; appearance-style = + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Desktop wallpaper. To change it, we recommended to use the parameters in +# the “theme” section +#os_install_locale_language# +#?os_install_locale_language==ru# +# Фоновое изображение рабочего стола. Рекомендуется менять обои при помощи +# настройки темы в секции "theme" +#os_install_locale_language# +#?os_install_locale_language==fr# +# Fond d’écran utilisateur. Il est recommandé d’utiliser les réglages +# appropriés de la section “thème” pour changer de fond d’écran +#os_install_locale_language# +; appearance-wallpaper = + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Font size +#os_install_locale_language# +#?os_install_locale_language==ru# +# Размер шрифта +#os_install_locale_language# +#?os_install_locale_language==fr# +# Taille de la police +#os_install_locale_language# +; font-size = 10 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Keyboard delay (milliseconds) +#os_install_locale_language# +#?os_install_locale_language==ru# +# Задержка нажатия клавиш в миллисекундах +#os_install_locale_language# +#?os_install_locale_language==fr# +# Délai de frappe du clavier (millisecondes) +#os_install_locale_language# +; keyboard-delay = 330 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Keyboard repeat rate (characters per second) +#os_install_locale_language# +#?os_install_locale_language==ru# +# Частота повтора (знаков в секунду) +#os_install_locale_language# +#?os_install_locale_language==fr# +# Taux de répétition du clavier (caractères/sec) +#os_install_locale_language# +; keyboard-rate = 30 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Mouse click policy ('single' or 'double') +#os_install_locale_language# +#?os_install_locale_language==ru# +# Настройка клика мышки ('single' or 'double') +#os_install_locale_language# +#?os_install_locale_language==fr# +# Configuration du clic de la souris ('single' ou 'double') +#os_install_locale_language# +; mouse-clickpolicy = single + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Mouse double click delay (milliseconds) +#os_install_locale_language# +#?os_install_locale_language==ru# +# Задержка в миллисекундах двойного клика мышки +#os_install_locale_language# +#?os_install_locale_language==fr# +# Délai du double-clic (millisecondes) +#os_install_locale_language# +; mouse-doubleclick-delayed = 400 + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Left hand mouse configuration +#os_install_locale_language# +#?os_install_locale_language==ru# +# Настройка мышки для левшей. +#os_install_locale_language# +#?os_install_locale_language==fr# +# Configuration de la souris pour gaucher +#os_install_locale_language# +; mouse-lefthanded = off + +#in# +#?in(os_linux_pkglist, CLDG)!=# +#?os_install_locale_language!=ru&&os_install_locale_language!=fr# +# Time in seconds before the display is turned off when idle, '0' - never +#os_install_locale_language# +#?os_install_locale_language==ru# +# Время в секундах, после которого дисплей переходит в режим ожидания, '0' - +# никогда +#os_install_locale_language# +#?os_install_locale_language==fr# +# Mettre en veille après (secondes), '0', ne jamais arrêter +#os_install_locale_language# +; power-display-sleep = 16 + +#in# diff --git a/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/4-example.container b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/4-example.container new file mode 100644 index 0000000..ce2f6d8 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/sys-apps/calculate-utils/ini.example/4-example.container @@ -0,0 +1,36 @@ +# Calculate comment=# name=ini.env.example append=after ini(container.type)==desktop +#?os_install_locale_language!=ru# +#============================= Xorg settings =============================== +#os_install_locale_language# +#?os_install_locale_language==ru# +#============================ Настройки Xorg ============================== +#os_install_locale_language# +[xorg] +#?os_install_locale_language!=ru# +# virtual terminal number +#os_install_locale_language# +#?os_install_locale_language==ru# +# номер виртуального терминала +#os_install_locale_language# +; vt = 7 +#?os_install_locale_language!=ru# +# bus id for isolate video device +#os_install_locale_language# +#?os_install_locale_language==ru# +# идентификатор шины для изолирования видеокарты +#os_install_locale_language# +; busid = PCI:0:0:2:0 +#?os_install_locale_language!=ru# +# `on` for disable virtual terminal switching +#os_install_locale_language# +#?os_install_locale_language==ru# +# `on` для отключения возможности переключать виртуальные терминалы +#os_install_locale_language# +; sharevts = off +#?os_install_locale_language!=ru# +# multiuser mode +#os_install_locale_language# +#?os_install_locale_language==ru# +# многопользователейский режим +#os_install_locale_language# +; multiuser = on diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/x11-base/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/.calculate_directory new file mode 100644 index 0000000..637ef86 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/.calculate_directory @@ -0,0 +1,2 @@ +# Calculate mergepkg()!= name=etc + diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/.calculate_directory new file mode 100644 index 0000000..11ffb10 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/.calculate_directory @@ -0,0 +1 @@ +# Calculate pkg(x11-base/xorg-server)<1.20.10-r3 diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/xdm b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/xdm new file mode 100644 index 0000000..d914ace --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/conf.d/xdm @@ -0,0 +1,39 @@ +# Calculate comment=# + +CHECKVT=7 + +#?module(client)!=&&client.os_remote_auth!=# +#?pkg(gnome-base/gdm)!=# +DISPLAYMANAGER="gdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)!=&&pkg(gnome-base/gdm)==# +DISPLAYMANAGER="lightdm" +START_STOP_ARGS= +#pkg# +#!module# +#?cl_autologin!=# +#?pkg(gnome-base/gdm)!=# +DISPLAYMANAGER="gdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)!=&&pkg(gnome-base/gdm)==# +DISPLAYMANAGER="lightdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)==&&pkg(gnome-base/gdm)==# +XUSER=#-cl_autologin-# +DISPLAYMANAGER="bash" +START_STOP_ARGS="--background -- /usr/bin/xautologin $XUSER $CHECKVT" +#pkg# +#!cl_autologin# +#?pkg(gnome-base/gdm)!=# +DISPLAYMANAGER="gdm" +START_STOP_ARGS= +#pkg# +#?pkg(x11-misc/lightdm)!=&&pkg(gnome-base/gdm)==# +DISPLAYMANAGER="lightdm" +START_STOP_ARGS= +#pkg# +#cl_autologin# +#module# diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/.calculate_directory new file mode 100644 index 0000000..bed8108 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/.calculate_directory @@ -0,0 +1 @@ +# Calculate cl_ver>=3.5.2.21 append=skip diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome.xml b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome.xml new file mode 100644 index 0000000..9ff0593 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome.xml @@ -0,0 +1,97 @@ +# Calculate path=/usr/share/gnome-background-properties name=calculate-gnome.xml pkg(gnome-base/gnome-session)!= + + + +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 11 Blue.jpg)!=&&exists(/usr/share/backgrounds/calculate/Calculate Linux 11 Brown.jpg)!=# + + Calculate Linux 11 Blue_Brown + /usr/share/backgrounds/calculate/Calculate Linux 11 Blue.jpg + /usr/share/backgrounds/calculate/Calculate Linux 11 Brown.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 12 Blue.jpg)!=&&exists(/usr/share/backgrounds/calculate/Calculate Linux 12 Brown.jpg)!=# + + Calculate Linux 12 Blue_Brown + /usr/share/backgrounds/calculate/Calculate Linux 12 Blue.jpg + /usr/share/backgrounds/calculate/Calculate Linux 12 Brown.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 13 Green.jpg)!=&&exists(/usr/share/backgrounds/calculate/Calculate Linux 13 Magenta.jpg)!=# + + Calculate Linux 13 Green_Magenta + /usr/share/backgrounds/calculate/Calculate Linux 13 Green.jpg + /usr/share/backgrounds/calculate/Calculate Linux 13 Magenta.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 13 Blue.jpg)!=&&exists(/usr/share/backgrounds/calculate/Calculate Linux 13 Brown.jpg)!=# + + Calculate Linux 13 Blue_Brown + /usr/share/backgrounds/calculate/Calculate Linux 13 Blue.jpg + /usr/share/backgrounds/calculate/Calculate Linux 13 Brown.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 14.jpg)!=# + + Calculate Linux 14 + /usr/share/backgrounds/calculate/Calculate Linux 14.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 15.jpg)!=# + + Calculate Linux 15 + /usr/share/backgrounds/calculate/Calculate Linux 15.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux 17.jpg)!=# + + Calculate Linux 17 + /usr/share/backgrounds/calculate/Calculate Linux 17.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# +#?exists(/usr/share/backgrounds/calculate/Calculate Linux.jpg)!=# + + Calculate Linux + /usr/share/backgrounds/calculate/Calculate Linux.jpg + zoom + solid + #000000 + #000000 + Calculate Ltd. http://www.calculate-linux.org + +#exists# + diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/.calculate_directory b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/.calculate_directory new file mode 100644 index 0000000..3c97142 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/usr/share/backgrounds name=calculate pkg(gnome-base/gnome-session)!= diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Blue.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Blue.jpg new file mode 100644 index 0000000..ac90a76 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Blue.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_11_Blue/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Brown.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Brown.jpg new file mode 100644 index 0000000..75cb5f3 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 11 Brown.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_11_Brown/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Blue.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Blue.jpg new file mode 100644 index 0000000..08f639d --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Blue.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_12_Blue/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Brown.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Brown.jpg new file mode 100644 index 0000000..317a5d5 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 12 Brown.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_12_Brown/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Blue.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Blue.jpg new file mode 100644 index 0000000..3b99204 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Blue.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_13_Blue/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Brown.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Brown.jpg new file mode 100644 index 0000000..79203a0 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Brown.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_13_Brown/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Green.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Green.jpg new file mode 100644 index 0000000..1eeca66 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Green.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_13_Green/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Magenta.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Magenta.jpg new file mode 100644 index 0000000..373da16 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 13 Magenta.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_13_Magenta/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 14.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 14.jpg new file mode 100644 index 0000000..9b24cc1 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 14.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_14/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 15.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 15.jpg new file mode 100644 index 0000000..c91d912 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 15.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_15/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 17.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 17.jpg new file mode 100644 index 0000000..cddbb93 --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux 17.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux_17/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux.jpg b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux.jpg new file mode 100644 index 0000000..28cf10c --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate-gnome/Calculate Linux.jpg @@ -0,0 +1 @@ +# Calculate link=#-wallpaper(#-os_install_x11_resolution-#,/usr/share/wallpapers/Calculate_Linux/contents/images)-# mirror diff --git a/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate.xml.remove b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate.xml.remove new file mode 100644 index 0000000..d8ca2ad --- /dev/null +++ b/profiles/templates/3_ac_install_live/1-merge/x11-base/xorg-server/wallpapers/calculate.xml.remove @@ -0,0 +1 @@ +# Calculate path=/usr/share/gnome-background-properties name=calculate.xml append=remove diff --git a/profiles/templates/3_ac_install_live/Depends/gdm b/profiles/templates/3_ac_install_live/Depends/gdm new file mode 100644 index 0000000..e982297 --- /dev/null +++ b/profiles/templates/3_ac_install_live/Depends/gdm @@ -0,0 +1 @@ +# Calculate append=skip merge(gnome-base/gdm)!= merge=x11-base/xorg-server diff --git a/profiles/templates/3_ac_install_live/README-eng.txt b/profiles/templates/3_ac_install_live/README-eng.txt new file mode 100644 index 0000000..7380711 --- /dev/null +++ b/profiles/templates/3_ac_install_live/README-eng.txt @@ -0,0 +1,15 @@ +# Calculate append=skip + +The ac_install_live event: +- package installation (not chroot*) +- package removal (not chroot) +- system setup +- system installation +- first boot + + +*The event will not be used while the system is being built or if the package +is being installed in builder mode. + +Action: package configuration +env: install diff --git a/profiles/templates/3_ac_install_live/README-rus.txt b/profiles/templates/3_ac_install_live/README-rus.txt new file mode 100644 index 0000000..ac6202b --- /dev/null +++ b/profiles/templates/3_ac_install_live/README-rus.txt @@ -0,0 +1,14 @@ +# Calculate append=skip + +Событие ac_install_live: +- установка пакета (не chroot*) +- удаление пакета (не chroot) +- настройка системы +- установка системы +- первая загрузка + +*Событие не будет использоваться во время сборки системы или установке пакета +в builder-режиме. + +Действие: настройка пакета +env: install \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/.calculate_directory b/profiles/templates/6_ac_desktop_profile/.calculate_directory new file mode 100644 index 0000000..0af99e1 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/.calculate_directory @@ -0,0 +1 @@ +# Calculate env=desktop path=~ name= chown=#-main.ur_login-#:#-main.ur_group-# ac_desktop_profile==on diff --git a/profiles/templates/6_ac_desktop_profile/2-user/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/.calculate_directory new file mode 100644 index 0000000..6e56023 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip ur_login!=root&&ini(main.update)!=off diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/.calculate_directory new file mode 100644 index 0000000..720d52e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.cache/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.cache/.calculate_directory new file mode 100644 index 0000000..a36b2fb --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.cache/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=~/ diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.calculate_directory new file mode 100644 index 0000000..f956fac --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip mergepkg(gnome-base/gnome-session)>=40.0&&ini(update.gnome)!=off&&ini(ver.gnome)==&&exists(~/.config/gnome-session)== diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/.calculate_directory new file mode 100644 index 0000000..879d998 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/.calculate_directory @@ -0,0 +1 @@ +# Calculate name= path="#-ini(resource.desktop)-#" diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/FTP.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/FTP.desktop new file mode 100644 index 0000000..b3eb71d --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/FTP.desktop @@ -0,0 +1,9 @@ +# Calculate chmod=755 format=kde env(client.os_remote_auth)!=&&ur_domain_set==on&&server(ftp.host)!= +[Desktop Entry] +Version=1.0 +Name=FTP +Comment=Open FTP network folder +Comment[ru_RU]=Открыть сетевой диск FTP +Icon=folder-download +URL=file:////home/#-ur_login-#/FTP +Type=Link diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Home.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Home.desktop new file mode 100644 index 0000000..0d16e32 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Home.desktop @@ -0,0 +1,9 @@ +# Calculate chmod=755 format=kde env(client.os_remote_auth)!=&&ur_domain_set==on append=replace +[Desktop Entry] +Version=1.0 +Name=Home +Comment=Open home network folder +Comment[ru_RU]=Открыть сетевой диск с личными файлами +Icon=user-home +URL=file:////home/#-ur_login-#/Home +Type=Link diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/README.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/README.desktop new file mode 100644 index 0000000..e34c77f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/README.desktop @@ -0,0 +1,28 @@ +# Calculate chmod=755 os_root_type==livecd +#!/usr/bin/env xdg-open + +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Type=Application +Name[bg]=Ръководство за инсталиране +Name[ru]=Руководство по установке +Name=Installation Guide +Comment= +Categories=Application; +#?os_locale_language!=ru# +#?pkg(www-client/chromium)!=# +Exec=chromium --app="file:///usr/share/calculate/doc/handbook-en.html" +#!pkg# +Exec=xdg-open /usr/share/calculate/doc/handbook-en.html +#pkg# +#!os_locale_language# +#?pkg(www-client/chromium)!=# +Exec=chromium --app="file:///usr/share/calculate/doc/handbook-ru.html" +#!pkg# +Exec=xdg-open /usr/share/calculate/doc/handbook-ru.html +#pkg# +#os_locale_language# +Icon=help-contents +Terminal=false +StartupNotify=false diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Share.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Share.desktop new file mode 100644 index 0000000..ada005b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/Share.desktop @@ -0,0 +1,9 @@ +# Calculate chmod=755 format=kde env(client.os_remote_auth)!=&&ur_domain_set==on +[Desktop Entry] +Version=1.0 +Name=Share +Comment=Open share network folder +Comment[ru_RU]=Открыть сетевой диск с сетевыми ресурсами +Icon=folder-remote +URL=file:////home/#-ur_login-#/Share +Type=Link diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-community.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-community.desktop new file mode 100644 index 0000000..c58ec74 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-community.desktop @@ -0,0 +1 @@ +# Calculate chmod=755 format=kde link=/usr/share/applications/calculate-chat.desktop mirror os_root_type==livecd diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-install.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-install.desktop new file mode 100644 index 0000000..b65a600 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/Desktop/calculate-install.desktop @@ -0,0 +1,3 @@ +# Calculate chmod=755 format=kde link=/usr/share/applications/cl-console-gui-install.desktop os_root_type==livecd mirror +[Desktop Entry] +NoDisplay=false diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/.calculate_directory new file mode 100644 index 0000000..03067b0 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=~/.local/share diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui-update.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui-update.desktop new file mode 100644 index 0000000..8ee566d --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui-update.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Calculate Linux Update +Name[ru]=Обновление Calculate Linux +Comment=Calculate Linux updater +Exec=cl-console-gui-update +Icon=console-gui-update +Terminal=false +Type=Application +Categories=Settings;X-GNOME-PersonalSettings; +OnlyShowIn=KDE;LXQt;LXDE;MATE;Razor;ROX;TDE;Unity;XFCE;Old;GNOME +StartupNotify=true diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui.desktop b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui.desktop new file mode 100644 index 0000000..658c62f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/applications/cl-console-gui.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=Calculate Console +Name[ru]=Консоль Calculate +Comment=Calculate Console +Exec=cl-console-gui +Icon=cl-console-gui +Terminal=false +Type=Application +Categories=Settings;X-GNOME-PersonalSettings; +OnlyShowIn=KDE;LXQt;LXDE;MATE;Razor;ROX;TDE;Unity;XFCE;Old;GNOME diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/.calculate_directory new file mode 100644 index 0000000..03067b0 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=~/.local/share diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/SystemSettings.directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/SystemSettings.directory new file mode 100644 index 0000000..a416a7a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/desktop-directories/SystemSettings.directory @@ -0,0 +1,12 @@ +[Desktop Entry] +Name[en_CA]=Settings +Name[en_GB]=Settings +Name[ru]=Параметры +Name=Settings +Comment[en_CA]=Calculate system parameters +Comment[en_GB]=Calculate system parameters +Comment[ru]=Параметры системы Calculate +Comment=Calculate system parameters +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=gnome-settings +Type=Directory diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/.calculate_directory b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/.calculate_directory new file mode 100644 index 0000000..f7b3472 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=~/.local/share/gnome-shell diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/LICENSE b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/LICENSE new file mode 100644 index 0000000..be85d4e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Just Perfection GNOME Shell Desktop + Copyright (C) 2021 Javad Rahmatzadeh + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Just Perfection GNOME Shell Desktop Copyright (C) 2021 Javad Rahmatzadeh + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/extension.js new file mode 100644 index 0000000..2197908 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/extension.js @@ -0,0 +1,546 @@ +/** + * Shutdown Timer Extension for GNOME Shell + * + * @author Deminder + * @author D. Neumann + * @copyright 2014-2021 + * @license GNU General Public License v3.0 + */ +/* exported init, enable, disable */ + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { + ScheduleInfo, + MenuItem, + Textbox, + RootMode, + Timer, + Convenience, + EndSessionDialogAware, + SessionModeAware, + CheckCommand, +} = Me.imports.lib; + +const { + guiIdle, + throttleTimeout, + disableGuiIdle, + modeLabel, + enableGuiIdle, + longDurationString, + logDebug, +} = Convenience; + +/* IMPORTS */ +const { GLib } = imports.gi; +const LoginManager = imports.misc.loginManager; + +// screen and main functionality +const Main = imports.ui.main; +const PopupMenu = imports.ui.popupMenu; + +// translations +const Gettext = imports.gettext.domain('ShutdownTimer'); +const _ = Gettext.gettext; +const C_ = Gettext.pgettext; +const _n = Gettext.ngettext; + +/* GLOBAL VARIABLES */ +let shutdownTimerMenu, timer, separator, settings; + +let initialized = false; + +/** + * + */ +function refreshExternalInfo() { + if (shutdownTimerMenu !== undefined) { + shutdownTimerMenu.infoFetcher.refresh(); + } +} + +/** + * + * @param textmsg + */ +function maybeShowTextbox(textmsg) { + if (settings.get_boolean('show-textboxes-value')) { + guiIdle(() => { + Textbox.showTextbox(textmsg); + }); + } +} + +/** + * + * @param info + * @param stopScheduled + */ +async function maybeStopRootModeProtection(info, stopScheduled = false) { + if ( + (stopScheduled || !info.scheduled) && + settings.get_boolean('root-mode-value') + ) { + logDebug(`Stop root mode protection for: ${info.mode}`); + try { + switch (info.mode) { + case 'poweroff': + case 'reboot': + await RootMode.shutdownCancel(); + refreshExternalInfo(); + break; + default: + logDebug(`No root mode protection stopped for: ${info.mode}`); + } + } catch (err) { + maybeShowTextbox( + C_('Error', '%s\n%s').format(_('Root mode protection failed!'), err) + ); + logError(err, 'DisableRootModeProtection'); + } + } +} + +/** + * + * Insure that shutdown is executed even if the GLib timer fails by running + * the `shutdown` command delayed by 1 minute. Suspend is not insured. + * + * @param info + */ +async function maybeStartRootModeProtection(info) { + if (info.scheduled && settings.get_boolean('root-mode-value')) { + logDebug(`Start root mode protection for: ${info.label}`); + try { + const minutes = Math.max(0, info.minutes) + 1; + switch (info.mode) { + case 'poweroff': + await RootMode.shutdown(minutes); + refreshExternalInfo(); + break; + case 'reboot': + await RootMode.shutdown(minutes, true); + refreshExternalInfo(); + break; + default: + logDebug(`No root mode protection started for: ${info.mode}`); + } + } catch (err) { + maybeShowTextbox( + C_('Error', '%s\n%s').format(_('Root mode protection failed!'), err) + ); + logError(err, 'EnableRootModeProtection'); + } + } +} + +/** + * + * @param wakeMinutes + */ +async function maybeStartWake(wakeMinutes) { + if (settings.get_boolean('auto-wake-value')) { + await wakeAction('wake', wakeMinutes); + } +} + +/** + * + */ +async function maybeStopWake() { + if (settings.get_boolean('auto-wake-value')) { + await wakeAction('no-wake'); + } +} + +// timer action (shutdown/reboot/suspend) +/** + * + * @param mode + */ +async function serveInernalSchedule(mode) { + const checkCmd = maybeCheckCmdString(); + try { + if (checkCmd !== '') { + guiIdle(() => { + shutdownTimerMenu.checkRunning = true; + shutdownTimerMenu.updateShutdownInfo(); + }); + maybeShowTextbox(checkCmd); + maybeShowTextbox( + _('Waiting for %s confirmation').format(modeLabel(mode)) + ); + await CheckCommand.doCheck( + checkCmd, + line => { + if (!line.startsWith('[')) { + maybeShowTextbox(`'${line}'`); + } + }, + async () => { + // keep protection alive + await maybeStartRootModeProtection( + new ScheduleInfo.ScheduleInfo({ mode, deadline: 0 }) + ); + } + ); + } + // check succeeded: do shutdown + shutdown(mode); + } catch (err) { + logError(err, 'CheckError'); + // check failed: cancel shutdown + // stop root protection + await maybeStopRootModeProtection( + new ScheduleInfo.ScheduleInfo({ mode, deadline: 0 }), + true + ); + try { + const root = settings.get_boolean('root-mode-value'); + if (root) { + await RootMode.shutdownCancel(); + } + const wake = settings.get_boolean('auto-wake-value'); + if (wake) { + await RootMode.wakeCancel(); + } + if (root || wake) { + refreshExternalInfo(); + } + } catch (err2) { + // error is most likely: script not installed + logError(err2, 'CheckError'); + } + // check failed: log failure + let code = '?'; + if ('code' in err) { + code = `${err.code}`; + logDebug(`Check command aborted ${mode}. Code: ${code}`); + } + maybeShowTextbox( + C_('CheckCommand', '%s aborted (Code: %s)').format(modeLabel(mode), code) + ); + if (parseInt(code) === 19) { + maybeShowTextbox(_('Confirmation canceled')); + } + } finally { + // update shutdownTimerMenu + guiIdle(() => { + shutdownTimerMenu.checkRunning = false; + shutdownTimerMenu.updateShutdownInfo(); + }); + // reset schedule timestamp + settings.set_int('shutdown-timestamp-value', -1); + } +} + +/** + * + */ +function foregroundActive() { + // ubuntu22.04 uses 'ubuntu' as 'user' sessionMode + return Main.sessionMode.currentMode !== 'unlock-dialog'; +} + +/** + * + * @param mode + */ +function shutdown(mode) { + if (foregroundActive()) { + Main.overview.hide(); + Textbox.hideAll(); + } + + if (['reboot', 'poweroff'].includes(mode)) { + if ( + foregroundActive() && + settings.get_boolean('show-end-session-dialog-value') + ) { + // show endSessionDialog + // refresh root shutdown protection + maybeStartRootModeProtection( + new ScheduleInfo.ScheduleInfo({ mode, deadline: 0 }) + ); + EndSessionDialogAware.register(); + const session = new imports.misc.gnomeSession.SessionManager(); + if (mode === 'reboot') { + session.RebootRemote(0); + } else { + session.ShutdownRemote(0); + } + } else { + imports.misc.util.spawnCommandLine( + mode === 'reboot' ? 'reboot' : 'poweroff' + ); + } + } else if (mode === 'suspend') { + LoginManager.getLoginManager().suspend(); + } else { + logError(new Error(`Unknown shutdown mode: ${mode}`)); + } +} + +/* ACTION FUNCTIONS */ +/** + * + * @param mode + * @param minutes + */ +async function wakeAction(mode, minutes) { + try { + switch (mode) { + case 'wake': + await RootMode.wake(minutes); + refreshExternalInfo(); + return; + case 'no-wake': + await RootMode.wakeCancel(); + refreshExternalInfo(); + return; + default: + logError(new Error(`Unknown wake mode: ${mode}`)); + return; + } + } catch (err) { + maybeShowTextbox( + C_('Error', '%s\n%s').format(_('Wake action failed!'), err) + ); + } +} + +/** + * + * @param stopProtection + */ +function stopSchedule(stopProtection = true) { + EndSessionDialogAware.unregister(); + const canceled = CheckCommand.maybeCancel(); + if (!canceled && settings.get_int('shutdown-timestamp-value') > -1) { + settings.set_int('shutdown-timestamp-value', -1); + maybeShowTextbox(_('Shutdown Timer stopped')); + } + + if (stopProtection) { + // stop root protection + const info = + timer !== undefined ? timer.info : new ScheduleInfo.ScheduleInfo(); + return Promise.all([maybeStopRootModeProtection(info), maybeStopWake()]); + } + return Promise.resolve(); +} + +/** + * + * @param maxTimerMinutes + * @param wakeMinutes + */ +async function startSchedule(maxTimerMinutes, wakeMinutes) { + EndSessionDialogAware.unregister(); + CheckCommand.maybeCancel(); + + const seconds = maxTimerMinutes * 60; + const info = new ScheduleInfo.ScheduleInfo({ + mode: settings.get_string('shutdown-mode-value'), + deadline: GLib.DateTime.new_now_utc().to_unix() + Math.max(1, seconds), + }); + settings.set_int('shutdown-timestamp-value', info.deadline); + let startPopupText = C_('StartSchedulePopup', '%s in %s').format( + modeLabel(info.mode), + longDurationString( + maxTimerMinutes, + h => _n('%s hour', '%s hours', h), + m => _n('%s minute', '%s minutes', m) + ) + ); + const checkCmd = maybeCheckCmdString(); + if (checkCmd !== '') { + maybeShowTextbox(checkCmd); + } + maybeShowTextbox(startPopupText); + + // start root protection + await Promise.all([ + maybeStartRootModeProtection(info), + maybeStartWake(wakeMinutes), + ]); +} + +/** + * + */ +function maybeCheckCmdString() { + const cmd = settings + .get_string('check-command-value') + .split('\n') + .filter(line => !line.trimLeft().startsWith('#') && line.trim()) + .join('\n'); + + return settings.get_boolean('enable-check-command-value') ? cmd : ''; +} + +/** + * + * @param info + */ +function onShutdownScheduleChange(info) { + if (timer !== undefined) { + timer.adjustTo(info); + } +} + +/** + * + * @param sessionMode + */ +function onSessionModeChange(sessionMode) { + logDebug(`sessionMode: ${sessionMode}`); + switch (sessionMode) { + case 'unlock-dialog': + disableForeground(); + break; + case 'user': + default: + enableForeground(); + break; + } +} + +/** + * + */ +function enableForeground() { + enableGuiIdle(); + // add separator line and submenu in status area menu + const statusMenu = Main.panel.statusArea['aggregateMenu']; + if (separator === undefined) { + separator = new PopupMenu.PopupSeparatorMenuItem(); + statusMenu.menu.addMenuItem(separator); + } + if (shutdownTimerMenu === undefined) { + shutdownTimerMenu = new MenuItem.ShutdownTimer(); + shutdownTimerMenu.checkRunning = CheckCommand.isChecking(); + timer.setTickCallback( + shutdownTimerMenu.updateShutdownInfo.bind(shutdownTimerMenu) + ); + statusMenu.menu.addMenuItem(shutdownTimerMenu); + } + // stop schedule if endSessionDialog cancel button is activated + EndSessionDialogAware.load(stopSchedule); + logDebug('Enabled foreground.'); +} + +/** + * + */ +function disableForeground() { + disableGuiIdle(); + Textbox.hideAll(); + if (shutdownTimerMenu !== undefined) { + shutdownTimerMenu.destroy(); + if (timer !== undefined) { + timer.setTickCallback(null); + // keep sleep process alive + timer.stopForeground(); + } + } + shutdownTimerMenu = undefined; + if (separator !== undefined) { + separator.destroy(); + } + separator = undefined; + EndSessionDialogAware.unload(); + logDebug('Disabled foreground.'); +} + +/* EXTENSION MAIN FUNCTIONS */ +/** + * + */ +function init() { + // initialize translations + ExtensionUtils.initTranslations(); +} + +let throttleDisable = null; +let throttleDisableCancel = null; + +/** + * + */ +function enable() { + if (!initialized) { + [throttleDisable, throttleDisableCancel] = throttleTimeout( + completeDisable, + 100 + ); + // initialize settings + settings = ExtensionUtils.getSettings(); + // ensure that no shutdown is scheduled + settings.set_int('shutdown-timestamp-value', -1); + MenuItem.init(settings, { + wakeAction, + startSchedule, + stopSchedule, + maybeStopRootModeProtection, + maybeStartRootModeProtection, + onShutdownScheduleChange, + }); + Textbox.init(); + + // check for shutdown may run in background and can be canceled by user + // starts internal shutdown schedule if ready + timer = new Timer.Timer(serveInernalSchedule); + + SessionModeAware.load(onSessionModeChange); + + initialized = true; + } else { + throttleDisableCancel(); + } + if (foregroundActive()) { + enableForeground(); + logDebug('Completly enabled.'); + } else { + logDebug('Background enabled.'); + } +} + +/** + * + */ +function disable() { + // unlock-dialog session-mode is required such that the timer action can trigger + disableForeground(); + // DELAYED DISABLE: + // Workaround for Gnome 42 weird behaviour (?unlock-dialog sessionMode bug?): + // on first screensaver activation after login gnome-shell quickly enables/disables this extension + // for each extension that is also enabled besides this extension + if (initialized) { + throttleDisable(); + } +} + +/** + * + */ +function completeDisable() { + if (initialized) { + if (timer !== undefined) { + timer.stopTimer(); + timer = undefined; + } + Textbox.uninit(); + MenuItem.uninit(); + // clear internal schedule and keep root protected schedule + stopSchedule(false); + SessionModeAware.unload(); + + throttleDisableCancel(); + throttleDisable = null; + throttleDisableCancel = null; + initialized = false; + logDebug('Completly disabled.'); + } +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/icons/shutdown-timer-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/icons/shutdown-timer-symbolic.svg new file mode 100644 index 0000000..8e85029 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/icons/shutdown-timer-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/CheckCommand.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/CheckCommand.js new file mode 100644 index 0000000..9e684f4 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/CheckCommand.js @@ -0,0 +1,95 @@ +/** + * CheckCommand module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported doCheck, maybeCancel, isChecking */ +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { RootMode, Convenience } = Me.imports.lib; +const Gio = imports.gi.Gio; +const logDebug = Convenience.logDebug; + +let checkCancel; + +/** + * Wait for checkCmd to execute successfully. + * + * @param {string} checkCmd check command + * @param {(line: string) => void} onLog + * @param {async () => void} redoRootProtection + */ +function doCheck(checkCmd, onLog, redoRootProtection) { + if (checkCancel !== undefined) { + return Promise.reject( + new Error( + 'Confirmation canceled: attempted to start a second check command!' + ) + ); + } + + checkCancel = new Gio.Cancellable(); + const checkWatchCancel = new Gio.Cancellable(); + return Promise.all([ + _doCheck(checkCmd, checkWatchCancel, onLog), + continueRootProtectionDuringCheck(checkWatchCancel, redoRootProtection), + ]); +} +/** + * + * @param checkCmd + * @param checkWatchCancel + * @param onLog + */ +async function _doCheck(checkCmd, checkWatchCancel, onLog) { + try { + await RootMode.execCheck(checkCmd, checkCancel, true, onLog); + logDebug(`Check command "${checkCmd}" confirmed shutdown.`); + } finally { + checkCancel = undefined; + checkWatchCancel.cancel(); + } +} + +/** + * + * @param cancellable + * @param redoRootProtection + */ +async function continueRootProtectionDuringCheck( + cancellable, + redoRootProtection +) { + try { + await RootMode.execCheck(['sleep', '30'], cancellable, false); + } catch (err) { + logDebug('RootProtection during check: Canceled'); + } + if (checkCancel === undefined) { + logDebug('RootProtection during check: Done'); + } else { + await redoRootProtection(); + logDebug('RootProtection during check: Continue'); + await continueRootProtectionDuringCheck(cancellable, redoRootProtection); + } +} + +/** + * + */ +function isChecking() { + return checkCancel !== undefined && !checkCancel.is_cancelled(); +} + +/** + * + */ +function maybeCancel() { + const doCancel = isChecking(); + if (doCancel) { + checkCancel.cancel(); + } + return doCancel; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Convenience.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Convenience.js new file mode 100644 index 0000000..1db0805 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Convenience.js @@ -0,0 +1,163 @@ +/** + * Convenience module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported MODES, WAKE_MODES, modeLabel, logDebug, proxyPromise, durationString, longDurationString, disableGuiIdle, enableGuiIdle, guiIdle, throttleTimeout */ + +const { GLib } = imports.gi; +const Gettext = imports.gettext.domain('ShutdownTimer'); +const _ = Gettext.gettext; +const _n = Gettext.ngettext; + +let debugMode = false; + +/** + * + * @param {...any} args + */ +function logDebug(...args) { + if (debugMode) { + log(...args); + } +} + +var MODES = ['suspend', 'poweroff', 'reboot']; +var WAKE_MODES = ['wake', 'no-wake']; +/** + * + * @param mode + */ +function modeLabel(mode) { + return { + suspend: _('Suspend'), + poweroff: _('Power Off'), + reboot: _('Restart'), + wake: _('Wake after'), + 'no-wake': _('No Wake'), + }[mode]; +} + +/** + * + * @param ProxyType + * @param session + * @param dest + * @param objectPath + */ +function proxyPromise(ProxyType, session, dest, objectPath) { + return new Promise((resolve, reject) => { + new ProxyType(session, dest, objectPath, (proxy, error) => { + if (error) { + reject(error); + } else { + resolve(proxy); + } + }); + }); +} + +/** + * + * @param seconds + */ +function durationString(seconds) { + const sign = Math.sign(seconds); + const absSec = Math.floor(Math.abs(seconds)); + const minutes = Math.floor(absSec / 60); + const hours = Math.floor(minutes / 60); + if (hours >= 3) { + return _n('%s hour', '%s hours', hours).format(sign * hours); + } else if (minutes === 0) { + return _n('%s sec', '%s secs', absSec).format( + sign * (absSec > 5 ? 10 * Math.ceil(absSec / 10) : absSec) + ); + } + return _n('%s min', '%s mins', minutes).format(sign * minutes); +} + +/** + * + * @param minutes + * @param hrFmt + * @param minFmt + */ +function longDurationString(minutes, hrFmt, minFmt) { + const hours = Math.floor(minutes / 60); + const residualMinutes = minutes % 60; + let parts = [minFmt(residualMinutes).format(residualMinutes)]; + if (hours) { + parts = [hrFmt(hours).format(hours)].concat(parts); + } + return parts.join(' '); +} + +let idleSourceId = null; +let idleCallbacks = []; +let idleEnabled = false; + +/** + * + */ +function enableGuiIdle() { + idleEnabled = true; +} + +/** + * + */ +function disableGuiIdle() { + idleEnabled = false; + idleCallbacks = []; + if (idleSourceId) { + GLib.Source.remove(idleSourceId); + } + idleSourceId = null; +} + +/** + * + * @param callback + */ +function guiIdle(callback) { + if (idleEnabled) { + idleCallbacks.push(callback); + if (!idleSourceId) { + idleSourceId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { + for (const func of idleCallbacks) { + func(); + } + idleCallbacks = []; + idleSourceId = null; + return GLib.SOURCE_REMOVE; + }); + } + } +} + +/** + * + * @param timeoutFunc + * @param delayMillis + */ +function throttleTimeout(timeoutFunc, delayMillis) { + let current = null; + return [ + () => { + if (current === null) { + current = setTimeout(() => { + timeoutFunc(); + current = null; + }, delayMillis); + } + }, + () => { + if (current) { + clearTimeout(current); + current = null; + } + }, + ]; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/EndSessionDialogAware.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/EndSessionDialogAware.js new file mode 100644 index 0000000..dc0ac16 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/EndSessionDialogAware.js @@ -0,0 +1,113 @@ +/** + * EndSessionDialogAware module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported register, unregister, load, unload */ +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { Convenience } = Me.imports.lib; +const { Gio } = imports.gi; +const { loadInterfaceXML } = imports.misc.fileUtils; +const { proxyPromise, logDebug } = Convenience; + +const EndSessionDialogInf = loadInterfaceXML( + 'org.gnome.SessionManager.EndSessionDialog' +); +const EndSessionDialogProxy = + Gio.DBusProxy.makeProxyWrapper(EndSessionDialogInf); + +let endSessionDialog = null; +let onCancelAction = null; +let registered = false; + +/** + * + */ +function unregister() { + registered = false; +} +/** + * + */ +function register() { + registered = true; +} + +/** + * + * @param cancelAction + */ +function load(cancelAction) { + onCancelAction = cancelAction; + _update(); +} + +/** + * + */ +function unload() { + onCancelAction = null; + _update(); +} + +/** + * + */ +async function _update() { + try { + if (onCancelAction && !endSessionDialog) { + endSessionDialog = await proxyPromise( + EndSessionDialogProxy, + Gio.DBus.session, + 'org.gnome.Shell', + '/org/gnome/SessionManager/EndSessionDialog' + ); + } + if (endSessionDialog) { + if (onCancelAction === null) { + _disconnect(endSessionDialog); + endSessionDialog = null; + } else { + _connect(endSessionDialog, onCancelAction); + } + } + } catch (err) { + logError(err, 'EndSessionDialogProxyError'); + endSessionDialog = null; + } +} + +/** + * + * @param dialog + * @param cancelAction + */ +function _connect(dialog, cancelAction) { + if (!('_cancelSignalId' in dialog)) { + logDebug('Connect cancel of endSessionDialog...'); + dialog['_cancelSignalId'] = dialog.connectSignal('Canceled', () => { + logDebug( + `endSessionDialog cancel triggered. propagate registered: ${registered}` + ); + if (registered) { + cancelAction(); + } + }); + } +} + +/** + * + * @param dialog + */ +function _disconnect(dialog) { + const signalId = dialog['_cancelSignalId']; + if (signalId) { + logDebug('Disconnect cancel of endSessionDialog...'); + dialog.disconnectSignal(signalId); + delete dialog['_cancelSignalId']; + } +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/InfoFetcher.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/InfoFetcher.js new file mode 100644 index 0000000..84e5dce --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/InfoFetcher.js @@ -0,0 +1,120 @@ +/** + * InfoFetcher module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported InfoFetcher */ + +const { Gio, GLib } = imports.gi; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { Convenience } = Me.imports.lib; +const { logDebug, throttleTimeout } = Convenience; +const ByteArray = imports.byteArray; + +/** + * + * @param path + */ +function readFile(path) { + return new Promise((resolve, reject) => { + try { + const file = Gio.File.new_for_path(path); + file.load_contents_async(null, (f, res) => { + try { + const [, contents] = f.load_contents_finish(res); + resolve(ByteArray.toString(contents)); + GLib.free(contents); + } catch (err) { + reject(err); + } + }); + } catch (err) { + reject(err); + } + }); +} + +/** + * + */ +async function isWakeInfoLocal() { + const content = await readFile('/etc/adjtime').catch(() => ''); + return content.trim().toLowerCase().endsWith('local'); +} + +/** + * + * @param rtc + */ +async function wakeInfo(rtc) { + const content = await readFile(`/sys/class/rtc/${rtc}/wakealarm`).catch( + () => '' + ); + let timestamp = content !== '' ? parseInt(content) : -1; + if (timestamp > -1 && (await isWakeInfoLocal())) { + const dt = GLib.DateTime.new_from_unix_local(timestamp); + timestamp = dt.to_unix() - dt.get_utc_offset() / 1000000; + dt.unref(); + } + return { deadline: timestamp }; +} + +/** + * + */ +async function shutdownInfo() { + try { + const content = await readFile('/run/systemd/shutdown/scheduled'); + // content: schedule unix-timestamp (micro-seconds), warn-all, shutdown-mode + const [usec, _, mode] = content.split('\n').map(l => l.split('=')[1]); + return { + mode, + deadline: parseInt(usec) / 1000000, + }; + } catch { + return { deadline: -1 }; + } +} + +var InfoFetcher = class { + constructor(onFetch) { + this._infoTimerId = null; + this._pending = false; + this._rtc = 'rtc0'; + this._onFetch = onFetch; + [this.refresh, this._cancelRefresh] = throttleTimeout( + this._refresh.bind(this), + 300 + ); + this.refresh(); + } + + _refresh() { + logDebug('Extra info refresh...'); + this.stop(); + // restart loop + this._infoTimerId = setInterval(this.tick.bind(this), 5000); + this.tick(); + } + + stop() { + if (this._infoTimerId !== null) { + clearInterval(this._infoTimerId); + } + this._cancelRefresh(); + } + + tick() { + if (!this._pending) { + this._pending = true; + Promise.all([shutdownInfo(), wakeInfo(this._rtc)]).then( + ([schedule, wake]) => { + this._onFetch(schedule, wake); + this._pending = false; + } + ); + } + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Install.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Install.js new file mode 100644 index 0000000..860f38d --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Install.js @@ -0,0 +1,89 @@ +/** + * Install module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported installAction, checkInstalled, reset, actionLabel */ + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { Convenience, RootMode } = Me.imports.lib; +const logDebug = Convenience.logDebug; + +const { Gio } = imports.gi; +// translations +const Gettext = imports.gettext.domain('ShutdownTimer'); +const _ = Gettext.gettext; + +let installCancel; + +/** + * + * @param action + * @param logInstall + */ +function installAction(action, logInstall) { + if (installCancel !== undefined) { + logDebug('Trigger cancel install.'); + installCancel.cancel(); + } else { + logDebug(`Trigger ${action} action.`); + installCancel = new Gio.Cancellable(); + _installAction(action, logInstall, installCancel).finally(() => { + installCancel = undefined; + }); + } +} + +/** + * + */ +function checkInstalled() { + const scriptPath = RootMode.installedScriptPath(); + const isInstalled = scriptPath !== null; + if (isInstalled) { + logDebug(`Existing installation at: ${scriptPath}`); + } + return isInstalled; +} + +/** + * + * @param action + * @param logInstall + * @param cancel + */ +async function _installAction(action, logInstall, cancel) { + logInstall(`[${_('START')} ${actionLabel(action)}]`); + try { + if (action === 'install') { + await RootMode.installScript(cancel, logInstall); + } else { + await RootMode.uninstallScript(cancel, logInstall); + } + logInstall(`[${_('END')} ${actionLabel(action)}]`); + } catch (err) { + logInstall(`[${_('FAIL')} ${actionLabel(action)}]\n# ${err}`); + logError(err, 'InstallError'); + } +} + +/** + * + * @param action + */ +function actionLabel(action) { + return { install: _('install'), uninstall: _('uninstall') }[action]; +} + +/** + * + */ +function reset() { + if (installCancel !== undefined) { + installCancel.cancel(); + } + installCancel = undefined; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/MenuItem.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/MenuItem.js new file mode 100644 index 0000000..1085377 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/MenuItem.js @@ -0,0 +1,444 @@ +/** + * MenuItem module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported ShutdownTimer, init, uninit, MODES */ + +const { GObject, St, Gio, Clutter } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { Convenience, InfoFetcher, ScheduleInfo } = Me.imports.lib; +const { + logDebug, + modeLabel, + MODES, + WAKE_MODES, + durationString, + longDurationString, + guiIdle, +} = Convenience; + +// menu items +const PopupMenu = imports.ui.popupMenu; +const Slider = imports.ui.slider; + +// translations +const Gettext = imports.gettext.domain('ShutdownTimer'); +const _ = Gettext.gettext; +const _n = Gettext.ngettext; +const C_ = Gettext.pgettext; + +let ACTIONS; +let settings; + +var ShutdownTimer = GObject.registerClass( + class ShutdownTimer extends PopupMenu.PopupSubMenuMenuItem { + _init() { + super._init('', true); + // track external shutdown and wake schedule + this.infoFetcher = new InfoFetcher.InfoFetcher( + this._externalScheduleInfoTick.bind(this) + ); + + this.checkRunning = false; + this.externalScheduleInfo = new ScheduleInfo.ScheduleInfo({ + external: true, + }); + this.externalWakeInfo = new ScheduleInfo.ScheduleInfo({ + external: false, + mode: 'wake', + }); + this.internalScheduleInfo = new ScheduleInfo.ScheduleInfo({ + external: false, + deadline: settings.get_int('shutdown-timestamp-value'), + mode: settings.get_string('shutdown-mode-value'), + }); + + // submenu in status area menu with slider and toggle button + this.sliderItems = {}; + this.sliders = {}; + ['shutdown', 'wake'].forEach(prefix => { + const [item, slider] = _createSliderItem(prefix); + this.sliderItems[prefix] = item; + this.sliders[prefix] = slider; + this._onShowSliderChanged(prefix); + }); + this.switcher = new PopupMenu.PopupSwitchMenuItem('', false); + _connect(this.switcher, [['toggled', this._onToggle.bind(this)]]); + this.switcherSettingsButton = new St.Button({ + reactive: true, + can_focus: true, + track_hover: true, + accessible_name: _('Settings'), + style_class: 'system-menu-action settings-button', + }); + this.switcherSettingsButton.child = new St.Icon({ + icon_name: 'emblem-system-symbolic', + style_class: 'popup-menu-icon', + }); + _connect(this.switcherSettingsButton, [ + [ + 'clicked', + async () => { + try { + const r = ExtensionUtils.openPrefs(); + if (r) { + await r; + } + } catch { + logDebug('failed to open preferences!'); + } + }, + ], + ]); + this.switcher.add_child(this.switcherSettingsButton); + + this._onShowSettingsButtonChanged(); + this._updateSwitchLabel(); + this.icon.icon_name = 'preferences-system-time-symbolic'; + this.menu.addMenuItem(this.switcher); + // make switcher toggle without popup menu closing + this.switcher.activate = __ => { + if (this.switcher._switch.mapped) { + this.switcher.toggle(); + } + }; + this.menu.addMenuItem(this.sliderItems['shutdown']); + + this.modeItems = MODES.map(mode => { + const modeItem = new PopupMenu.PopupMenuItem(modeLabel(mode)); + _connect(modeItem, [ + [ + 'activate', + () => { + this._startMode(mode); + }, + ], + ]); + this.menu.addMenuItem(modeItem); + return [mode, modeItem]; + }); + + this.wakeItems = [ + new PopupMenu.PopupSeparatorMenuItem(), + this.sliderItems['wake'], + ...WAKE_MODES.map(mode => { + const modeItem = new PopupMenu.PopupMenuItem(modeLabel(mode)); + if (mode === 'wake') { + this.wakeModeItem = modeItem; + } + _connect(modeItem, [ + [ + 'activate', + () => ACTIONS.wakeAction(mode, _getSliderMinutes('wake')), + ], + ]); + return modeItem; + }), + ]; + this._updateWakeModeItem(); + this.wakeItems.forEach(item => { + this.menu.addMenuItem(item); + }); + this._updateShownWakeItems(); + this._updateShownModeItems(); + this._updateSelectedModeItems(); + this._onInternalShutdownTimestampChanged(); + + // handlers for changed values in settings + this.settingsHandlerIds = [ + ['shutdown-max-timer-value', this._updateSwitchLabel.bind(this)], + ['nonlinear-shutdown-slider-value', this._updateSwitchLabel.bind(this)], + ['wake-max-timer-value', this._updateWakeModeItem.bind(this)], + ['nonlinear-wake-slider-value', this._updateWakeModeItem.bind(this)], + [ + 'shutdown-slider-value', + () => { + this._updateSlider('shutdown'); + this._updateSwitchLabel(); + }, + ], + [ + 'wake-slider-value', + () => { + this._updateSlider('wake'); + this._updateWakeModeItem(); + }, + ], + ['root-mode-value', this._onRootModeChanged.bind(this)], + ['show-settings-value', this._onShowSettingsButtonChanged.bind(this)], + [ + 'show-shutdown-slider-value', + () => this._onShowSliderChanged('shutdown'), + ], + ['show-wake-slider-value', () => this._onShowSliderChanged('wake')], + ['show-wake-items-value', this._updateShownWakeItems.bind(this)], + ['show-shutdown-mode-value', this._updateShownModeItems.bind(this)], + ['shutdown-mode-value', this._onModeChange.bind(this)], + [ + 'shutdown-timestamp-value', + this._onInternalShutdownTimestampChanged.bind(this), + ], + ].map(([label, func]) => settings.connect(`changed::${label}`, func)); + } + + _onRootModeChanged() { + Promise.all([ + ACTIONS.maybeStopRootModeProtection(this.internalScheduleInfo), + ACTIONS.maybeStartRootModeProtection(this.internalScheduleInfo), + ]).then(() => { + this._updateSwitchLabel(); + }); + } + + _onModeChange() { + // redo Root-mode protection + ACTIONS.maybeStopRootModeProtection(this.internalScheduleInfo, true) + .then(() => { + this._updateCurrentMode(); + logDebug(`Shutdown mode: ${this.internalScheduleInfo.mode}`); + guiIdle(this._updateSelectedModeItems.bind(this)); + }) + .then(() => + ACTIONS.maybeStartRootModeProtection(this.internalScheduleInfo) + ); + } + + _updateCurrentMode() { + this.internalScheduleInfo = this.internalScheduleInfo.copy({ + mode: settings.get_string('shutdown-mode-value'), + }); + + ACTIONS.onShutdownScheduleChange(this.internalScheduleInfo); + this.updateShutdownInfo(); + } + + _onInternalShutdownTimestampChanged() { + this.internalScheduleInfo = this.internalScheduleInfo.copy({ + deadline: settings.get_int('shutdown-timestamp-value'), + }); + + ACTIONS.onShutdownScheduleChange(this.internalScheduleInfo); + this.switcher.setToggleState(this.internalScheduleInfo.scheduled); + this.updateShutdownInfo(); + } + + /* Schedule Info updates */ + _externalScheduleInfoTick(info, wakeInfo) { + this.externalScheduleInfo = this.externalScheduleInfo.copy({ + ...info, + }); + this.externalWakeInfo = this.externalWakeInfo.copy({ ...wakeInfo }); + guiIdle(this.updateShutdownInfo.bind(this)); + } + + _updateShownModeItems() { + const activeModes = settings + .get_string('show-shutdown-mode-value') + .split(',') + .map(s => s.trim().toLowerCase()) + .filter(s => MODES.includes(s)); + this.modeItems.forEach(([mode, item]) => { + const position = activeModes.indexOf(mode); + if (position > -1) { + this.menu.moveMenuItem(item, position + 2); + } + item.visible = position > -1; + }); + } + + updateShutdownInfo() { + let shutdownLabel; + if (this.internalScheduleInfo.scheduled && this.checkRunning) { + const secPassed = Math.max(0, -this.internalScheduleInfo.secondsLeft); + shutdownLabel = _('Check %s for %s').format( + this.internalScheduleInfo.modeText, + durationString(secPassed) + ); + } else { + const info = this.externalScheduleInfo.isMoreUrgendThan( + this.internalScheduleInfo + ) + ? this.externalScheduleInfo + : this.internalScheduleInfo; + shutdownLabel = info.label; + } + this.label.text = + [shutdownLabel, this.externalWakeInfo.label] + .filter(v => !!v) + .join('\n') || _('Shutdown Timer'); + } + + _updateSelectedModeItems() { + this.modeItems.forEach(([mode, item]) => { + item.setOrnament( + mode === this.internalScheduleInfo.mode + ? PopupMenu.Ornament.DOT + : PopupMenu.Ornament.NONE + ); + }); + } + + // update timer value if slider has changed + _updateSlider(prefix) { + this.sliders[prefix].value = + settings.get_double(`${prefix}-slider-value`) / 100.0; + } + + _updateSwitchLabel() { + const minutes = Math.abs(_getSliderMinutes('shutdown')); + const timeStr = longDurationString( + minutes, + h => _n('%s hr', '%s hrs', h), + m => _n('%s min', '%s mins', m) + ); + this.switcher.label.text = settings.get_boolean('root-mode-value') + ? _('%s (protect)').format(timeStr) + : timeStr; + } + + _updateWakeModeItem() { + const minutes = Math.abs(_getSliderMinutes('wake')); + this.wakeModeItem.label.text = C_('WakeButtonText', '%s %s').format( + modeLabel('wake'), + longDurationString( + minutes, + h => _n('%s hour', '%s hours', h), + m => _n('%s minute', '%s minutes', m) + ) + ); + } + + _onShowSettingsButtonChanged() { + this.switcherSettingsButton.visible = settings.get_boolean( + 'show-settings-value' + ); + } + + _updateShownWakeItems() { + this.wakeItems.forEach(item => { + item.visible = settings.get_boolean('show-wake-items-value'); + }); + this._onShowSliderChanged('wake'); + } + + _onShowSliderChanged(settingsPrefix) { + this.sliderItems[settingsPrefix].visible = + (settingsPrefix !== 'wake' || + settings.get_boolean('show-wake-items-value')) && + settings.get_boolean(`show-${settingsPrefix}-slider-value`); + } + + _startMode(mode) { + settings.set_string('shutdown-mode-value', mode); + ACTIONS.startSchedule( + _getSliderMinutes('shutdown'), + _getSliderMinutes('wake') + ); + } + + // toggle button starts/stops shutdown timer + _onToggle() { + if (this.switcher.state) { + // start shutdown timer + ACTIONS.startSchedule( + _getSliderMinutes('shutdown'), + _getSliderMinutes('wake') + ); + } else { + // stop shutdown timer + ACTIONS.stopSchedule(); + } + } + + destroy() { + this.infoFetcher.stop(); + this.settingsHandlerIds.forEach(handlerId => { + settings.disconnect(handlerId); + }); + this.settingsHandlerIds = []; + super.destroy(); + } + } +); + +/** + * + * @param settingsObj + * @param actions + */ +function init(settingsObj, actions) { + settings = settingsObj; + ACTIONS = actions; +} + +/** + * + */ +function uninit() { + settings = null; + ACTIONS = null; +} + +/** + * + * @param prefix + */ +function _getSliderMinutes(prefix) { + let sliderValue = settings.get_double(`${prefix}-slider-value`) / 100.0; + const rampUp = settings.get_double(`nonlinear-${prefix}-slider-value`); + const ramp = x => Math.expm1(rampUp * x) / Math.expm1(rampUp); + return Math.floor( + (rampUp === 0 ? sliderValue : ramp(sliderValue)) * + settings.get_int(`${prefix}-max-timer-value`) + ); +} + +/** + * + * @param item + * @param connections + */ +function _connect(item, connections) { + const handlerIds = connections.map(([label, func]) => + item.connect(label, func) + ); + const destroyId = item.connect('destroy', () => { + handlerIds.concat(destroyId).forEach(handlerId => { + item.disconnect(handlerId); + }); + }); +} + +/** + * + * @param settingsPrefix + */ +function _createSliderItem(settingsPrefix) { + const sliderValue = + settings.get_double(`${settingsPrefix}-slider-value`) / 100.0; + const item = new PopupMenu.PopupBaseMenuItem({ activate: false }); + const sliderIcon = new St.Icon({ + icon_name: + settingsPrefix === 'wake' ? 'alarm-symbolic' : 'system-shutdown-symbolic', + style_class: 'popup-menu-icon', + }); + item.add(sliderIcon); + const slider = new Slider.Slider(sliderValue); + _connect(slider, [ + [ + 'notify::value', + () => { + settings.set_double( + `${settingsPrefix}-slider-value`, + slider.value * 100 + ); + }, + ], + ]); + item.add_child(slider); + return [item, slider]; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/RootMode.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/RootMode.js new file mode 100644 index 0000000..bed5e15 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/RootMode.js @@ -0,0 +1,279 @@ +/** + * RootMode module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported shutdown, shutdownCancel, wake, wakeCancel, installScript, uninstallScript */ +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const logDebug = Me.imports.lib.Convenience.logDebug; + +const { Gio, GLib } = imports.gi; + +// translations +const Gettext = imports.gettext.domain('ShutdownTimer'); +const _ = Gettext.gettext; + +/** + * + * @param stream + * @param cancellable + */ +function readLine(stream, cancellable) { + return new Promise((resolve, reject) => { + stream.read_line_async(0, cancellable, (s, res) => { + try { + const line = s.read_line_finish_utf8(res)[0]; + + if (line !== null) { + resolve(line); + } else { + reject(new Error('No line was read!')); + } + } catch (e) { + reject(e); + } + }); + }); +} + +/** + * + * @param str + */ +function quoteEscape(str) { + return str.replaceAll('\\', '\\\\').replaceAll('"', '\\"'); +} + +/** + * Execute a command asynchronously and check the exit status. + * + * If given, @cancellable can be used to stop the process before it finishes. + * + * @param {string[] | string} argv - a list of string arguments or command line that will be parsed + * @param {Gio.Cancellable} [cancellable] - optional cancellable object + * @param {boolean} shell - run command as shell command + * @param logFunc + * @returns {Promise} - The process success + */ +function execCheck( + argv, + cancellable = null, + shell = true, + logFunc = undefined +) { + if (!shell && typeof argv === 'string') { + argv = GLib.shell_parse_argv(argv)[1]; + } + + const isRootProc = argv[0] && argv[0].endsWith('pkexec'); + + if (shell && Array.isArray(argv)) { + argv = argv.map(c => `"${quoteEscape(c)}"`).join(' '); + } + let cancelId = 0; + let proc = new Gio.Subprocess({ + argv: (shell ? ['/bin/sh', '-c'] : []).concat(argv), + flags: + logFunc !== undefined + ? Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE + : Gio.SubprocessFlags.NONE, + }); + proc.init(cancellable); + + if (cancellable instanceof Gio.Cancellable) { + cancelId = cancellable.connect(() => { + if (logFunc !== undefined) { + if (isRootProc) { + logFunc(`# ${_('Can not cancel root process!')}`); + } else { + logFunc(`[${_('CANCEL')}]`); + } + } + proc.force_exit(); + }); + } + let stdoutStream = null; + let stderrStream = null; + let stdCancel = null; + + if (logFunc !== undefined) { + stdoutStream = new Gio.DataInputStream({ + base_stream: proc.get_stdout_pipe(), + close_base_stream: true, + }); + + stderrStream = new Gio.DataInputStream({ + base_stream: proc.get_stderr_pipe(), + close_base_stream: true, + }); + const readNextLine = async (stream, prefix) => { + stdCancel = new Gio.Cancellable(); + const line = await readLine(stream, stdCancel); + logFunc(prefix + line); + logDebug(line); + return readNextLine(stream, prefix); + }; + // read stdout and stderr asynchronously + readNextLine(stdoutStream, '').catch(() => {}); + readNextLine(stderrStream, '# ').catch(() => {}); + } + + return new Promise((resolve, reject) => { + proc.wait_check_async(null, (p, res) => { + try { + const success = p.wait_check_finish(res); + if (stdCancel !== null) { + stdCancel.cancel(); + } + if (!success) { + let status = p.get_exit_status(); + + throw new Gio.IOErrorEnum({ + code: Gio.io_error_from_errno(status), + message: GLib.strerror(status), + }); + } + + resolve(); + } catch (e) { + reject(e); + } finally { + const maybeCloseStream = stream => { + if (stream !== null && !stream.is_closed()) { + stream.close_async(0, null, (s, sRes) => { + try { + s.close_finish(sRes); + } catch (e) { + logError(e, 'StreamCloseError'); + } + }); + } + }; + maybeCloseStream(stdoutStream); + maybeCloseStream(stderrStream); + if (cancelId > 0) { + cancellable.disconnect(cancelId); + } + } + }); + }); +} + +/** + * + */ +function installedScriptPath() { + for (const name of [ + 'shutdowntimerctl', + `shutdowntimerctl-${GLib.get_user_name()}`, + ]) { + const standard = GLib.find_program_in_path(name); + if (standard !== null) { + return standard; + } + for (const bindir of ['/usr/local/bin/', '/usr/bin/']) { + const path = bindir + name; + logDebug(`Looking for: ${path}`); + if (Gio.File.new_for_path(path).query_exists(null)) { + return path; + } + } + } + return null; +} + +/** + * + * @param action + * @param cancellable + * @param logFunc + */ +function _runInstaller(action, cancellable, logFunc) { + const user = GLib.get_user_name(); + logDebug(`? installer.sh --tool-user ${user} ${action}`); + return execCheck( + [ + 'pkexec', + Me.dir.get_child('tool').get_child('installer.sh').get_path(), + '--tool-user', + user, + action, + ], + cancellable, + false, + logFunc + ); +} + +/** + * + * @param cancellable + * @param logFunc + */ +async function installScript(cancellable, logFunc) { + // install for user if installed in the /home directory + await _runInstaller('install', cancellable, logFunc); + return true; +} + +/** + * + * @param cancellable + * @param logFunc + */ +async function uninstallScript(cancellable, logFunc) { + await _runInstaller('uninstall', cancellable, logFunc); + return true; +} + +/** + * + * @param args + * @param noScriptArgs + */ +function runWithScript(args, noScriptArgs) { + const installedScript = installedScriptPath(); + if (installedScript !== null) { + return execCheck(['pkexec', installedScript].concat(args), null, false); + } + if (noScriptArgs === undefined) { + throw new Error(_('Privileged script installation required!')); + } + return execCheck(noScriptArgs, null, false); +} + +/** + * + * @param minutes + * @param reboot + */ +function shutdown(minutes, reboot = false) { + return runWithScript( + [reboot ? 'reboot' : 'shutdown', `${minutes}`], + ['shutdown', reboot ? '-r' : '-P', `${minutes}`] + ); +} + +/** + * + */ +function shutdownCancel() { + return runWithScript(['shutdown-cancel'], ['shutdown', '-c']); +} + +/** + * + * @param minutes + */ +function wake(minutes) { + return runWithScript(['wake', `${minutes}`]); +} + +/** + * + */ +function wakeCancel() { + return runWithScript(['wake-cancel']); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/ScheduleInfo.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/ScheduleInfo.js new file mode 100644 index 0000000..9fd4d80 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/ScheduleInfo.js @@ -0,0 +1,84 @@ +/** + * ScheduleInfo module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported ScheduleInfo */ +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { durationString } = Me.imports.lib.Convenience; + +const { GLib } = imports.gi; + +// translations +const Gettext = imports.gettext.domain('ShutdownTimer'); +const _ = Gettext.gettext; + +var ScheduleInfo = class { + constructor({ mode = '?', deadline = -1, external = false }) { + this._v = { mode, deadline, external }; + } + + copy(vals) { + return new ScheduleInfo({ ...this._v, ...vals }); + } + + get deadline() { + return this._v.deadline; + } + + get external() { + return this._v.external; + } + + get mode() { + return this._v.mode; + } + + get scheduled() { + return this.deadline > -1; + } + + get secondsLeft() { + return this.deadline - GLib.DateTime.new_now_utc().to_unix(); + } + + get minutes() { + return Math.floor(this.secondsLeft / 60); + } + + get modeText() { + const texts = { + suspend: _('suspend'), + poweroff: _('shutdown'), + reboot: _('reboot'), + wake: _('wakeup'), + }; + return this.mode in texts ? texts[this.mode] : texts['poweroff']; + } + + get label() { + let label = ''; + if (this.scheduled) { + label = _('%s until %s').format( + durationString(this.secondsLeft), + this.modeText + ); + if (this.external) { + label = _('%s (sys)').format(label); + } + } + return label; + } + + isMoreUrgendThan(otherInfo) { + return ( + !otherInfo.scheduled || + (this.scheduled && + // external deadline is instant, internal deadline has 1 min slack time + (this.external ? this.deadline : this.deadline + 58) < + otherInfo.deadline) + ); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/SessionModeAware.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/SessionModeAware.js new file mode 100644 index 0000000..105e031 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/SessionModeAware.js @@ -0,0 +1,33 @@ +/** + * ScreenModeAware module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported load, unload */ +const Main = imports.ui.main; + +let sessionId = null; + +/** + * + * @param onSessionModeChange + */ +function load(onSessionModeChange) { + if (sessionId === null) { + sessionId = Main.sessionMode.connect('updated', session => + onSessionModeChange(session.currentMode) + ); + } +} + +/** + * + */ +function unload() { + if (sessionId !== null) { + Main.sessionMode.disconnect(sessionId); + sessionId = null; + } +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Textbox.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Textbox.js new file mode 100644 index 0000000..6f395e1 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Textbox.js @@ -0,0 +1,119 @@ +/** + * Textbox module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported showTextbox, hideAll, init, uninit */ +const Main = imports.ui.main; +const { St, Clutter } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const { Convenience } = Me.imports.lib; +const { logDebug, throttleTimeout } = Convenience; +let textboxes = []; + +let throttleUpdate = null; +let throttleUpdateCancel = null; + +/** + * + */ +function init() { + [throttleUpdate, throttleUpdateCancel] = throttleTimeout(_update, 50); +} + +/** + * + */ +function uninit() { + throttleUpdate = null; + throttleUpdateCancel = null; +} + +// show textbox with message +/** + * + * @param textmsg + */ +function showTextbox(textmsg) { + for (const t of textboxes) { + // replace old textbox if it has the same text + if (t.text === textmsg) { + t['_hidden'] = 1; + } + } + logDebug(`show textbox: ${textmsg}`); + const textbox = new St.Label({ + style_class: 'textbox-label', + text: textmsg, + opacity: 0, + }); + Main.uiGroup.add_actor(textbox); + textboxes.unshift(textbox); + throttleUpdate(); +} + +/** + * + */ +function _update() { + // remove hidden textboxes + textboxes = textboxes.filter(t => { + if (t['_hidden']) { + const sid = t['_sourceId']; + if (sid) { + clearTimeout(sid); + } + delete t['_sourceId']; + t.destroy(); + } + return !t['_hidden']; + }); + const monitor = Main.layoutManager.primaryMonitor; + let heightOffset = 0; + textboxes.forEach((textbox, i) => { + if (i === 0) { + heightOffset = -textbox.height / 2; + } + textbox.set_position( + monitor.x + Math.floor(monitor.width / 2 - textbox.width / 2), + monitor.y + Math.floor(monitor.height / 2 + heightOffset) + ); + heightOffset += textbox.height + 10; + if (!('_sourceId' in textbox)) { + // start fadeout of textbox after 3 seconds + textbox['_sourceId'] = setTimeout(() => { + textbox['_sourceId'] = 0; + textbox.ease({ + opacity: 0, + duration: 1000, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => { + textbox['_hidden'] = 1; + throttleUpdate(); + }, + }); + }, 3000); + } + if (textbox['_sourceId']) { + // set opacity before fadeout starts + textbox.opacity = + i === 0 + ? 255 + : Math.max(25, 25 + 230 * (1 - heightOffset / (monitor.height / 2))); + } + }); +} + +/** + * + */ +function hideAll() { + throttleUpdateCancel(); + for (const t of textboxes) { + t['_hidden'] = 1; + } + _update(); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Timer.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Timer.js new file mode 100644 index 0000000..0c2a38f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/lib/Timer.js @@ -0,0 +1,118 @@ +/** + * Timer module + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported Timer */ +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { RootMode, ScheduleInfo } = Me.imports.lib; +const logDebug = Me.imports.lib.Convenience.logDebug; + +const { Gio } = imports.gi; + +/* TIMER */ +var Timer = class { + constructor(callbackAction, initialMode = 'shutdown') { + this._timerMaxSeconds = 0; + this._timerCancel = null; + this._callbackAction = callbackAction; + this._tick = null; + this._timerId = null; + this.info = new ScheduleInfo.ScheduleInfo({ mode: initialMode }); + } + + setTickCallback(tick) { + this._tick = tick; + } + + adjustTo(info) { + const newDeadline = info.deadline !== this.info.deadline; + this.info = info; + if (info.scheduled) { + if (newDeadline) { + // update proc process for new deadline + this.startProcTimer(); + } + this.startForegroundTick(); + logDebug( + `Started timer: ${this.info.minutes}min remaining (deadline: ${this.info.deadline})` + ); + } else { + this.stopTimer(); + logDebug( + `Stopped timer: ${this.info.minutes}min remaining (deadline: ${this.info.deadline})` + ); + } + } + + stopTimer() { + this.stopProcTimer(); + this.stopForeground(); + } + + _maybeRunTimerAction() { + if (this._timerCancel !== null) { + // ensure timer action is only run once + logDebug(`Running '${this.info.mode}' timer action...`); + this._callbackAction(this.info.mode); + } + } + + async startProcTimer() { + // secondary timer witch calls a sleep process as timer + this.stopProcTimer(); + + const secs = this.info.secondsLeft; + this._timerCancel = new Gio.Cancellable(); + try { + if (secs > 0) { + await RootMode.execCheck( + ['sleep', `${secs}`], + this._timerCancel, + false + ); + } + this._maybeRunTimerAction(); + } catch { + } finally { + this._timerCancel = null; + } + } + + stopProcTimer() { + if (this._timerCancel !== null) { + this._timerCancel.cancel(); + } + this._timerCancel = null; + } + + _maybeTick() { + if (this._tick !== null) { + this._tick(); + } + } + + startForegroundTick() { + if (this._timerId === null) { + // primary timer which updates ticks every second + this._timerId = setInterval(() => { + this._maybeTick(); + if (!this.info.scheduled || this.info.secondsLeft < 0) { + // timer completed + this._maybeRunTimerAction(); + this.stopTimer(); + } + }, 1000); + this._maybeTick(); + } + } + + stopForeground() { + if (this._timerId) { + clearInterval(this._timerId); + } + this._timerId = null; + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/cs/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/cs/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..65eec923e5a58bc54084c3da99a5212db86ba1ba GIT binary patch literal 1871 zcmbW1%WoVt9LEO;P?kqaK?w15DTxxH*-myVwVHGbYMPWnH(4biAOx!1nIF5}%-AE_ zvw4U!C%7Q>4+sZNp#;?Aw7O7Qi}K2Y040&6`V{~q@5G2{L1WfbLukPJy3+F8MNhG{=&_53a_$)}j_Wy&^qw48(I)R{%##Dz zy$e@|H)&W$<$6d{EJ{%qLMmi#$*Id#q0FTf37a%tlW&PMPnqfDHddRGS&n5}v|wwJXV`T z#H3lKjIctcGGNBd-?Ba#+gmTS8jbtujgYN;&GCeTMT2c3K06?sI2L+zu} zhduXNT6HP1{?*uDCvA{w$c8nSrLrqa%gqHSDM{GEmL=)DDl3#JZT+Tci`c)Ew~fE1 zLRM)l`zzEF&c(mXErqNW)M|ck)(_6HS}m*xZv?d^4Ex`A)EhjVg7A)p)0hg#wx#|dCzQYztv8;NUD)aFOD{ZEHahm)#k#u zp4n`fN1kWI^rjT)PpV)8=ctW(ZHS(~eT;9nt0 zx~#mVC>EC0t3h=ZmQwUrakCp@V&ae~(P}cY6_eO?9v@m9fHGA4Xk{Gxft4WZA|zlTz2;v)I+& zmHoYc8QBiLO5P)>y!HOAsH1jZ&Qzj0+}-572ltJfP50R3%)K66+KD3?MH;w`F75w6 NktbZI!?2^4{sXcl5+(ou literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/de/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/de/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..5b231b2bdfcb5b372450b8518bdb9d509081b396 GIT binary patch literal 10074 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/fr/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/fr/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..f1b1d6105ac8bfc29a03817d2ca4ed797c55549d GIT binary patch literal 1834 zcmd6n&u<(x6vtf%PzDO6{5bH_5G{07&2+K>wVIFu329Z-ZI@*G<4_LH%*(FJj6K+% zG)N%v2XL(fS8j{AA#N3yJtM&ZapMqi=Py9w>zUc4f;190tnqyO?C0nA-uTV$C+6-j zv}e#?M8Avv68g;}c%l6a9tVE`9|w0qulpzX7&!L;W3Pe7!7jK6z6^c@cEHcTN5OBv zqu_Tfe*m9={3G}r_!Bq}{sH=ZM;~PD1uz0%0Y3m=1#f}g&X?c>KHLFMKz`?;=A3oV z`*#!c{(SzXIpM@4*24t)1Tm zJCOeZ@v!+v7=wGY4p7HB=Lc=`Ie`mxPQAWA>uGd^^RMRP^)bO@?W0#fn%Gn5K6c-H ztWWwu$MUhR%#5}kG@_}6LaNG6^hxPjW;+duH;W{Oml$3*(6UJ?%W6G+W2D+@uIph(^LFTUeAP+g=zUzC| zXE|pBqi<2_!i!mWjf{n>37^H>gvu{mzS3XAB;`3@+i|44R^eW-|!coF|ajzG~Z-((1-s>g3w@$^qI1Vle>%yTC%I3mplkgQoDieyY zj>V=>iY$M7vzdz0+0?tELdZNyb#V>`)Tk083Wp>L96XZ~zGZ^`#s1oUJPT1AtZD_% zapb2Zd~&qoPM5imYKgn5?r3(gmWkepH*QT%u zS7j~Q<=zr+hRY`vKgSokOTmrs0x2?0bOTM9bbK+2qXn!qVz?qKmBNh^9!00?XMb&j zgh|H(tcEexgSxn=GIcqP{h+D0dfvYdEH<$%l=D~Sn#i$-7j4aD#Bz_f*~g zLAQ@8nt_>4wx$!@ixlC%XUz0l*8=$$N^Z&Ngk2(@O((b|r6b;C z0N-1xw5~+E`^DE}9T)X(s1If}npHfla2Jp#pN~%Wz@_YsX6H-?smHywKFR;pQpFL^ NHsN>Jp4V7re*-nE_$dGY literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/it/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/it/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..ad37b936a56f2c3045ffcb9a4a2122b950b09f56 GIT binary patch literal 1873 zcmchXO>Z1U5QYaZ9~r)b;lO8wV3Z~5&3F^ZVT=(<*f=X?$;!J4+)%Sq?6#Td9=dyM z!w=vB5+^R4xNzct;E1>Z65=OtKp=hqQp6R(+cUe~MA$xXVC3GXtGl}9t(q?Xa(wBN z2+yM!PhxzJ@f1dW8-DQo3O)q>2HpqW0GGkP!F$2w+oR}NkiZsr5qugfz!mT#@EG_t zcn|n37|#DNvwsF3fc-o87|JcEJH< zi;iQ2oP++LIefQh#nIGMc1~AM8q?NBp>*XrEH|@yvC>}UwBn+^+*3tWkegOMGrO9+ zDws|wJ@;-M>|$w0=G7sdyYd}ABGCT!fkC#6@l=?Mqak~*^u$HOso7m9bh*mdVzE)Y zKcNw%FV-8AoHu33*}|(iPNi|mE2HaNpFeqaZM}80Psw)7+QZ9B>xbhhXI0JvQ&!~? zii?V&oUez>k9fnO`}@)7A0ir9v&~~KdYQP+));h{ zacQg%Q&Pbm7K5`u`E*Rd70xB+!tFZ zDgS0~6!&}m?jobrb`oDS8rt#F_e!Ypyywr9xm0?c##3n>`;BX(OXB>(FNk}at?25p z$#6qbI{%jP@gT3P%*7>R3zw2EYtwCX)`^<=#wks7VuNV4wI07AHd(W6avT`Wl&7=p zq`iur#uOK%<5K!*O6~TU`fsr}WNF9K0d_@#{Wvt3v9dwkZns)>^VQq+Oa(_2(u7-c zUFOCz71B9X7|J-WyT>m2P__PVr@qPX4gGhYQE14hSD<0Md>^+*MRlW5rpT2%(datu zO*Fh|exSoai)b4k?v+P?0Xj0o=ehvn%DPaL@ULj4b;#ze66U`9-S}T3qL(DO9iHF< J&ja3^=06jG``G{h literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/nl/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/nl/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..da584ab8eb7a3409d4d27dfb1722cfc1a1e2f3db GIT binary patch literal 3371 zcmchZ%WoV-5Qhgycr4+S7jLK#f@6_cuQ!N9Ym6X?lUT&bD(gHHMMUkL+S$p@c8|Jy zY$q2Y#1SDlAi)8NKY#-fS1$Mp5{fu*BT_&}2!wJ+Li~Cj-gsmCLSW?Cue+Sm&F6m=d>Z}p;CpZ{w;VNIrsr|cE5tqaS3$( zTmxM^zk<%Mn+3OF(DfSyFMv+(J^Wk%KPdPo_#yhoE1uT{uNORuWTNR^1>HPfgL}Yh z;BN5mf+JW2G`(iQ^Pr2n3qA(E1CD_ofzIAH1-~ogKZ1KO{u}80+x}3lM^lLL%-e$3efJ1n_iWCQ`Rtl5*UmrpJeeb_o2Srr`FB1!KapM!OXWR**VT)A z9>?o)?dr`v&*DXTJ-Ftfys~xkb{XobRF^baBk$_0(~o3o*$wBdY%rBJifNbeX2fFD zPy1xLsSVVEBpdaac1N<*9$j5U)4Yh&H8dAQkJmA@EMC>fNu@0HRlr`0(J1}nnA=v& z#XRJy>X7YXFpdJ&D;%%VDZ`{>d@1+UP^ej0XkBKls%x2F_KyCYXAH1 zgTX{Cu#RMiSvnLM3Y27;j|7b*JznJY2niX`NVzT}1jn&}BBr+L_aVyzDCK1W5@jMA zDM`Xm!n)1UmT{D+bSqq?nbcUCW5P;nAw#BGHsN@!mK)B}P-OK^8MTPlc&)BlAj3B6 z(Ohb+lG)%`7i%~yaSkp-LC6+<;mbm)EZ4%rRh4cHVTD3o>M&Q-{46q}hq`2}N)iqR z!^6pNo8+aPd-qL@uCG%p1GKErw$<)(kjC6pNt$fHu7nlr!&Yh%mVtN1ZJl*yT2sC} zOIZ<~DNHuCx`@5wPY3>K)&|AVpp~K1k>e+3rZC8HOjC=NrPHdMjJpmtYil-uN~*~9++fu3`$!`h#cZ55y}8?=8evXy3> zY7zT~mF^o%m1JErS)ZW1Ik{WXj!7CHov57kkFaE&2iH^_M3(keYt?Z`@~+>)(cI>P zxd#o(U09aB#g`V84$Lv+p+Of0pB)f}6Jfgzs#eFczk#g9Lbtn3Nc|e*6?d|y`2~<_ zmaBB#xu04m$Zvp5$KsSN&wqha)kYVCUaWcxLTK#5!3`jb8{q#_ayI}jfE2sJa!l|h zJGx2-3J>RnbRyI4rcq~3#J&8K%1*Rfy|2>oG|s<~bUC^xaUO>p2T_Ov<-fL%+Uw;Z zxRXB%3LAbbjcj%u!2iLxD+NnkTzU{AEcYe0OA#kFMuK}>J7LK4igiGJ=)#0b0xjBI zlt10L@=1Pu+_>^7<^A$Jz{nurRkJ3rCljr*JENF&MdGV;h^feaUtw;Gy^BfULd{Kv zyMy8=3|S5)!WrCSJ+wS`a-!2p=^kg5KWO%(N(k2qw!^H#^^0?Fj&9TQ{4+|KgWXuI1#WOvX<@S->?iqILHEdMmQ6QbS*!%|`MCEJ% literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/pl/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/pl/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..1f2c4ec5b590c12e10be4814eb10beba3b536466 GIT binary patch literal 1977 zcmchXO>Y}T7{?a~g_@U^wjjjoK;NCGET9{--#ndf=do}bRledghL z7V9Of`&chyB@f{X&(Gj#@E7n&@Bw%Z{1bcvJom8Yy$%wv0j`3tfGJo9KLJmIUxAN< z--0%OuhM@2pN9S`_#F5EJP)3Hq|Eoh7oqpTS3wEB27U_K{k{aBN6y!k|NBSFxZgqB z&)E}YTmag7E?4}Z;=PKWgSO7^z#8}?cozH(w0-_j=_ej5`+EVjeOw0Zyl#TFo}{wp zpsn*`(9Z1(5F>MY1KugDIV)6;JsTx^PhsIG?-?w+Kic}oW6!bg3tPI`*#L~dJA-9w zw&&TJ?R)d;nv7(wrqoU-RppeFi`+14E+uEoh2aUQYp+Xpd77t0k8%^su^@)0j4W_5 zjcyzsqR1VZd0o$#0`7|V+H1u{VC zGkd8LZDf|QcotQrlT2!ExD>9}`SXhxmm9~&WK2a&7(^MWOg|d2I8RtlW_dP;;bLMK z=WW~hF((}9-`{=uBD|iG+blBvdhEZ)lt!r`nf6@ucKzl?cMV3CBxG&ZFkz!=n=F&c z_+35Zv41rmYJVU@QtNH_o9qs^A^zLcu#mKacH0k@{NN&Kx5L)b8$mk=YB#7h{yey4w*k-G!02_Q>)o|km#t<{Ta^O+ppYU%rH1XA3t2+BSSHbkD$Pvi*5I0dX%=S-{*WnuO++%r zuO=jywz#SFl3dZmza~|xLn1P#>dxXaj^3H7Ag6_#c4N8rzJHwwrpj^kB#XHri_M_ff~QpdKK`Q-TPX{*#9?o^U~DVlfkE($Ri*6F9e%T(*;Jax96v z7&ZzGZBwFiTvx8^dgJfLtvsIC^X*LF#q1{3&hEeD Oj;oUCEPrZpE&T=58Xu|v literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/pt/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/pt/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..0e87a33c958970fb8ec19c4f0720b8595d754f41 GIT binary patch literal 1801 zcmc(eOK%)S5XT2F0fu*o!hu)eVB}3So7r_xqA^Ayu^mOp+AHrSM2ZyD*(vWfndu&N z_t*}H9CG0UAh;tA2ni4z5H}9^6CfmV%O$6L0xlf*_w0*Ujt^XDZSSwUs;0WCy6fKI znJ)s2!2WLEO-~31@D73@X+Hy@Fp08bKpAoG+2&! z8+-x#&%mSLm*6q*d(hke4!#Ed1-=Eo@pWoOK=a@x1rsFrHQLIqa{2 z$HBpfpO5(Kh!4OQp+9nHX#WoA^KF2yf@`2Ze-k_b-U0o&KaAwRfb-b@0s8a)1`*C= zco{-_Xv|<2V&dp3_m@HMbMJTx0$+c)tZM7^C_@#m&()7-FrW8}IZFdwnlY_kja>Dkn3Vvq4Mj$h^$S4oa8mZADJzO!HEWzO%LcO$=>`tbBy!wz$a$IGU*Ub<$zy zr0UzCGYV<4pe|xFd$weqE(%VkVw=g74Heo-C$*}QdH2}D>BZW?HU*m=D+enljO+9U zoR%54bx{^Gs3S^(dVSL=dEl@8iQf5JT%T}Y!VY%D@eXq@vfRXV@6-dcf> zvy4`D94l`XZg8QEi(0lX)97s3w^3Io6t>r+4c?O8Bw7}Z6KclIW)z=_;?vY@CXIy? zaWjs?OTxOSYlO0yaM~oaER^Jo*0{`tQqZe@Df%3BS>y?A=o@UDrVlgj8%?tpg%!D& zotPz5xUhAhwKC13QIErOS|MH>bgMulj(6P2A`?yBeLD+WCMs*+eU< zr&BzDgwEWME^KF|5m~gVO>PrXMYXj{%|#k6m*y3HK#kgBcr`lDip?;mw&qkiTByhM z1~kKM)IoFf_}nmngoY7Jv={l-wl=A~B&|#6-|YU(HdtnKLto^$YaMj|9e2u<9-y?s$t@%pw9%+=_H~uH<&5zttEA^@ b`|I{N9^0b2s1(ZiA047Y(fDI;4~6~@JxuwC literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/ru/LC_MESSAGES/ShutdownTimer.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/locale/ru/LC_MESSAGES/ShutdownTimer.mo new file mode 100644 index 0000000000000000000000000000000000000000..c3199ec8e6a6a3844152eb201cd4ecea367443c1 GIT binary patch literal 1147 zcmah{&rj4q6t0TD)@Y0|dXSjM0U|N8w1prk6b-Nt;x261#dtGiJM31w(`IHWkZ?dR znrQUoKj6*8gCP=8gq!#2KVbCaf8fc3Z?+5Tfykt<-}~P8eofQwm%82-3y6St1#tlJ8scAo>34oieu^<73pzVsWqsd zgtQ#RN!*1a0;c=#w>HW=dPr-M%=+XWVR$9HZg~Yc?)dYF^6xOwrS>yo{*%i*XA{SLHw)dI1}STEpXlN_Vk3O-4F-dYNU)NrBZOKVWqSMwSAZD~Ad9 zLNXokrf`78Eh^l>QOI2P2J5v<*R`Op543CcxRwRC!30c4KJME4(wIA>-ByJ;X4$a5 zo|TMSL;YA{VTs*8n!8VCD5E_4GUbT+frP=lnYU2MD5*pVuhGfuDh_0KIZ*G?wUvnb zq8JG2z=KZNgePe1$%X^@{6OpJXcg-5TBD3AF;UOyKT>^F+iExeA9pW(l0H=*)Q-~L zOHd!xp8mzuTMT~2`mJ;W)MolZeNj8Y;A`0rNc;npwiJS(ZhNP;*HmhWT3LznPJzWpj9^)Ce zDF;-cHrfc$LIqTff)FZFIfb@JL6B{cxb;@V4FRWkw}?XzaNx){-r1}`r4k38{O0%G z%=6pt+1_8aZ1~WC-4EXiZ^5_0U%3ej>Z`~w^SH{D_wkAg#>s-FhWJ&HW&rb(WJEK++wFHI%YJBad4LF;M<$kQ~EEFgozsJL@1OhY34 zRC@eSL?jC-+0G)>PTgF%en~j9}jW%7@d2+8A^di`w?FpnlA=7LGaqkOE#2Zl$+3dT!H;tkGw&%>xD{54va)*jD# zktPCd9MaR%l|gpzovut`lLi5qoRc(CRptzhc_OWfXfV&(l{SP`;|?*a)7A_<$W)2- zoGYnA%67SI*-u*b2q~8xdvu3gwr%ryS4gXtxRD54$rFckR=>Tva3NbdlO0WQU2`Amu+T{uw zyV7?^u{e}p{j*u>CUw7xQ_IG=sXp^-t!CC-xz<`h(mwt6`kFQ85qH3 O{ly2l`u|d_HT(s^W&Vo* literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/metadata.json b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/metadata.json new file mode 100644 index 0000000..0cc06c7 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/metadata.json @@ -0,0 +1,17 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Shutdown/reboot/suspend the device after a specific time or wake with a rtc alarm.\n\nThe screen-saver will not interrupt the timer. A privileged control script may be installed to control shutdown and rtcwake as user. Additionally, a check command may be configured before shutdown.", + "gettext-domain": "ShutdownTimer", + "name": "Shutdown Timer", + "session-modes": [ + "user", + "unlock-dialog" + ], + "settings-schema": "org.gnome.shell.extensions.shutdowntimer-deminder", + "shell-version": [ + "42" + ], + "url": "https://github.com/Deminder/ShutdownTimer", + "uuid": "ShutdownTimer@deminder", + "version": 31 +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules new file mode 100644 index 0000000..05ec286 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules @@ -0,0 +1,8 @@ +polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.policykit.exec" && + action.lookup("program") == "{{TOOL_OUT}}" && + subject.isInGroup("{{TOOL_USER}}")) + { + return polkit.Result.YES; + } +}); diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules.legacy b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules.legacy new file mode 100644 index 0000000..7f00aa8 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/10-dem.shutdowntimer.settimers.rules.legacy @@ -0,0 +1,12 @@ +polkit.addRule(function (action, subject) { + var idx = action.id.lastIndexOf("."); + var username_stripped = action.id.substring(0, idx); + var username = action.id.substring(idx + 1); + if (username_stripped === "{{RULE_BASE}}") { + if (subject.user === username) { + return polkit.Result.YES; + } else { + return polkit.Result.NO; + } + } +}); diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/dem.shutdowntimer.policy.in b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/dem.shutdowntimer.policy.in new file mode 100644 index 0000000..6f93f7b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/polkit/dem.shutdowntimer.policy.in @@ -0,0 +1,20 @@ + + + + Shutdown Timer + https://github.com/Deminder/ShutdownTimer + + + Control shutdown and rtc wake alarm schedule + Steuerung des Ausschalt-Planers und des RTC-Weck-Alarms + No Authorization required to control shutdown or rtc wake alarm. + Keine Autorisierung zur Steuerung des Ausschalt-Planers oder RTC-Weck-Alarms notwendig. + + yes + yes + yes + + {{PATH}} + 3.0.0 + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/prefs.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/prefs.js new file mode 100644 index 0000000..e5d8119 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/prefs.js @@ -0,0 +1,229 @@ +/** + * Extension preferences GUI + * + * @author Deminder + * @copyright 2021 + * @license GNU General Public License v3.0 + */ +/* exported init, fillPreferencesWindow */ +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); + +const { Install, Convenience } = Me.imports.lib; +const { logDebug } = Convenience; +const { enableGuiIdle, disableGuiIdle, guiIdle, modeLabel, MODES } = + Convenience; + +const { GLib, Gtk, Gio } = imports.gi; + +/** + * + */ +function init() { + ExtensionUtils.initTranslations(); +} + +const templateComponents = { + shutdown: { + 'shutdown-mode': 'combo', + 'root-mode': 'switch', + 'show-end-session-dialog': 'switch', + 'shutdown-max-timer': 'adjustment', + 'shutdown-slider': 'adjustment', + 'nonlinear-shutdown-slider': 'adjustment', + }, + wake: { + 'auto-wake': 'switch', + 'wake-max-timer': 'adjustment', + 'wake-slider': 'adjustment', + 'nonlinear-wake-slider': 'adjustment', + }, + display: { + 'show-settings': 'switch', + 'show-shutdown-mode': 'buffer', + 'show-shutdown-slider': 'switch', + 'show-textboxes': 'switch', + 'show-wake-slider': 'switch', + 'show-wake-items': 'switch', + }, + check: { + 'check-command': 'textbuffer', + 'enable-check-command': 'switch', + }, +}; + +/** + * + * @param pageId + * @param builder + * @param settings + * @param handlers + */ +function initPage(pageId, builder, settings, handlers) { + const page = builder.get_object(pageId); + const pageName = pageId.split('_').at(-1); + if (!page) { + throw new Error(`${pageId} not found!`); + } + + const connectComp = (baseName, component) => { + const baseId = baseName.replaceAll('-', '_'); + const settingsName = `${baseName}-value`; + const compId = `${baseId}_${component}`; + const comp = builder.get_object(compId); + if (!comp) { + throw new Error(`Component not found in template: ${compId}`); + } + if (compId === 'shutdown_mode_combo') { + // replace combo box entries + comp.remove_all(); + MODES.forEach(mode => { + comp.append(mode, modeLabel(mode)); + }); + } + + settings.bind( + settingsName, + comp, + { + adjustment: 'value', + switch: 'active', + textbuffer: 'text', + buffer: 'text', + combo: 'active-id', + }[component], + Gio.SettingsBindFlags.DEFAULT + ); + + if (compId === 'show_shutdown_mode_buffer') { + builder + .get_object(`${baseId}_entry`) + .set_placeholder_text( + `${MODES.join(',')} (${MODES.map(modeLabel).join(', ')})` + ); + } + }; + + if (pageName in templateComponents) { + for (const [k, v] of Object.entries(templateComponents[pageName])) { + connectComp(k, v); + } + } + + const lineIter = (buffer, lineIndex) => { + const [ok, iter] = buffer.get_iter_at_line(lineIndex); + if (!ok) { + throw new Error(`Line ${lineIndex} not found!`); + } + return iter; + }; + + if (pageName === 'check') { + // check command textbuffer + const checkCommandBuffer = builder.get_object('check_command_textbuffer'); + const commentTag = new Gtk.TextTag({ foreground: 'grey' }); + checkCommandBuffer.get_tag_table().add(commentTag); + const applyCommentTags = b => { + b.remove_tag(commentTag, b.get_start_iter(), b.get_end_iter()); + const lc = b.get_line_count(); + for (let i = 0; i < lc; i++) { + const startIter = lineIter(b, i); + const endIter = lc === i + 1 ? b.get_end_iter() : lineIter(b, i + 1); + const line = b.get_text(startIter, endIter, false); + if (line.trimLeft().startsWith('#')) { + b.apply_tag(commentTag, startIter, endIter); + } + } + }; + applyCommentTags(checkCommandBuffer); + handlers.push([ + checkCommandBuffer, + checkCommandBuffer.connect('changed', applyCommentTags), + ]); + } else if (pageName === 'install') { + // install log textbuffer updates + const logTextBuffer = builder.get_object('install_log_textbuffer'); + const scrollAdj = builder.get_object('installer_scrollbar_adjustment'); + const errorTag = new Gtk.TextTag({ foreground: 'red' }); + const successTag = new Gtk.TextTag({ foreground: 'green' }); + logTextBuffer.get_tag_table().add(errorTag); + logTextBuffer.get_tag_table().add(successTag); + const appendLogLine = line => { + line = ['[', '#'].includes(line[0]) ? line : ` ${line}`; + logTextBuffer.insert(logTextBuffer.get_end_iter(), `${line}\n`, -1); + const lastLineIndex = logTextBuffer.get_line_count() - 1; + const applyTag = tag => { + logTextBuffer.apply_tag( + tag, + lineIter(logTextBuffer, lastLineIndex - 1), + lineIter(logTextBuffer, lastLineIndex) + ); + }; + if (line.startsWith('# ')) { + applyTag(errorTag); + } else if (line.endsWith('🟢')) { + applyTag(successTag); + } + guiIdle(() => scrollAdj.set_value(1000000)); + }; + + const installSwitch = builder.get_object('install_policy_switch'); + installSwitch.set_active(Install.checkInstalled()); + const switchHandlerId = installSwitch.connect('notify::active', () => + Install.installAction( + installSwitch.get_active() ? 'install' : 'uninstall', + message => guiIdle(() => message.split('\n').forEach(appendLogLine)) + ) + ); + handlers.push([installSwitch, switchHandlerId]); + + // clear log + guiIdle(() => logTextBuffer.set_text('', -1)); + } + return page; +} + +/** + * + * @param window + */ +function fillPreferencesWindow(window) { + const builder = Gtk.Builder.new(); + builder.add_from_file( + Me.dir.get_child('ui').get_child('prefs.ui').get_path() + ); + + const settings = ExtensionUtils.getSettings(); + const handlers = []; + const pageNames = ['install', 'shutdown', 'wake', 'display', 'check'].map( + n => `shutdowntimer-prefs-${n}` + ); + enableGuiIdle(); + for (const page of pageNames.map(name => + initPage(name.replaceAll('-', '_'), builder, settings, handlers) + )) { + window.add(page); + } + const selPageName = + pageNames[settings.get_int('preferences-selected-page-value')]; + if (selPageName) { + window.set_visible_page_name(selPageName); + } + const pageVisHandlerId = window.connect('notify::visible-page-name', () => { + logDebug(window.get_visible_page_name()); + settings.set_int( + 'preferences-selected-page-value', + pageNames.indexOf(window.get_visible_page_name()) + ); + }); + handlers.push([window, pageVisHandlerId]); + // release all resources on destroy + const destroyId = window.connect('destroy', () => { + disableGuiIdle(); + handlers.forEach(([comp, handlerId]) => { + comp.disconnect(handlerId); + }); + Install.reset(); + window.disconnect(destroyId); + }); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/gschemas.compiled b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..9af400a925827a6a8cebf5ac2b7f18afb3a7c628 GIT binary patch literal 1820 zcmah~O^6&t7_F$Q$tIdL*@RIOY)piikm^|>3o96mBx@q%unN%#D%N(_%rx8G)pphF zHWEWX^kRe@6NsSbAwlpIK~clTAM_yJ3?iPyizjmmxk!AkdS-vz6&K#VH?O|>s=Dgy zua7>j%0%T(4E`G6leKQ%F*Ly=JA}B6zk2Mrk9i6H&(&*xF^u{#aZH@!k2{6f05WAa z?B*uZq3!834Rz&oZWEJR7=0I;h1?~XE@iB_25cK(I~ZFR%t`G2{_F(fxX0~cUNpdu0xzF>`Wk)et?;M72LZh(UZGD- ze+GO4n7VN3UHa7H@C$GS9R2vWY5LUn!#@YU2u!xVdxSpqPWYdJzXE=}{=?h!sUL#> z3-}M~_06!l7 zU>D=5nP(#|Yz&ao`}WbNeh~fycoMkw^?_4ZQx9xtHfc@sU!_#Cy=s8 z;)8oLR7Jg{nBml&(!uBicgW$DR8dR;xW(?Wt^zgbeC$u=Rqv{=q7+YjlB%zi@qWR zd-J^jO4#>7_B-}L_CvgKz8`{o?_*CyyYT&UcqhIzt;5yTOY)szUFuxTrdqCZ)66z_ zKHN=5mpaE4VE?I(oQ`Fox~tv~1S8+-68qmeUfSN;NWVOC#;veWt~dDE#z&^@KQe9q Zk!de~WMHiKk!jatZM)O literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/org.gnome.shell.extensions.shutdowntimer-deminder.gschema.xml b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/org.gnome.shell.extensions.shutdowntimer-deminder.gschema.xml new file mode 100644 index 0000000..c55da2a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/schemas/org.gnome.shell.extensions.shutdowntimer-deminder.gschema.xml @@ -0,0 +1,135 @@ + + + + + + 180 +

Maximum shutdown time (in minutes) + Set maximum selectable shutdown time of the slider (in minutes). Use only values greater zero. + + + + 1440 + Maximum wake time (in minutes) + Set maximum selectable wake time of the slider (in minutes). Use only values greater zero. + + + + false + Automatically start and stop wake on shutdown timer toggle + Enable/Disable the wake alarm when the shutdown timer is started/stopped. + + + + -1 + Scheduled shutdown timestamp. + Unix time in seconds of scheduled shutdown or -1 if disabled. + + + + 70 + Wake slider position (in percent) + Set wake slider position as percent of the maximum time. Must be in range 0 and 100. + + + + 1.5 + Ramp-up of non-linear wake slider value + Exponential ramp-up for wake time slider + + + + 70 + Shutdown slider position (in percent) + Set shutdown slider position as percent of the maximum time. Must be in range 0 and 100. + + + + 0 + Ramp-up of non-linear shutdown slider value + Exponential ramp-up for shutdown time slider + + + + true + Show settings button + Show/hide settings button in widget. + + + + true + Show shutdown slider + Show/hide shutdown slider in widget. + + + + true + Show wake slider + Show/hide wake slider in widget. + + + + false + Show all wake items + Show/hide all wake items in widget. + + + + true + Show notification text boxes + Show/hide notification text boxes on screen. + + + + false + Root mode + Set root mode on/off. In root mode powering off is done via 'pkexec' and 'shutdown' terminal command. + + + + true + Show end-session dialog + Show the end-session dialog for reboot and shutdown if screensaver is inactive. + + + + "poweroff,suspend" + Shown shutdown modes + Comma-separated shutdown modes which are shown in the popup menu + + + + "poweroff" + Use mode + Mode to use for timer action + + + + "# Examples ... + +# Run a pre-shutdown script (e.g. updates or backups) +# ~/.local/scripts/pre-shutdown.sh + +# Wait for a process to exit +# tail -f --pid=$PID + +# Activate the screen saver +# xdg-screensaver activate" + Check command(s) + Run command(s) before shutdown command. Proceed with shutdown only if check command succeeds. + + + + true + Enable check command + Check command is skipped if disabled. + + + + 0 + Last selected page in the preferences. + Last selected page in the preferences. + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/stylesheet.css b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/stylesheet.css new file mode 100644 index 0000000..092263c --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/stylesheet.css @@ -0,0 +1,28 @@ +/** + AUTHOR: Daniel Neumann +**/ + +.textbox-label { + font-size: 2em; + font-weight: bold; + color: #ffffff; + background-color: rgba(10, 10, 10, 0.7); + border-radius: 0.5em; + padding: 0.5em; +} + +.settings-button { + padding: 4px; + border-radius: 32px; + margin: 1px; +} + +.settings-button:hover, +.settings-button:focus { + padding: 5px; + margin: 0px; +} + +.settings-button > StIcon { + icon-size: 15px; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/installer.sh b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/installer.sh new file mode 100644 index 0000000..0b2fa8a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/installer.sh @@ -0,0 +1,261 @@ +#!/bin/bash + +# installer.sh - This script installs a policykit rule for the Shutdown Timer gnome-shell extension. +# +# This file is part of the gnome-shell extension ShutdownTimer@Deminder. + +# Authors: Martin Koppehel , Fin Christensen (cpupower extension), Deminder + +set -e + +################################ +# EXTENSION SPECIFIC OPTIONS: # +################################ + +EXTENSION_NAME="Shutdown Timer" +ACTION_BASE="dem.shutdowntimer" +RULE_BASE="$ACTION_BASE.settimers" +CFC_BASE="shutdowntimerctl" +POLKIT_DIR="polkit" +VERSION=1 + + +EXIT_SUCCESS=0 +EXIT_INVALID_ARG=1 +EXIT_FAILED=2 +EXIT_NEEDS_UPDATE=3 +EXIT_NEEDS_SECURITY_UPDATE=4 +EXIT_NOT_INSTALLED=5 +EXIT_MUST_BE_ROOT=6 + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #stackoverflow 59895 + +export TEXTDOMAINDIR="$DIR/../locale" +export TEXTDOMAIN="ShutdownTimer" +function gtxt() { + gettext "$1" +} + +function recent_polkit() { + printf -v versions '%s\n%s' "$(pkaction --version | cut -d' ' -f3)" "0.106" + if [[ $versions != "$(sort -V <<< "$versions")" ]];then + echo "available" + else + echo "unavailable" + fi +} + +function check_support() { + RECENT_STR=", stand-alone polkit rules $(recent_polkit)" + if which rtcwake >/dev/null 2>&1 + then + echo "rtcwake supported${RECENT_STR}" + exit ${EXIT_SUCCESS} + else + echo "rtcwake unsupported${RECENT_STR}" + exit ${EXIT_FAILED} + fi +} + +function fail() { + echo "$(gtxt "Failed")${1}" >&2 && exit ${EXIT_FAILED} +} +DEFAULT_SUCCESS_MSG=$(gtxt 'Success') + +function success() { + echo -n "${1:-$DEFAULT_SUCCESS_MSG}" + echo -e "\U1F7E2" +} + + + +######################## +# GENERALIZED SCRIPT: # +######################## + +function usage() { + echo "Usage: installer.sh [options] {supported,install,check,update,uninstall}" + echo + echo "Available options:" + echo " --tool-user USER Set the user of the tool (default: \$USER)" + echo + exit ${EXIT_INVALID_ARG} +} + +if [ $# -lt 1 ] +then + usage +fi + +ACTION="" +TOOL_USER="$USER" +while [[ $# -gt 0 ]] +do + key="$1" + + # we have to use command line arguments here as pkexec does not support + # setting environment variables + case $key in + --tool-user) + TOOL_USER="$2" + shift + shift + ;; + supported|install|check|update|uninstall) + if [ -z "$ACTION" ] + then + ACTION="$1" + else + echo "Too many actions specified. Please give at most 1." + usage + fi + shift + ;; + *) + echo "Unknown argument $key" + usage + ;; + esac +done + + +CFC_DIR="/usr/local/bin" +RULE_DIR="/etc/polkit-1/rules.d" + +RULE_IN="${DIR}/../${POLKIT_DIR}/10-$RULE_BASE.rules" +if [[ "$(recent_polkit)" != "available" ]];then + RULE_IN="${RULE_IN}.legacy" + ACTION_IN="${DIR}/../${POLKIT_DIR}/${ACTION_BASE}.policy.in" +fi +TOOL_IN="${DIR}/$CFC_BASE" + +TOOL_OUT="${CFC_DIR}/${CFC_BASE}-${TOOL_USER}" +RULE_OUT="${RULE_DIR}/10-${RULE_BASE}-${TOOL_USER}.rules" +ACTION_ID="${RULE_BASE}.${TOOL_USER}" +ACTION_OUT="/usr/share/polkit-1/actions/${ACTION_ID}.policy" + +function print_policy_xml() { + sed -e "s:{{PATH}}:${TOOL_OUT}:g" \ + -e "s:{{ACTION_BASE}}:${ACTION_BASE}:g" \ + -e "s:{{ACTION_ID}}:${ACTION_ID}:g" "${ACTION_IN}" +} + +function print_rules_javascript() { + if [[ "$RULE_IN" == *.legacy ]]; then + sed -e "s:{{RULE_BASE}}:${RULE_BASE}:g" "${RULE_IN}" + else + sed -e "s:{{TOOL_OUT}}:${TOOL_OUT}:g" \ + -e "s:{{TOOL_USER}}:${TOOL_USER}:g" "${RULE_IN}" + fi + +} + +if [ "$ACTION" = "supported" ] +then + check_support +fi + +if [ "$ACTION" = "check" ] +then + if ! print_rules_javascript | cmp --silent "${RULE_OUT}" + then + if [ -f "${ACTION_OUT}" ] + then + echo "Your $EXTENSION_NAME installation needs updating!" + exit ${EXIT_NEEDS_UPDATE} + else + echo "Not installed" + exit ${EXIT_NOT_INSTALLED} + fi + fi + echo "Installed" + + exit ${EXIT_SUCCESS} +fi + +TOOL_NAME=$(basename ${TOOL_OUT}) + +if [ "$ACTION" = "install" ] +then + if [ "${EUID}" -ne 0 ]; then + echo "The install action must be run as root for security reasons!" + echo "Please have a look at https://github.com/martin31821/cpupower/issues/102" + echo "for further details." + exit ${EXIT_MUST_BE_ROOT} + fi + + echo -n "$(gtxt 'Installing') ${TOOL_NAME} $(gtxt 'tool')... " + mkdir -p "${CFC_DIR}" + install "${TOOL_IN}" "${TOOL_OUT}" || fail + success + + if [ ! -z "$ACTION_IN" ];then + echo "$(gtxt 'Using legacy policykit install')..." + echo -n "$(gtxt 'Installing') $(gtxt 'policykit action')..." + (print_policy_xml > "${ACTION_OUT}" 2>/dev/null && chmod 0644 "${ACTION_OUT}") || fail + success + fi + + echo -n "$(gtxt 'Installing') $(gtxt 'policykit rule')..." + mkdir -p "${RULE_DIR}" + (print_rules_javascript > "${RULE_OUT}" 2>/dev/null && chmod 0644 "${RULE_OUT}") || fail + success + + exit ${EXIT_SUCCESS} +fi + +if [ "$ACTION" = "update" ] +then + "${BASH_SOURCE[0]}" --tool-user "${TOOL_USER}" uninstall || exit $? + "${BASH_SOURCE[0]}" --tool-user "${TOOL_USER}" install || exit $? + + exit ${EXIT_SUCCESS} +fi + +if [ "$ACTION" = "uninstall" ] +then + LEG_CFG_OUT="/usr/bin/shutdowntimerctl-$TOOL_USER" + if [ -f "$LEG_CFG_OUT" ] + then + # remove legacy "tool" install + echo -n "$(gtxt 'Uninstalling') $(gtxt 'tool')..." + rm "${LEG_CFG_OUT}" || fail " - $(gtxt 'cannot remove') ${LEG_CFG_OUT}" && success + fi + + if [ -f "$ACTION_OUT" ] + then + # remove legacy "policykit action" install + echo -n "$(gtxt 'Uninstalling') $(gtxt 'policykit action')..." + rm "${ACTION_OUT}" || fail " - $(gtxt 'cannot remove') ${ACTION_OUT}" && success + fi + LEG_RULE_OUT="/usr/share/polkit-1/rules.d/10-dem.shutdowntimer.settimers.rules" + if [ -f "$LEG_RULE_OUT" ] + then + # remove legacy "policykit action" install + echo -n "$(gtxt 'Uninstalling') $(gtxt 'policykit rule')..." + rm "${LEG_RULE_OUT}" || fail " - $(gtxt 'cannot remove') ${LEG_RULE_OUT}" && success + fi + + echo -n "$(gtxt 'Uninstalling') ${TOOL_NAME} $(gtxt 'tool')... " + if [ -f "${TOOL_OUT}" ] + then + rm "${TOOL_OUT}" || fail " - $(gtxt 'cannot remove') ${TOOL_OUT}" && success + else + echo "$(gtxt 'tool') $(gtxt 'not installed at') ${TOOL_OUT}" + fi + + echo -n "$(gtxt 'Uninstalling') $(gtxt 'policykit rule')... " + if [ -f "${RULE_OUT}" ] + then + rm "${RULE_OUT}" || fail " - $(gtxt 'cannot remove') ${RULE_OUT}" && success + else + echo "$(gtxt 'policy rule') $(gtxt 'not installed at') ${RULE_OUT}" + fi + + exit ${EXIT_SUCCESS} +fi + +echo "Unknown parameter." +usage + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/shutdowntimerctl b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/shutdowntimerctl new file mode 100644 index 0000000..f11c673 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/tool/shutdowntimerctl @@ -0,0 +1,53 @@ +#!/bin/bash + +# shutdowntimerctl - This script can configure the shutdown and rtc wake alarm schedule. +# +# This file is part of the gnome-shell extension ShutdownTimer@Deminder. + +SHUTDOWN_BIN=/usr/sbin/shutdown +RTCWAKE_BIN=/usr/sbin/rtcwake + +SHUTDOWN_MODE="-P" +if [ ! -z "$2" ] && [ "$2" -gt 0 ];then + POSITIVE_VALUE="$2" +fi + +function print_help() { + echo "[help] (show this help)" >&2 + echo "[shutdown|reboot] {MINUTES}" >&2 + echo "[wake|wake-cancel] {MINUTES} (default: 0)" >&2 +} + +if [ "$#" -lt 1 ]; then + print_help + exit +fi + +case "$1" in + shutdown|reboot) + if [[ "$1" = "reboot" ]]; then + SHUTDOWN_MODE="-r" + fi + $SHUTDOWN_BIN "$SHUTDOWN_MODE" "$POSITIVE_VALUE" + ;; + shutdown-cancel) + $SHUTDOWN_BIN -c + ;; + wake|wake-cancel) + if [ -z "$POSITIVE_VALUE" ];then + $RTCWAKE_BIN --mode disable + else + $RTCWAKE_BIN --date +${POSITIVE_VALUE}min --mode on & + PID=$! + sleep 0.2 + kill $PID + fi + ;; + -h|help) + print_help + ;; + *) + echo "Invalid argument: $1" >&2 + print_help +esac + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/ui/prefs.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/ui/prefs.ui new file mode 100644 index 0000000..be8197f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/ShutdownTimer@deminder/ui/prefs.ui @@ -0,0 +1,456 @@ + + + + + START test +. +. +. +. +. +. +. +. +. +. +. +. +DONE test + + + + 1000000 + 1 + 10 + + + -5 + 5 + 0.001 + 0.10 + + + -5 + 5 + 0.001 + 0.10 + + + + 10000 + 1 + 10 + + + 100 + 0.1 + 10 + + + 10000 + 1 + 10 + + + 100 + 0.1 + 10 + + + shutdowntimer-prefs-install + Install + go-up-symbolic + + + + + 1 + Install/Uninstall privileges for this user + Setup a privileged script and give user access via polkit + + + center + + + + + + + Install output + + + 1 + installer_scrollbar_adjustment + 350 + + + 1 + 5 + 0 + char + 0 + install_log_textbuffer + 0 + 1 + + + + + + + + + + + shutdowntimer-prefs-shutdown + Shutdown + preferences-system-time-symbolic + + + Timer Action + + + Use mode + Mode to use for timer action + + + center + 0 + + Shutdown + Suspend + Reboot + (replaced in code) + + + + + + + + Show end-session dialog + Shown for reboot and shutdown if screensaver is inactive + + + center + + + + + + + Toggle root shutdown with shutdown timer + Runs extra 'shutdown -P/-r' command for shutdown or reboot + + + center + + + + + + + + + Timer Input + + + Shutdown slider position (in &#37;) + + + 1 + center + shutdown_slider_adjustment + 1 + 1 + 1 + 1 + if-valid + + + + + + + Shutdown slider position (in &#37;) + + + 1 + center + 1 + shutdown_slider_adjustment + 1 + 1 + 1 + + + + + + + Non-linear scaling or 0 to disable + + + 1 + center + nonlinear_shutdown_slider_adjustment + 1 + 3 + 1 + 1 + if-valid + 120 + + + + + + + Maximum shutdown timer value (in minutes) + + + 1 + center + shutdown_max_timer_adjustment + 1 + 1 + 1 + if-valid + 120 + + + + + + + + + shutdowntimer-prefs-wake + Wake + alarm-symbolic + + + Timer Action + + + 1 + Toggle wake with timer action + + + 1 + center + + + + + + + + + Timer Input + + + Wake slider position (in &#37;) + + + 1 + center + wake_slider_adjustment + 1 + 1 + 1 + 1 + if-valid + + + + + + + Wake slider position (in &#37;) + + + 1 + center + 1 + wake_slider_adjustment + 1 + 1 + 1 + + + + + + + Non-linear scaling or 0 to disable + + + 1 + center + nonlinear_wake_slider_adjustment + 1 + 3 + 1 + 1 + if-valid + 120 + + + + + + + Maximum wake timer value (in minutes) + + + 1 + center + wake_max_timer_adjustment + 1 + 1 + 1 + if-valid + 120 + + + + + + + + + shutdowntimer-prefs-display + Display + preferences-color-symbolic + + + General + + + 1 + Show settings button + + + center + + + + + + + 1 + Show notification text boxes + + + center + 1 + + + + + + + + + Shutdown + + + Show shutdown items + Comma-separated shutdown modes which are shown in the popup menu + + + + + Show shutdown items + + + center + show_shutdown_mode_buffer + poweroff, reboot, suspend + + + + + + + 1 + Show shutdown slider + + + center + + + + + + + + + Wake + + + 1 + Show wake items + + + center + + + + + + + 1 + Show wake slider + + + center + + + + + + + + + shutdowntimer-prefs-check + Check + emblem-ok-symbolic + + + + + 1 + Enable check + Script is run in a bash user shell after timer activates. Timer action proceeds if check terminates successfully. + + + center + + + + + + + Check script + + + 1 + 350 + + + 1 + 5 + check_command_textbuffer + 1 + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/LICENSE b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/LICENSE new file mode 100644 index 0000000..d7f1051 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/LICENSE @@ -0,0 +1,339 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/extension.js new file mode 100644 index 0000000..40df84a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/extension.js @@ -0,0 +1,564 @@ +const {Clutter, Gio, St, GObject} = imports.gi; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; +const Main = imports.ui.main; +const Util = imports.misc.util; +const Mainloop = imports.mainloop; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Sensors = Me.imports.sensors; +const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); +const _ = Gettext.gettext; +const MessageTray = imports.ui.messageTray; +const Values = Me.imports.values; +const Config = imports.misc.config; +const MenuItem = Me.imports.menuItem; + +let vitalsMenu; + +var VitalsMenuButton = GObject.registerClass({ + GTypeName: 'VitalsMenuButton', +}, class VitalsMenuButton extends PanelMenu.Button { + _init() { + super._init(St.Align.START); + + this._settings = ExtensionUtils.getSettings('org.gnome.shell.extensions.vitals'); + + this._sensorIcons = { + 'temperature' : { 'icon': 'temperature-symbolic.svg' }, + 'voltage' : { 'icon': 'voltage-symbolic.svg' }, + 'fan' : { 'icon': 'fan-symbolic.svg' }, + 'memory' : { 'icon': 'memory-symbolic.svg' }, + 'processor' : { 'icon': 'cpu-symbolic.svg' }, + 'system' : { 'icon': 'system-symbolic.svg' }, + 'network' : { 'icon': 'network-symbolic.svg', + 'icon-rx': 'network-download-symbolic.svg', + 'icon-tx': 'network-upload-symbolic.svg' }, + 'storage' : { 'icon': 'storage-symbolic.svg' }, + 'battery' : { 'icon': 'battery-symbolic.svg' } + } + + this._warnings = []; + this._sensorMenuItems = {}; + this._hotLabels = {}; + this._hotIcons = {}; + this._groups = {}; + this._widths = {}; + this._last_query = new Date().getTime(); + + this._sensors = new Sensors.Sensors(this._settings, this._sensorIcons); + this._values = new Values.Values(this._settings, this._sensorIcons); + this._menuLayout = new St.BoxLayout({ + vertical: false, + clip_to_allocation: true, + x_align: Clutter.ActorAlign.START, + y_align: Clutter.ActorAlign.CENTER, + reactive: true, + x_expand: true, + pack_start: false + }); + + this._drawMenu(); + this.add_actor(this._menuLayout); + this._settingChangedSignals = []; + this._refreshTimeoutId = null; + + this._addSettingChangedSignal('update-time', this._updateTimeChanged.bind(this)); + this._addSettingChangedSignal('position-in-panel', this._positionInPanelChanged.bind(this)); + + let settings = [ 'use-higher-precision', 'alphabetize', 'hide-zeros', 'fixed-widths', 'hide-icons', 'unit', 'memory-measurement', 'include-public-ip', 'network-speed-format', 'storage-measurement' ]; + for (let setting of Object.values(settings)) + this._addSettingChangedSignal(setting, this._redrawMenu.bind(this)); + + // add signals for show- preference based categories + for (let sensor in this._sensorIcons) + this._addSettingChangedSignal('show-' + sensor, this._showHideSensorsChanged.bind(this)); + + this._initializeMenu(); + + // start off with fresh sensors + this._querySensors(); + + // start monitoring sensors + this._initializeTimer(); + } + + _initializeMenu() { + // display sensor categories + for (let sensor in this._sensorIcons) { + // groups associated sensors under accordion menu + if (sensor in this._groups) continue; + + this._groups[sensor] = new PopupMenu.PopupSubMenuMenuItem(_(this._ucFirst(sensor)), true); + this._groups[sensor].icon.gicon = Gio.icon_new_for_string(Me.path + '/icons/' + this._sensorIcons[sensor]['icon']); + + // hide menu items that user has requested to not include + if (!this._settings.get_boolean('show-' + sensor)) + this._groups[sensor].actor.hide(); + + if (!this._groups[sensor].status) { + this._groups[sensor].status = this._defaultLabel(); + this._groups[sensor].actor.insert_child_at_index(this._groups[sensor].status, 4); + this._groups[sensor].status.text = 'No Data'; + } + + this.menu.addMenuItem(this._groups[sensor]); + } + + // add separator + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + + let item = new PopupMenu.PopupBaseMenuItem({ + reactive: false, + style_class: 'vitals-menu-button-container' + }); + + let customButtonBox = new St.BoxLayout({ + style_class: 'vitals-button-box', + vertical: false, + clip_to_allocation: true, + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER, + reactive: true, + x_expand: true, + pack_start: false + }); + + // custom round refresh button + let refreshButton = this._createRoundButton('view-refresh-symbolic', _('Refresh')); + refreshButton.connect('clicked', (self) => { + // force refresh by clearing history + this._sensors.resetHistory(); + this._values.resetHistory(); + + // make sure timer fires at next full interval + this._updateTimeChanged(); + + // refresh sensors now + this._querySensors(); + }); + customButtonBox.add_actor(refreshButton); + + // custom round monitor button + let monitorButton = this._createRoundButton('org.gnome.SystemMonitor-symbolic', _('System Monitor')); + monitorButton.connect('clicked', (self) => { + this.menu._getTopMenu().close(); + Util.spawn([this._settings.get_string('monitor-cmd')]); + }); + customButtonBox.add_actor(monitorButton); + + // custom round preferences button + let prefsButton = this._createRoundButton('preferences-system-symbolic', _('Preferences')); + prefsButton.connect('clicked', (self) => { + this.menu._getTopMenu().close(); + ExtensionUtils.openPrefs(); + }); + customButtonBox.add_actor(prefsButton); + + // now add the buttons to the top bar + item.actor.add_actor(customButtonBox); + + // add buttons + this.menu.addMenuItem(item); + + // query sensors on menu open + this._menuStateChangeId = this.menu.connect('open-state-changed', (self, isMenuOpen) => { + if (isMenuOpen) { + // make sure timer fires at next full interval + this._updateTimeChanged(); + + // refresh sensors now + this._querySensors(); + } + }); + } + + _createRoundButton(iconName) { + let button = new St.Button({ + style_class: 'message-list-clear-button button vitals-button-action' + }); + + button.child = new St.Icon({ + icon_name: iconName + }); + + return button; + } + + _removeMissingHotSensors(hotSensors) { + for (let i = hotSensors.length - 1; i >= 0; i--) { + let sensor = hotSensors[i]; + + // make sure default icon (if any) stays visible + if (sensor == '_default_icon_') continue; + + // removes sensors that are no longer available + if (!this._sensorMenuItems[sensor]) { + hotSensors.splice(i, 1); + this._removeHotLabel(sensor); + this._removeHotIcon(sensor); + } + } + + return hotSensors; + } + + _saveHotSensors(hotSensors) { + // removes any sensors that may not currently be available + hotSensors = this._removeMissingHotSensors(hotSensors); + + this._settings.set_strv('hot-sensors', hotSensors.filter( + function(item, pos) { + return hotSensors.indexOf(item) == pos; + } + )); + } + + _initializeTimer() { + // used to query sensors and update display + let update_time = this._settings.get_int('update-time'); + this._refreshTimeoutId = Mainloop.timeout_add_seconds(update_time, (self) => { + // only update menu if we have hot sensors + if (Object.values(this._hotLabels).length > 0) + this._querySensors(); + + // keep the timer running + return true; + }); + } + + _createHotItem(key, value) { + let icon = this._defaultIcon(key); + this._hotIcons[key] = icon; + this._menuLayout.add_actor(icon) + + // don't add a label when no sensors are in the panel + if (key == '_default_icon_') return; + + let label = new St.Label({ + style_class: 'vitals-panel-label', + text: (value)?value:'\u2026', // ... + y_expand: true, + y_align: Clutter.ActorAlign.START + }); + + // attempt to prevent ellipsizes + label.get_clutter_text().ellipsize = 0; + + this._hotLabels[key] = label; + + // support for fixed widths #55, save label (text) width + this._widths[key] = label.width; + + this._menuLayout.add_actor(label); + } + + _showHideSensorsChanged(self, sensor) { + this._sensors.resetHistory(); + this._groups[sensor.substr(5)].visible = this._settings.get_boolean(sensor); + } + + _positionInPanelChanged() { + this.container.get_parent().remove_actor(this.container); + let position = this._positionInPanel(); + + // allows easily addressable boxes + let boxes = { + left: Main.panel._leftBox, + center: Main.panel._centerBox, + right: Main.panel._rightBox + }; + + // update position when changed from preferences + boxes[position[0]].insert_child_at_index(this.container, position[1]); + } + + _removeHotLabel(key) { + if (key in this._hotLabels) { + let label = this._hotLabels[key]; + delete this._hotLabels[key]; + // make sure set_label is not called on non existant actor + label.destroy(); + } + } + + _removeHotLabels() { + for (let key in this._hotLabels) + this._removeHotLabel(key); + } + + _removeHotIcon(key) { + if (key in this._hotIcons) { + this._hotIcons[key].destroy(); + delete this._hotIcons[key]; + } + } + + _removeHotIcons() { + for (let key in this._hotIcons) + this._removeHotIcon(key); + } + + _redrawMenu() { + this._removeHotIcons(); + this._removeHotLabels(); + + for (let key in this._sensorMenuItems) { + if (key.includes('-group')) continue; + this._sensorMenuItems[key].destroy(); + delete this._sensorMenuItems[key]; + } + + this._drawMenu(); + this._sensors.resetHistory(); + this._values.resetHistory(); + this._querySensors(); + } + + _drawMenu() { + // grab list of selected menubar icons + let hotSensors = this._settings.get_strv('hot-sensors'); + for (let key of Object.values(hotSensors)) { + // fixes issue #225 which started when _max_ was moved to the end + if (key == '__max_network-download__') key = '__network-rx_max__'; + if (key == '__max_network-upload__') key = '__network-tx_max__'; + + this._createHotItem(key); + } + } + + _destroyTimer() { + // invalidate and reinitialize timer + if (this._refreshTimeoutId != null) { + Mainloop.source_remove(this._refreshTimeoutId); + this._refreshTimeoutId = null; + } + } + + _updateTimeChanged() { + this._destroyTimer(); + this._initializeTimer(); + } + + _addSettingChangedSignal(key, callback) { + this._settingChangedSignals.push(this._settings.connect('changed::' + key, callback)); + } + + _updateDisplay(label, value, type, key) { + // update sensor value in menubar + if (this._hotLabels[key]) { + this._hotLabels[key].set_text(value); + + // support for fixed widths #55 + if (this._settings.get_boolean('fixed-widths')) { + // grab text box width and see if new text is wider than old text + let width2 = this._hotLabels[key].get_clutter_text().width; + if (width2 > this._widths[key]) { + this._hotLabels[key].set_width(width2); + this._widths[key] = width2; + } + } + } + + // have we added this sensor before? + let item = this._sensorMenuItems[key]; + if (item) { + // update sensor value in the group + item.value = value; + } else if (type.includes('-group')) { + // update text next to group header + let group = type.split('-')[0]; + if (this._groups[group]) { + this._groups[group].status.text = value; + this._sensorMenuItems[type] = this._groups[group]; + } + } else { + // add item to group for the first time + let sensor = { 'label': label, 'value': value, 'type': type } + this._appendMenuItem(sensor, key); + } + } + + _appendMenuItem(sensor, key) { + let split = sensor.type.split('-'); + let type = split[0]; + let icon = (split.length == 2)?'icon-' + split[1]:'icon'; + let gicon = Gio.icon_new_for_string(Me.path + '/icons/' + this._sensorIcons[type][icon]); + + let item = new MenuItem.MenuItem(gicon, key, sensor.label, sensor.value, this._hotLabels[key]); + item.connect('toggle', (self) => { + let hotSensors = this._settings.get_strv('hot-sensors'); + + if (self.checked) { + // add selected sensor to panel + hotSensors.push(self.key); + this._createHotItem(self.key, self.value); + } else { + // remove selected sensor from panel + hotSensors.splice(hotSensors.indexOf(self.key), 1); + this._removeHotLabel(self.key); + this._removeHotIcon(self.key); + } + + if (hotSensors.length <= 0) { + // add generic icon to panel when no sensors are selected + hotSensors.push('_default_icon_'); + this._createHotItem('_default_icon_'); + } else { + let defIconPos = hotSensors.indexOf('_default_icon_'); + if (defIconPos >= 0) { + // remove generic icon from panel when sensors are selected + hotSensors.splice(defIconPos, 1); + this._removeHotIcon('_default_icon_'); + } + } + + // this code is called asynchronously - make sure to save it for next round + this._saveHotSensors(hotSensors); + }); + + this._sensorMenuItems[key] = item; + let i = Object.keys(this._sensorMenuItems[key]).length; + + // alphabetize the sensors for these categories + if (this._settings.get_boolean('alphabetize')) { + let menuItems = this._groups[type].menu._getMenuItems(); + for (i = 0; i < menuItems.length; i++) + // use natural sort order for system load, etc + if (menuItems[i].label.localeCompare(item.label, undefined, { numeric: true, sensitivity: 'base' }) > 0) + break; + } + + this._groups[type].menu.addMenuItem(item, i); + } + + _defaultLabel() { + return new St.Label({ + y_expand: true, + y_align: Clutter.ActorAlign.CENTER + }); + } + + _defaultIcon(key) { + let split = key.replaceAll('_', ' ').trim().split(' ')[0].split('-'); + let type = split[0]; + + let icon = new St.Icon({ + style_class: 'system-status-icon vitals-panel-icon-' + type, + reactive: true + }); + + // second condition prevents crash due to issue #225, which started when _max_ was moved to the end + if (type == 'default' || !(type in this._sensorIcons)) { + icon.gicon = Gio.icon_new_for_string(Me.path + '/icons/' + this._sensorIcons['system']['icon']); + } else if (!this._settings.get_boolean('hide-icons')) { // support for hide icons #80 + let iconObj = (split.length == 2)?'icon-' + split[1]:'icon'; + icon.gicon = Gio.icon_new_for_string(Me.path + '/icons/' + this._sensorIcons[type][iconObj]); + } + + return icon; + } + + _ucFirst(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + } + + _positionInPanel() { + let alignment = ''; + let gravity = 0; + let arrow_pos = 0; + + switch (this._settings.get_int('position-in-panel')) { + case 0: // left + alignment = 'left'; + gravity = -1; + arrow_pos = 1; + break; + case 1: // center + alignment = 'center'; + gravity = -1; + arrow_pos = 0.5; + break; + case 2: // right + alignment = 'right'; + gravity = 0; + arrow_pos = 0; + break; + case 3: // far left + alignment = 'left'; + gravity = 0; + arrow_pos = 1; + break; + case 4: // far right + alignment = 'right'; + gravity = -1; + arrow_pos = 0; + break; + } + + // set arrow position when initializing and moving vitals + this.menu._arrowAlignment = arrow_pos; + + return [alignment, gravity]; + } + + _querySensors() { + // figure out last run time + let now = new Date().getTime(); + let dwell = (now - this._last_query) / 1000; + this._last_query = now; + + this._sensors.query((label, value, type, format) => { + let key = '_' + type.replace('-group', '') + '_' + label.replace(' ', '_').toLowerCase() + '_'; + + // if a sensor is disabled, gray it out + if (key in this._sensorMenuItems) { + this._sensorMenuItems[key].setSensitive((value!='disabled')); + + // don't continue below, last known value is shown + if (value == 'disabled') return; + } + + let items = this._values.returnIfDifferent(dwell, label, value, type, format, key); + for (let item of Object.values(items)) + this._updateDisplay(_(item[0]), item[1], item[2], item[3]); + }, dwell); + + if (this._warnings.length > 0) { + this._notify('Vitals', this._warnings.join("\n"), 'folder-symbolic'); + this._warnings = []; + } + } + + _notify(msg, details, icon) { + let source = new MessageTray.Source('MyApp Information', icon); + Main.messageTray.add(source); + let notification = new MessageTray.Notification(source, msg, details); + notification.setTransient(true); + source.notify(notification); + } + + destroy() { + this._destroyTimer(); + + for (let signal of Object.values(this._settingChangedSignals)) + this._settings.disconnect(signal); + + super.destroy(); + } +}); + +function init() { + ExtensionUtils.initTranslations('vitals'); +} + +function enable() { + vitalsMenu = new VitalsMenuButton(); + let position = vitalsMenu._positionInPanel(); + Main.panel.addToStatusArea('vitalsMenu', vitalsMenu, position[1], position[0]); +} + +function disable() { + vitalsMenu.destroy(); + vitalsMenu = null; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/file.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/file.js new file mode 100644 index 0000000..594325f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/file.js @@ -0,0 +1,85 @@ +const GLib = imports.gi.GLib; +const Gio = imports.gi.Gio; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +Me.imports.helpers.polyfills; +const ByteArray = imports.byteArray; + +function getcontents(filename) { + let handle = Gio.File.new_for_path(filename); + let contents = handle.load_contents(null)[1]; + return ByteArray.toString(contents).trim(); +} + +function File(path) { + if (path.indexOf('https://') == -1) + this.file = Gio.File.new_for_path(path); + else + this.file = Gio.File.new_for_uri(path); +} + +File.prototype.read = function(delimiter = '', strip_header = false) { + return new Promise((resolve, reject) => { + try { + this.file.load_contents_async(null, function(file, res) { + try { + // grab contents of file or website + let contents = file.load_contents_finish(res)[1]; + + // convert contents to string + contents = ByteArray.toString(contents).trim(); + + // split contents by delimiter if passed in + if (delimiter) contents = contents.split(delimiter); + + // optionally strip header when converting to a list + if (strip_header) contents.shift(); + + // return results + resolve(contents); + } catch (e) { + reject(e.message); + } + }); + } catch (e) { + reject(e.message); + } + }); +}; + +File.prototype.list = function() { + return new Promise((resolve, reject) => { + let max_items = 125, results = []; + + try { + this.file.enumerate_children_async(Gio.FILE_ATTRIBUTE_STANDARD_NAME, Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_LOW, null, function(file, res) { + try { + let enumerator = file.enumerate_children_finish(res); + + let callback = function(enumerator, res) { + try { + let files = enumerator.next_files_finish(res); + for (let i = 0; i < files.length; i++) { + results.push(files[i].get_attribute_as_string(Gio.FILE_ATTRIBUTE_STANDARD_NAME)); + } + + if (files.length == 0) { + enumerator.close_async(GLib.PRIORITY_LOW, null, function(){}); + resolve(results); + } else { + enumerator.next_files_async(max_items, GLib.PRIORITY_LOW, null, callback); + } + } catch (e) { + reject(e.message); + } + }; + + enumerator.next_files_async(max_items, GLib.PRIORITY_LOW, null, callback); + } catch (e) { + reject(e.message); + } + }); + } catch (e) { + reject(e.message); + } + }); +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/polyfills.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/polyfills.js new file mode 100644 index 0000000..1ad274f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/helpers/polyfills.js @@ -0,0 +1,184 @@ +if (!String.prototype.includes) { + String.prototype.includes = function(search, start) { + 'use strict'; + + if (typeof start !== 'number') + start = 0; + + if (start + search.length > this.length) + return false; + else + return this.indexOf(search, start) !== -1; + } +} + +// in parts of the system you may think that we can use Object.values +// instead of "key in" statements. Gnome 3.18 - 3.22 doesn't like doing that. +if (!Object.values) + Object.values = obj => Object.keys(obj).map(key => obj[key]); + +if (!Math.getMaxOfArray) { + Math.getMaxOfArray = function(numArray) { + return Math.max.apply(null, numArray); + } +} + +// newer verisons of Gnome have Promises built in +// Credit goes to https://github.com/satya164/gjs-helpers +if (typeof Promise === 'undefined') { + const GLib = imports.gi.GLib; + + const PENDING = 0, + FULFILLED = 1, + REJECTED = 2; + + Promise = function(executor) { + if (false === (this instanceof Promise)) { + throw new TypeError("Promises must be constructed via new"); + } + + if (typeof executor !== "function") { + throw new TypeError("Promise resolver " + executor + " is not a function"); + } + + // Create an array to add handlers + this._deferreds = []; + + // Set the promise status + this._state = PENDING; + this._caught = false; + + this._handle = deferred => { + if (this._state === PENDING) { + this._deferreds.push(deferred); + + return; + } + + GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1, () => { + let cb = this._state === FULFILLED ? deferred.onFulfilled : deferred.onRejected; + + if (cb === null) { + (this._state === FULFILLED ? deferred.resolve : deferred.reject)(this._value); + + return false; + } + + if (typeof cb !== "function") { + deferred.reject(this._value); + + return false; + } + + let ret; + + try { + ret = cb(this._value); + } catch (e) { + deferred.reject(e); + + return false; + } + + deferred.resolve(ret); + + return false; // Don't repeat + }); + }; + + let doresolve = (fn, onFulfilled, onRejected) => { + let done = false; + + try { + fn(value => { + if (done) { + return; + } + + done = true; + + onFulfilled(value); + }, function(reason) { + if (done) return; + done = true; + onRejected(reason); + }); + } catch (e) { + if (done) return; + done = true; + onRejected(e); + } + }; + + let finale = () => { + for (var i = 0, len = this._deferreds.length; i < len; i++) { + this._handle.call(this, this._deferreds[i]); + } + + this._deferreds = null; + }; + + let resolve = value => { + // Call all fulfillment handlers one by one + try { + if (value === this) { + throw new TypeError("A promise cannot be resolved with itself"); + } + + if (value && (typeof value === "object" || typeof value === "function")) { + // If returned value is a thenable, treat is as a promise + if (typeof value.then === "function") { + doresolve(value.then.bind(value), resolve.bind(this), reject.bind(this)); + + return; + } + } + + // Promise is fulfilled + this._state = FULFILLED; + this._value = value; + + finale.call(this); + } catch (e) { + reject.call(this, e); + } + }; + + let reject = reason => { + // Promise is rejected + this._state = REJECTED; + this._value = reason; + + finale.call(this); + }; + + doresolve(executor, resolve.bind(this), reject.bind(this)); + }; + + // Appends fulfillment and rejection handlers to the promise + Promise.prototype.then = function(onFulfilled, onRejected) { + return new Promise((resolve, reject) => { + this._handle.call(this, { + resolve: resolve, + reject: reject, + onFulfilled: onFulfilled, + onRejected: onRejected + }); + }); + }; + + // Appends a rejection handler callback to the promise + Promise.prototype.catch = function(onRejected) { + return this.then(null, onRejected); + }; + + // Returns a Promise object that is rejected with the given reason + Promise.reject = function(reason) { + return new Promise((resolve, reject) => reject(reason)); + }; + + // Returns a Promise object that is resolved with the given value + Promise.resolve = function(value) { + return new Promise(resolve => resolve(value)); + }; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/battery-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/battery-symbolic.svg new file mode 100644 index 0000000..70df9ee --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/battery-symbolic.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/cpu-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/cpu-symbolic.svg new file mode 100644 index 0000000..19969e4 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/cpu-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/fan-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/fan-symbolic.svg new file mode 100644 index 0000000..a584b74 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/fan-symbolic.svg @@ -0,0 +1,133 @@ + + + + + + + + image/svg+xml + + Gnome Symbolic Icon Theme + + + + + + + Gnome Symbolic Icon Theme + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/memory-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/memory-symbolic.svg new file mode 100644 index 0000000..13ca4bc --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/memory-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-download-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-download-symbolic.svg new file mode 100644 index 0000000..5cab840 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-download-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-symbolic.svg new file mode 100644 index 0000000..0483417 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-upload-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-upload-symbolic.svg new file mode 100644 index 0000000..e2c5a08 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/network-upload-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/storage-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/storage-symbolic.svg new file mode 100644 index 0000000..9832999 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/storage-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/system-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/system-symbolic.svg new file mode 100644 index 0000000..909f530 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/system-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/temperature-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/temperature-symbolic.svg new file mode 100644 index 0000000..c58beca --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/temperature-symbolic.svg @@ -0,0 +1,45 @@ + +image/svg+xml \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/voltage-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/voltage-symbolic.svg new file mode 100644 index 0000000..b2e7eff --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/icons/voltage-symbolic.svg @@ -0,0 +1,125 @@ + + + + + + + + image/svg+xml + + Gnome Symbolic Icon Theme + + + + + + + Gnome Symbolic Icon Theme + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/ca/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/ca/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..5a18109cbbec78b561fb686e4b07a33e3380dded GIT binary patch literal 3343 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 Nt7HHlYrP~w{{!LoK0N>c literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/fi_FI/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/fi_FI/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..38454e3df1fc067585e343ab4af5fc7527d3a6b3 GIT binary patch literal 4004 zcmb7`ON<;x8Gs820k6X&4zJiiDh3A!duAVg;EW$(9eeHdYe(L-iG@g1J5#$;Gd*2R zSM}Hv2_=yNNKr&kB*+1Yhq711i9Nt^xS&Y6AwZyT$bmy71cC#KIPm>FJ-cxdAJUrY zuO5H@_5XkURW+~gy6Z=Z=M?4hlzTp?)H3|vhj{Uv|FBa0)FQ7Pa0%WAZ&d9*{0Qxv z@Gkf?7YE6#2)Y$bYNqZ^KW~?pEVZL(%^n6nkEPV*kr4n_a3;V$@U#n++e z`B&BcFBCg>5_GZuUMTso8;bvRDDxew#up*3sjE=tc>;=^0gC)HQ2c!!ioTcN1MnwR z|8FafAXBSX;b-8Vq1gLRD0=TEX+_^2D0=omnYRvQz6SgPJO@S2LXq=O_RlRSdHWJ% zIm$=cGgbWrlzF~P*;Dl$gc1vR#1=Ux_EY94^3*7GimaDBk5I%Wc_e0yvPP_+*d~wI zB+pkU4^qT-d8R23m9_EuNQ~udlHC3(TD4;TaJwP>(Q#N=2v|Y)qIlpmWj4a zE$f(78{Jb@2b%_;2Q@!1E-|Z#rDk)pZq;cQgF5Yfi0bq(+Mph@X|%a|%;#3`YpVs5 zss(FeK{L1CE^LTF`&_RU>)}z|Osol34_t6jpD?J27UVF+IKRVy9TGw|sxP zg}Rn+yL5f}x{D?W(=G&*?LBqQ#q-7LiD`4HuCI7~)8x5Ht~6x z?fSbX+16Z6)b=Uf*RxKx_tcrPE~>R#(?ehAHD9D{9Xl@QBG|PesjCH__f1p_xwZ1b z!?ZP2=WI%R5_R6St$xbpUJp!yy=pOSB?Wz1v6{G+UTkX9Zi}7jl3k1Hk~eKVd!%1g zD$>4e`#vA4%RY4xf7S@=q~5=MD7EpX&wE?LS?*it_xV;&K!dE^L_rvaXqlqYO+CYS zS+cFZfls1*a-~wfl-X1-xCD=yCU#V_GYqbU!%fdpI-hEn>dd5;9@f<6L`7uBw&)et zx042jH7CJPS1tZCw;k7_XRWEO5upwYHXo3hSKWFis%0`FZ3j(`-n5ugWNkhS^pBHu z`KHO#^4PaAbmgL2A<+z<&bOi)*sbPDIoE#_+I5@DXAM2oT&i8QlK4KYo#6|*E}0N(E2M8o z3`^9|XA@^IGEcoe8+tZzDQ=#CCe-bu0XV0e0Jj8>sH6)!N!xUEIT$ihtD)=lsb*5Jn`*MxLPMun*$gM=j_YytN8`x;SFW3#99V&Rl!65j8IJ(|*e??!Dn?vpq}_$3;8ZsH@8bTbgyu zj7beqA4mU2V&w!-P3IC$DjkO%BFd_=TpWjE&m^L{TO_^muvl!?%4k}Y1>5hNa*c7O z?_v?ko95zntFN{ja_1C;!SQ7>@H$pY93{V`qhF3rTKpX#wI(eI7wMC333H4mHcbok zC1xTu$wQV$7NXM2+Vr#0<~syaj$^V}q{^8j+1vcmT-mHHYzI$qG8?10x!F(C!S)LD-PWnD zySzu3O7q9tZprm*8Run@$8P@LlrnM^rFuaAvDNrse!MI3+jW>mU8weD8IRjrDSsaZ zoYHvEi_XctVf6B7gQ=X%y;|7`2 nrIoxyfc+9ljp6(fQ8ltPBs&br_ndH&q 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/it/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/it/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..8d9429bc295b38efe5c5c69c08dadfcdcd9bd2d2 GIT binary patch literal 3076 zcmb7_OKe;<6ow776b8zpJPK_AH_)c9naNBk3TcxPB~6)vIA5Wh;EPoA-d~|$EJb>s*q4wAyy#7rV=a=n@R{ISn!`ao(WMUB&_&;e$Dam z@$sLZwrzTcp;SK(coZq~D(h?*m^49|hk9Y29bw9pDv^)?E$!2BiJI1MdQV z0Pg{R2JZ!b2k!?rV-fYYgET(~lK;4mjid_Q9&gH;Q!M(8edFWrqp=jN&Af4|9KA2*EgAak53tjs= zK^i{_QXD5iI#)d~0%;!$Qe4*pFM#Cthv38DC*ULCwJ?7jBzu2=bp9Hz9qRJvcrYgR5vD|I9t8*iA*v+*P`k?=A`D{YB}^lD9VC$%#cYgU9x zL?e-CNh_L?O-SvfWfR6qz9(i=LbE9;e1@)-uVm7B$BpHUtm%&PS|Wv$d__6s`7yy; z*nV`N<$dZ#%H^i=t*lXsOuHPxTx4RUo8?92MdHfJIT#xlJE{DstZ}R?#!CE*;j6-0 zp?&8Nm*-L|os%(br`l$ZWFiFA91ii zSJgA%I?hXM5p1KK!g;!~{@991JpJTMFkTbB#cHjNQxQ&CGq^uxG*_CZLQ9PFH?8#! z%I2h#b_IzvrpTFgrbaV%?caX{az^@PstB>ZI_+%X7Y*CPL|> zJZcH+q#s?VPZfvP*O5zjw#5^=`$k6ia08Z~FLu)~_qAqZj7L^2RZCA7YDtFdEK=^e z5w6p`>qe_bdAB*bPxIZQys{tv8Ty)lXK$s)OGj{VY+SkNse@o=Egq-jB3a5MA~GB~ z#8nUq#U_ruO`Y{d+b-?oDd_GH4W4+*s z;ci7G)a9|_xuggVT|wU921!lC|9a*%(W!|fSCB&C44z7+1#b!jbxjHAh|6_EaMM+h z2>MfkJI$uFstvCdW~8;oDjo|QxT!@VtUS&aN!H-7z@um?7>#8@v1>~2afs|@FaJyN zHb`BN9m8f+1M1RKo;AUO^5CfoM-NPq@{n&jOA;0INAYA(Va}?xHA5lt2V3?-K6UOP~{=&D%QV$ zJ1A__Qn=eSy5#kZu-?IA*%m=L6kd#Nt4OV{!434X11f|Ru1O2scZeIVC=$7V<#ur^ z*k5R9SYp;yOftj>O4g0hoFXBE1h7e@9b(m$GHh&-IEmt-*;K}Ak!MHGEjAyCc0-vU zVtm{~(p0aPYZ-bZY!EVN+SL!(f>#OMP_H34rDnTp9{)pn8YkJ=D9Tdus2*Mc`v=^q B0CE5T literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/nl/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/nl/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..476fd4dbf5977666c50a67dae4d4aa0f9e86763d GIT binary patch literal 6980 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/oc/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/oc/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..ef097f71c3e1d4538c744db7f6052fd45b96bee5 GIT binary patch literal 3817 zcmb7_TWlRi8Gxq{E_DlS!!0e)4uQ1L^!S!0O-~Y6jvXgPNqz7omSM{@p#c(>4zs z?d&)A|DS*U`R9-O_dTmfQ{)ekZ-0wYOYqgV@*|yln^Jsgp5Lu-0lo)*rl}|J9n{z1 zKKLZ$Q%^ViDttTjZ$KIM9F(Ph0AGSvoBk^dlKEeTBIg+>gx`mE!)s8+{T99x zz5r$1iw*w-`PAR|-3I>&-wj`Zcfea2d>6bMO8qdD{u5C4^~t9FbC6G^{6^p!6uDo7 zBKJ#B*7-UVIX{HA!=FIW|CbGa-S7n{>-+)oslV`(b^ZY{f%*^p0DJ}Vsr__{ynCSR z=RPQU-rw*jd>8duDDxMgj9-N^{^nVWC$=P3pqW@3n zly!auKL&pTW&Gcp_WweW_bOzHx`jn#{7A#QpvXA@WuAtAg@=dz7)$g%0BKV9LK*)c z6hEAV_re7z`lJmnLy`AX!>={`78Lt^555on42s|U4!$401V0G>-Sppq@eWWw1ZDgb z6u(@CVy{&w_D-Pa`31NiJ_Y&Iv;4$gu0ql8=TP?feAE7WDE{^5ru|<~^!^_dJMClf zkHFiY%x^(ye+0_7DJc4%g<_x8hGEm6Lm9sTMXxJO{hLtq|1Okut~LAxlzl!A#cyAP zw?Ii!AFoPEorE%9&Rpyz=^?V%K$5H>=ksy$Bw136JW7`HlJqE9be1GGYF8ztj>8W( zWzkL217xuS$5N#+{`WU!*_YTrVw3pVgXD+FV&{9v5)X#yJ_-k$ik!FjlGx`E`7l|N zA0Zzlf0Qg|bA)_?{0Z_fiBE7u)!9p%oJ|u7)hWtc5j8=UB>r}+D)F1{W~EotahwIl z+mKQ|FkS1TO{<+vT~;_Xy=J1=bYn}&7N&32>Bu{EI?J3_r#HNHYR0DC7HTFdtUeT~ zIg_e6YkWzyuuqiMd8e~NcgwzeOm|{yoYiZQi@ZK*^q{c4QwIm$=dL|A){p$4?2ZOm zG8V90kcCm&AG;WN6T7jq${a${F&{d!h>ey2MxvViroVyDHif}GuO0k`42MMSeU zC3aXrvChyKYSFTPWZSyrGtQb~4+{;Tv&9;&xft~aUM=AfY3MXQx^7XY%tIzR z+G}TBS~s~`s`pkyH(ON8IGSPVbl{^kyHj1R#MS>546RmjFPg46+4~BfIzX~5G@cdU zvso&Qp}N>u=hH>xadT0>F4p?9>q|E9t@*HZ(H1hTtw%Zwtwk%2pQWu?X3%urINw^v zeO+ugqPG4N&g3yWq@@rL{9G^JenwV@& zKB_0i+mpu*k57z`kF2(8x36^XWH#hdA3>4TR$XbG=CbFwOIweQ?zS#jQv?HXqtFWo05PUXMLi_LJ`{36xzhSD&z(R*%i1l|&iB>;1CXST093BVV{g<=zO&1O*}4UH!J^s+QS zYZDVpz0M>YzkKD|V;Y}vC0E^VzCKdE>2N$_a*@?H5|N|O)G;|qC?c{7$pP};d{8c` zn9OzbMb;Hv%@gJJbzQR2oq&8k>SBc|B5(hg%^Ed~$%GLJ96U&|apG^hY})9}?X4oK z? zdlGxv4Q`ga!RW#g;r347jpKWo(b6V~>6^`ncZ(pkr!Uhka(;U&xj_#@BpAl`8#+)> z!k8?wi0s*{TSTI_)7+Io#IErzlMs%=2TTxbZ#gwb_zJ3!FV2MbO32^d8pizE?oKTu z(1|Db!UVo@?LEPNk9Fn24LOt8_VE!n=4>B5ZfH}4>=L)##Nq4rfa^0$I3BPW+vi-F zU)_M}bdgt&76nEB;bmH4OG#HP4J|Z${B}&n tslALCc`n3?o#7*)6BFq^mmoB11s_FuU%weLY`8(ZvcS-<+4fGW`ajgu!dCzQ literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pl/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pl/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..0c3ba947355114544e3cd8fabc6fb23a4687bda2 GIT binary patch literal 3543 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/pt_BR/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..6fb58f59d7ad991d3dea7779741a34d882a13e5e GIT binary patch literal 3654 zcmb7`O^h7H6~~Lj#9{b0AK@#cyn$eYduDbQV|(x}*vX5cmsF6z-(LsP{2aUnJOq;7#{w5X{MagP^xY;1Q`xV;pMVL7AA1}(n*V7KOR;A`()anm zKZDnz|2jzDzYCK5`yk1G7{)&aZ$|&q@cwHMKlTl7PyT?he}eS=R;3(&0wnooK(gbH zAkFtONb_F+N&by6{x(SSy%+i)g7+gvJ`Usm#v~+v1)M?i?FFfS6G-da4*nFZg5-}C zkmNQ&OuJgTfjF#^5b7X+K(^7__rX*Uj?U;9e07G_x`|x zAno%ch#xzN+pXX_Ncx-$?1QwQPX#^)(ma0v$&NpPWXHQ8+4(_u{}D**e*%)eUk3gI zB)L5pqnPvN zTh-X~YB8pZO`>$Cc1C%Tx|(thlTFMnDgS8RI$jgARes9wEn%(DesGA(^O=>-$%K|u zy)0ESseX5notcY;5~E>vHS1;*vnPsYnwqONADEoCO|BE}yUOw0$#$Mr*`l#M;n|{< zl5Vh2#{;$`H9V8DM^z&EwzP)#MGAe{vX0XnV_DuxRm_*0TqFtU$yQ|BvlSx}K6$to z9s}-; zY;G(@M|b4N3T$(9QkQ45!H>3-ubhp_@Gs0;@?%^1bai?P>zs|6MkdNf^Emt&BB{Zv z)k-tXabhAmPp-jrR&?FW)Wf`doH?NRET25M^ZB|IHttd=M)gKGVAXT(dj%#Nqx7|# z#1tHZsCB!&pN3M#t2QE@VtrS+2OGR6b-s*awA)mN8^})BZ3>p%WFCUTaaZ<)tCecy zs>0Sy3x{%!l5--!cA1)m4aVVgoKP+^dU&CaQ@A>OHBsX7>}<_AJ1-cMB3UmPq=cL& zh9iCP{_wR&_*`a`6%A%$e>9KF@ zp|Y+>Y#Y)aHW!B%7HIQbh5uKjxunE|bZ^*->SHI0gg<-@8VI&jB>dBHj!bDO8d0)b zk^9S}uPm23K~fyPVkqxt!*{3z7lXXDAZ$la_E&oJyz^L$q6!S(v{)=8IxG~I zTevfTa&WnfmB~1jM2Klnn?V z_N_#4ph9#|r;UTdJ^pu~log_7(1iMdqq2d*1mR2VBMn9-kID!Rd|yC5R27dhqR=g> h3F-(1UQnMT4T=Ue__QY!qOq(du$=~>W+*2;_FuEor#1ip literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/ru/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/ru/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..21039f2b77e5c1c566e680d7f63f13f2605d43ed GIT binary patch literal 3116 zcmZ{kTWl0n7{?FZt@kV9je|-Bao61i4K6GO5wr>D28xly2dBHI?C5r8otZ5beE@1S z1|pGYyd+pLL|-%lcI8r9^v%SVGchqSMql*B2NQhJM1Ao0&CIrfbh>AL=lXsB?>pc0 zr)w{GOY!7sx6<~^QK|y}Igc05>GPGk5dID?g@3~9;G7H6@eS}I#`EFDuotpL<+J$` zeYmhlZJe%^(b!4Ke-@Dq3yoPgKBZ?f@^ z+4^r#^!}60UrjJ#S3~i$2+Fx46uWDn=zJpM7AX5`Q1(9u`KgH4T(}*|`aXyY^&S+R zV^H*c1o^2>#tC>m|X@$g-c-(K9kMwgOdOKQ2ZUuXrb8q70UTPvhf@SxKLNZYvJ5% zd=C_VOW}?1VJLBK$=1DWybWsR_dq%SX~r+1#QiN4{lCK7;a^a6%p=$m?1eJkl5r4< z-w-Zw- z#8>voB;Qdl;~Y)Cg(Wn3wTxLi}w#@os5h(m?1wHQ5$^E zjr>3l;^CDh z@_1&v+87Dl8Ua@Q(2ZQ*)2^pmj%Sz&%%BO#0?}5deOJ5js*PrlcpES@!7wS`=x%L9 zYLlt?UOm+0ew#6#Znx@ONXUG837fV#Eww3CnnGuSRlgshWOFD2H-|Hpe`25r3aQ2iiJYYQ@OP4617#| z)ZIvz@}>MTR?=baVJ9>#Cu)>+KHpPqwyDvaRB%|TUr zYUvghREkCYkS=JpGhS6Gb(dCFmPt1`QCL|l>6czgkE|*#Tg;InM@oxV%qZDpoS@dI zq9s=-XJ1GD+3=hjiskONINOd=S+099oNaw6g8j%Hq-LdBXWh4~tcQ%(?&BMn&D8y6 z%~evB*qLq50|>4)%#ah_m&$6pJ<7hX?WuT&owA?vK4eew*HQMJc&9zZL~}_+{Ql?6G*4?6oJcY^UNK@m@P_Pl(kw8Sdo7C<|iE zeq=j#l8GJ4erCr-hWrP!@3CXTc4YdXSU?kwls$m;DSMbUo}T|$gkRB;}S|gtBkrl$7I9 zl*_afX}21YDz%$TB)YluQ4Ea7yESolh-y3@)fhaSnUz~hE?ur7Ju*pbN$%vpWH-4rm6($1BlG(()8UJts%QIn&Rjt0ak(I!6toDVONELYi6eepvpgjg$Xh-e QYJz;E8pV%P-r2YJFQ4E}lmGw# literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/sk/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/sk/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..520430835714c03ef882660ec10ac99e3bf16eed GIT binary patch literal 8624 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 keyzoSV$R?nquZ-Vv6bF5Y`p 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 G^Zpm&rM+1I literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/zh_CN/LC_MESSAGES/vitals.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/locale/zh_CN/LC_MESSAGES/vitals.mo new file mode 100644 index 0000000000000000000000000000000000000000..5c43dc8aecb27bcaa8d9175a890487684db4dcb2 GIT binary patch literal 7963 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 { + this._settings.set_boolean(sensor, val); + }); + } + + // process individual drop down sensor preferences + sensors = [ 'position-in-panel', 'unit', 'network-speed-format', 'memory-measurement', 'storage-measurement', 'battery-slot' ]; + for (let key in sensors) { + let sensor = sensors[key]; + + widget = this.builder.get_object(sensor); + widget.set_active(this._settings.get_int(sensor)); + widget.connect('changed', (widget) => { + this._settings.set_int(sensor, widget.get_active()); + }); + } + + this._settings.bind('update-time', this.builder.get_object('update-time'), 'value', Gio.SettingsBindFlags.DEFAULT); + + // process individual text entry sensor preferences + sensors = [ 'storage-path', 'monitor-cmd' ]; + for (let key in sensors) { + let sensor = sensors[key]; + + widget = this.builder.get_object(sensor); + widget.set_text(this._settings.get_string(sensor)); + + widget.connect('changed', (widget) => { + let text = widget.get_text(); + if (!text) text = widget.get_placeholder_text(); + this._settings.set_string(sensor, text); + }); + } + + // makes individual sensor preference boxes appear + sensors = [ 'temperature', 'network', 'storage', 'memory', 'battery', 'system' ]; + for (let key in sensors) { + let sensor = sensors[key]; + + // create dialog for intelligent autohide advanced settings + this.builder.get_object(sensor + '-prefs').connect('clicked', () => { + let transientObj; + if (shellVersion < 40) + transientObj = this.widget.get_toplevel(); + else + transientObj = this.widget.get_root(); + + let title = sensor.charAt(0).toUpperCase() + sensor.slice(1); + let dialog = new Gtk.Dialog({ title: _(title + ' Preferences'), + transient_for: transientObj, + use_header_bar: false, + modal: true }); + + let box = this.builder.get_object(sensor + '_prefs'); + + if (shellVersion < 40) + dialog.get_content_area().add(box); + else + dialog.get_content_area().append(box); + + dialog.connect('response', (dialog, id) => { + // remove the settings box so it doesn't get destroyed; + dialog.get_content_area().remove(box); + dialog.destroy(); + return; + }); + + dialog.show(); + }); + } + } +}); + +function init() { + ExtensionUtils.initTranslations(); +} + +function buildPrefsWidget() { + let settings = new Settings(); + let widget = settings.widget; + + widget.show(); + return widget; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.legacy.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.legacy.ui new file mode 100644 index 0000000..b61ea2c --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.legacy.ui @@ -0,0 +1,1669 @@ + + + + + + 1 + 60 + 1 + 10 + + + True + False + 12 + 12 + vertical + + + True + False + 0 + in + + + True + False + none + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + Include public IP address + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + Format + + + True + True + 0 + + + + + True + False + 0 + + Bytes + Bits + + + + False + True + end + 1 + + + + + + + + + + + + + + False + True + 0 + + + + + False + 6 + 6 + 6 + 6 + vertical + 2 + + + True + False + True + True + True + + + True + False + 12 + 9 + 12 + 12 + vertical + 12 + + + True + False + start + baseline + General + + + + + + False + True + 0 + + + + + True + False + 0 + out + + + True + False + none + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Seconds between updates + + + True + True + 0 + + + + + True + True + 5 + 5 + 2 + 2 + number + update-time-params + 1 + True + True + if-valid + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Position in panel + + + True + True + 0 + + + + + True + False + 5 + 0 + + Left + Center + Right + Far Left + Far Right + + + + False + True + end + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Use higher precision + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Alphabetize sensors + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Hide zero values + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Use fixed widths + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + 5 + Hide icons in top bar + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + + + + + + False + True + 1 + + + + + True + False + start + baseline + About + + + + + + False + True + 2 + + + + + True + False + 0 + out + + + True + False + start + baseline + 5 + 0 + Feature requests or bugs? Please visit <a href="https://github.com/corecoding/Vitals/issues">GitHub</a>. No warranty, expressed or implied. <a href="https://corecoding.com/donate.php">Donate</a> if you found this useful. + True + True + 0 + + + + + + + + False + True + 3 + + + + + False + True + 0 + + + + + True + False + 6 + 9 + 12 + 12 + vertical + 12 + + + True + False + start + baseline + Sensors + + + + + + False + True + 6 + + + + + True + False + 0 + out + + + True + False + + + True + False + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor temperature + + + True + True + 0 + + + + + True + False + 6 + + + True + True + True + center + center + 0.46000000834465027 + + + True + False + emblem-system-symbolic + + + + + + False + True + 0 + + + + + True + True + end + center + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor voltage + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor fan + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor memory + + + True + True + 0 + + + + + True + False + 6 + + + True + True + True + center + center + 0.46000000834465027 + + + True + False + emblem-system-symbolic + + + + + + False + True + 0 + + + + + True + True + end + center + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor processor + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor system + + + True + True + 0 + + + + + True + False + 6 + + + True + True + True + center + center + 0.46000000834465027 + + + True + False + emblem-system-symbolic + + + + + + False + True + 0 + + + + + True + True + end + center + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor network + + + True + True + 0 + + + + + True + False + 6 + + + True + True + True + center + center + 0.46000000834465027 + + + True + False + emblem-system-symbolic + + + + + + False + True + 0 + + + + + True + True + end + center + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor storage + + + True + True + 0 + + + + + True + False + 6 + + + True + True + True + center + center + 0.46000000834465027 + + + True + False + emblem-system-symbolic + + + + + + False + True + 0 + + + + + True + True + end + center + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + 100 + True + True + False + + + True + False + center + 6 + 6 + + + True + False + start + 5 + Monitor battery + + + True + True + 0 + + + + + True + False + 6 + + + True + True + True + center + center + 0.46000000834465027 + + + True + False + emblem-system-symbolic + + + + + + False + True + 0 + + + + + True + True + end + center + + + False + True + 1 + + + + + False + True + 1 + + + + + + + + + + + + + + + + False + True + 7 + + + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + 12 + 12 + vertical + + + True + False + 0 + in + + + True + False + none + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + Monitor command + + + True + True + 0 + + + + + True + True + gnome-system-monitor + + + False + True + 1 + + + + + + + + + + + + + + False + True + 0 + + + + + True + False + 12 + 12 + vertical + + + True + False + 0 + in + + + True + False + none + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + Path + + + True + True + 0 + + + + + True + True + / + + + False + True + 1 + + + + + + + + + 100 + True + True + 0 + False + + + True + False + center + 6 + 6 + + + True + False + start + Measurement + + + True + True + 0 + + + + + True + False + 0 + + Binary + Decimal + + + + False + True + end + 1 + + + + + + + + + + + + + + False + True + 0 + + + + + True + False + 12 + 12 + vertical + + + True + False + 0 + in + + + True + False + none + + + 100 + True + True + 0 + False + + + True + False + center + 6 + 6 + + + True + False + start + Unit + + + True + True + 0 + + + + + True + False + 0 + + °C + °F + + + + False + True + end + 1 + + + + + + + + + + + + + + False + True + 0 + + + + + True + False + 12 + 12 + vertical + + + True + False + 0 + in + + + True + False + none + + + 100 + True + True + 0 + False + + + True + False + center + 6 + 6 + + + True + False + start + Measurement + + + True + True + 0 + + + + + True + False + 0 + + Binary + Decimal + + + + False + True + end + 1 + + + + + + + + + + + + + + False + True + 0 + + + + + True + False + 12 + 12 + vertical + + + True + False + 0 + in + + + True + False + none + + + 100 + True + True + False + + + True + False + 6 + 6 + + + True + False + start + Display battery + + + True + True + 0 + + + + + True + False + 0 + + BAT0 + BAT1 + BAT2 + CMB0 + + + + False + True + end + 1 + + + + + + + + + + + + + + False + True + 0 + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.ui new file mode 100644 index 0000000..9489261 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/prefs.ui @@ -0,0 +1,1111 @@ + + + + + 1 + 60 + 1 + 10 + + + 0 + 12 + 12 + 6 + 6 + vertical + + + 0 + + + 0 + none + + + 100 + 1 + 0 + + + 0 + 6 + 6 + 6 + 6 + 12 + + + 1 + 0 + start + Include public IP address + + + + + end + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + 6 + 6 + + + 1 + 0 + start + Format + + + + + 0 + 0 + + Bytes + Bits + + + + + + + + + + + + + + 0 + 0 + 6 + 6 + 6 + 6 + vertical + 2 + + + 0 + 1 + 1 + 1 + + + 0 + 12 + 9 + 12 + 12 + vertical + 12 + + + 0 + start + baseline + General + + + + + + + + 0 + + + 0 + none + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Seconds between updates + + + + + 5 + 5 + 0 + 2 + update-time-params + 1 + 1 + 1 + if-valid + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Position in panel + + + + + 0 + 5 + 0 + + Left + Center + Right + Far Left + Far Right + + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Use higher precision + + + + + end + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Alphabetize sensors + + + + + end + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Hide zero values + + + + + end + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Use fixed widths + + + + + end + + + + + + + + + 100 + 0 + + + 0 + 6 + 6 + + + 1 + 0 + start + 5 + Hide icons in top bar + + + + + end + + + + + + + + + + + + + + + + 0 + start + baseline + About + + + + + + + + 0 + + + 0 + start + baseline + 5 + Feature requests or bugs? Please visit <a href="https://github.com/corecoding/Vitals/issues">GitHub</a>. No warranty, expressed or implied. <a href="https://corecoding.com/donate.php">Donate</a> if you found this useful. + 1 + 1 + 0 + + + + + + + + + + + + 0 + 6 + 9 + 12 + 12 + vertical + 12 + + + 0 + start + baseline + Sensors + + + + + + + + 0 + + + 0 + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor temperature + + + + + 0 + 6 + + + 1 + center + center + + + 0 + emblem-system-symbolic + + + + + + + + end + center + + + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor voltage + + + + + end + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor fan + + + + + end + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor memory + + + + + 0 + 6 + + + 1 + center + center + + + 0 + emblem-system-symbolic + + + + + + + + end + center + + + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor processor + + + + + end + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor system + + + + + 0 + 6 + + + 1 + center + center + + + 0 + emblem-system-symbolic + + + + + + + + end + center + + + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor network + + + + + 0 + 6 + + + 1 + center + center + + + 0 + emblem-system-symbolic + + + + + + + + end + center + + + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor storage + + + + + 0 + 6 + + + 1 + center + center + + + 0 + emblem-system-symbolic + + + + + + + + end + center + + + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + + + 1 + 0 + start + 5 + Monitor battery + + + + + 0 + 6 + + + 1 + center + center + + + 0 + emblem-system-symbolic + + + + + + + + end + center + + + + + + + + + + + + + + + + + + + + + + 1 + 12 + 12 + 6 + 6 + vertical + + + 1 + + + 1 + none + + + 100 + 1 + 0 + + + 1 + 6 + 6 + 6 + 6 + 12 + + + 1 + 1 + start + Path + + + + + / + 1 + 1 + 24 + + + + + + + + + 100 + 0 + + + 0 + center + 6 + 6 + 6 + 6 + + + 1 + 0 + start + Measurement + + + + + 0 + 0 + + Binary + Decimal + + + + + + + + + + + + + + 0 + 12 + 12 + 6 + 6 + vertical + + + 0 + + + 0 + none + + + 100 + 1 + 0 + + + 0 + 6 + 6 + 6 + 6 + 12 + + + 1 + 0 + start + Unit + + + + + 0 + 0 + end + + °C + °F + + + + + + + + + + + + + + 0 + 12 + 12 + 6 + 6 + vertical + + + 0 + + + 0 + none + + + 100 + 1 + 0 + + + 0 + 6 + 6 + 6 + 6 + 12 + + + 1 + 0 + start + Measurement + + + + + 0 + 0 + + Binary + Decimal + + + + + + + + + + + + + + 0 + 12 + 12 + 6 + 6 + vertical + + + 0 + + + 0 + none + + + 100 + 1 + 0 + + + 0 + 6 + 6 + 6 + 6 + 12 + + + 1 + 0 + start + Display Battery + + + + + 0 + 0 + + BAT0 + BAT1 + BAT2 + CMB0 + + + + + + + + + + + + + + 1 + 12 + 12 + 6 + 6 + vertical + + + 1 + + + 1 + none + + + 100 + 1 + 0 + + + 1 + 6 + 6 + 6 + 6 + 12 + + + 1 + 1 + start + Monitor command + + + + + gnome-system-monitor + 1 + 1 + 24 + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/schemas/gschemas.compiled b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..4606bde42183474e7af5ca6a6fc88fffd06452bf GIT binary patch literal 1676 zcmZ8hO=uNY7`?GZ(?m^-+G>NK6y?P-?=>hkQo0hUixvV}3EhnI-n+?MotZn%y_3Ay zv}9qyf(1cbwIyAtQ0mW0t0->7F0*LdYH+&Np8l z3o;cXR+QIP@Mxhct4gl}{HXf>elqXv6ounE;X+gf3U)_u4-vh25T&~fl?twoCo(F!| zzjS~;^+xy$;O9WQAJpu}OYl(yZlB$^#CU41e;h1<7qdf;=u^{gfoFh)+c$rwPfh9nj4gw8Kew#ON=KgFzYX85{tRybdr zC(hO+rsx#=<=D>sD}Rtzs*SQ((o+e#p2(=Y<-UoyA1d@$HSj%aKZt$v zv>90GSrtq6Yh}L)9a$V7Emz-|YRRTIshT!yKkodpXP!wV?vLp#4&Kkp^=m9hT)g{} zX1XDb(HWO7)(^Gy3_iCyGk#I4pBp6L3%}^3AL*d!55+M2_NH0OkAs%)i{2f3MI|sr viKk_ziyYZk9&E8faZav}-aBo^{L8 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/sensors.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/sensors.js new file mode 100644 index 0000000..0595925 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/sensors.js @@ -0,0 +1,629 @@ +/* + Copyright (c) 2018, Chris Monahan + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the GNOME nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +const GObject = imports.gi.GObject; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const FileModule = Me.imports.helpers.file; +const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); +const _ = Gettext.gettext; +const NM = imports.gi.NM; + +let GTop, hasGTop = true; +try { + GTop = imports.gi.GTop; +} catch (e) { + global.log(e); + hasGTop = false; +} + +var Sensors = GObject.registerClass({ + GTypeName: 'Sensors', +}, class Sensors extends GObject.Object { + _init(settings, sensorIcons) { + this._settings = settings; + this._sensorIcons = sensorIcons; + + this.resetHistory(); + + this._last_processor = { 'core': {}, 'speed': [] }; + + if (hasGTop) { + this.storage = new GTop.glibtop_fsusage(); + this._storageDevice = ''; + this._findStorageDevice(); + + this._lastRead = 0; + this._lastWrite = 0; + } + } + + _refreshIPAddress(callback) { + // check IP address + new FileModule.File('https://corecoding.com/vitals.php').read().then(contents => { + let obj = JSON.parse(contents); + this._returnValue(callback, 'Public IP', obj['IPv4'], 'network', 'string'); + }).catch(err => { }); + } + + _findStorageDevice() { + new FileModule.File('/proc/mounts').read("\n").then(lines => { + for (let line of Object.values(lines)) { + let loadArray = line.trim().split(/\s+/); + if (loadArray[1] == this._settings.get_string('storage-path')) { + this._storageDevice = loadArray[0]; + break; + } + } + }).catch(err => { }); + } + + query(callback, dwell) { + if (!this._hardware_detected) { + // we could set _hardware_detected in discoverHardwareMonitors, but by + // doing it here, we guarantee avoidance of race conditions + this._hardware_detected = true; + this._discoverHardwareMonitors(callback); + } + + for (let sensor in this._sensorIcons) { + if (this._settings.get_boolean('show-' + sensor)) { + if (sensor == 'temperature' || sensor == 'voltage' || sensor == 'fan') { + // for temp, volt, fan, we have a shared handler + this._queryTempVoltFan(callback, sensor); + } else { + // directly call queryFunction below + let method = '_query' + sensor[0].toUpperCase() + sensor.slice(1); + this[method](callback, dwell); + } + } + } + } + + _queryTempVoltFan(callback, type) { + for (let label in this._tempVoltFanSensors[type]) { + let sensor = this._tempVoltFanSensors[type][label]; + + new FileModule.File(sensor['path']).read().then(value => { + this._returnValue(callback, label, value, type, sensor['format']); + }).catch(err => { + this._returnValue(callback, label, 'disabled', type, sensor['format']); + }); + } + } + + _queryMemory(callback) { + // check memory info + new FileModule.File('/proc/meminfo').read().then(lines => { + let total = 0, avail = 0, swapTotal = 0, swapFree = 0; + + let values = lines.match(/MemTotal:(\s+)(\d+) kB/); + if (values) total = values[2]; + + values = lines.match(/MemAvailable:(\s+)(\d+) kB/); + if (values) avail = values[2]; + + values = lines.match(/SwapTotal:(\s+)(\d+) kB/); + if (values) swapTotal = values[2]; + + values = lines.match(/SwapFree:(\s+)(\d+) kB/); + if (values) swapFree = values[2]; + + let used = total - avail + let utilized = used / total; + + this._returnValue(callback, 'Usage', utilized, 'memory', 'percent'); + this._returnValue(callback, 'memory', utilized, 'memory-group', 'percent'); + this._returnValue(callback, 'Physical', total, 'memory', 'memory'); + this._returnValue(callback, 'Available', avail, 'memory', 'memory'); + this._returnValue(callback, 'Allocated', used, 'memory', 'memory'); + this._returnValue(callback, 'Swap', swapTotal - swapFree, 'memory', 'memory'); + }).catch(err => { }); + } + + _queryProcessor(callback, dwell) { + let columns = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq', 'steal', 'guest', 'guest_nice']; + + // check processor usage + new FileModule.File('/proc/stat').read("\n").then(lines => { + let statistics = {}; + + for (let line of Object.values(lines)) { + let reverse_data = line.match(/^(cpu\d*\s)(.+)/); + if (reverse_data) { + let cpu = reverse_data[1].trim(); + + if (!(cpu in statistics)) + statistics[cpu] = {}; + + if (!(cpu in this._last_processor['core'])) + this._last_processor['core'][cpu] = 0; + + let stats = reverse_data[2].trim().split(' ').reverse(); + for (let column of columns) + statistics[cpu][column] = parseInt(stats.pop()); + } + } + + let cores = Object.keys(statistics).length - 1; + + for (let cpu in statistics) { + let total = statistics[cpu]['user'] + statistics[cpu]['nice'] + statistics[cpu]['system']; + + // make sure we have data to report + if (this._last_processor['core'][cpu] > 0) { + let delta = (total - this._last_processor['core'][cpu]) / dwell; + + // /proc/stat provides overall usage for us under the 'cpu' heading + if (cpu == 'cpu') { + delta = delta / cores; + this._returnValue(callback, 'processor', delta / 100, 'processor-group', 'percent'); + this._returnValue(callback, 'Usage', delta / 100, 'processor', 'percent'); + } else { + this._returnValue(callback, _('Core %d').format(cpu.substr(3)), delta / 100, 'processor', 'percent'); + } + } + + this._last_processor['core'][cpu] = total; + } + + // if frequency scaling is enabled, gather cpu-freq values + if (!this._processor_uses_cpu_info) { + for (let core = 0; core <= cores; core++) { + new FileModule.File('/sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_cur_freq').read().then(value => { + this._last_processor['speed'][core] = parseInt(value); + }).catch(err => { }); + } + } + }).catch(err => { }); + + // if frequency scaling is disabled, use cpuinfo for speed + if (this._processor_uses_cpu_info) { + // grab CPU frequency + new FileModule.File('/proc/cpuinfo').read("\n").then(lines => { + let freqs = []; + for (let line of Object.values(lines)) { + // grab megahertz + let value = line.match(/^cpu MHz(\s+): ([+-]?\d+(\.\d+)?)/); + if (value) freqs.push(parseFloat(value[2])); + } + + let sum = freqs.reduce((a, b) => a + b); + let hertz = (sum / freqs.length) * 1000 * 1000; + this._returnValue(callback, 'Frequency', hertz, 'processor', 'hertz'); + + //let max_hertz = Math.getMaxOfArray(freqs) * 1000 * 1000; + //this._returnValue(callback, 'Boost', max_hertz, 'processor', 'hertz'); + }).catch(err => { }); + // if frequency scaling is enabled, cpu-freq reports + } else if (Object.values(this._last_processor['speed']).length > 0) { + let sum = this._last_processor['speed'].reduce((a, b) => a + b); + let hertz = (sum / this._last_processor['speed'].length) * 1000; + this._returnValue(callback, 'Frequency', hertz, 'processor', 'hertz'); + //let max_hertz = Math.getMaxOfArray(this._last_processor['speed']) * 1000; + //this._returnValue(callback, 'Boost', max_hertz, 'processor', 'hertz'); + } + } + + _querySystem(callback) { + // check load average + new FileModule.File('/proc/sys/fs/file-nr').read("\t").then(loadArray => { + this._returnValue(callback, 'Open Files', loadArray[0], 'system', 'string'); + }).catch(err => { }); + + // check load average + new FileModule.File('/proc/loadavg').read(' ').then(loadArray => { + let proc = loadArray[3].split('/'); + + this._returnValue(callback, 'Load 1m', loadArray[0], 'system', 'load'); + this._returnValue(callback, 'system', loadArray[0], 'system-group', 'load'); + this._returnValue(callback, 'Load 5m', loadArray[1], 'system', 'load'); + this._returnValue(callback, 'Load 15m', loadArray[2], 'system', 'load'); + this._returnValue(callback, 'Threads Active', proc[0], 'system', 'string'); + this._returnValue(callback, 'Threads Total', proc[1], 'system', 'string'); + }).catch(err => { }); + + // check uptime + new FileModule.File('/proc/uptime').read(' ').then(upArray => { + this._returnValue(callback, 'Uptime', upArray[0], 'system', 'duration'); + + let cores = Object.keys(this._last_processor['core']).length - 1; + if (cores > 0) + this._returnValue(callback, 'Process Time', upArray[0] - upArray[1] / cores, 'processor', 'duration'); + }).catch(err => { }); + } + + _queryNetwork(callback, dwell) { + // check network speed + let directions = ['tx', 'rx']; + let netbase = '/sys/class/net/'; + + new FileModule.File(netbase).list().then(interfaces => { + for (let iface of interfaces) { + for (let direction of directions) { + // lo tx and rx are the same + if (iface == 'lo' && direction == 'rx') continue; + + new FileModule.File(netbase + iface + '/statistics/' + direction + '_bytes').read().then(value => { + // issue #217 - don't include 'lo' traffic in Maximum calculations in values.js + // by not using network-rx or network-tx + let name = iface + ((iface == 'lo')?'':' ' + direction); + + let type = 'network' + ((iface=='lo')?'':'-' + direction); + this._returnValue(callback, name, value, type, 'storage'); + }).catch(err => { }); + } + } + }).catch(err => { }); + + // some may not want public ip checking + if (this._settings.get_boolean('include-public-ip')) { + // check the public ip every hour or when waking from sleep + if (this._next_public_ip_check <= 0) { + this._next_public_ip_check = 3600; + + this._refreshIPAddress(callback); + } + + this._next_public_ip_check -= dwell; + } + + // wireless interface statistics + new FileModule.File('/proc/net/wireless').read("\n", true).then(lines => { + for (let line of Object.values(lines)) { + let netArray = line.trim().split(/\s+/); + let quality_pct = netArray[2].substr(0, netArray[2].length-1) / 70; + let signal = netArray[3].substr(0, netArray[3].length-1); + + this._returnValue(callback, 'WiFi Link Quality', quality_pct, 'network', 'percent'); + this._returnValue(callback, 'WiFi Signal Level', signal, 'network', 'string'); + } + }).catch(err => { }); + } + + _queryStorage(callback, dwell) { + // display zfs arc status, if available + new FileModule.File('/proc/spl/kstat/zfs/arcstats').read().then(lines => { + let target = 0, maximum = 0, current = 0; + + let values = lines.match(/c(\s+)(\d+)(\s+)(\d+)/); + if (values) target = values[4]; + + values = lines.match(/c_max(\s+)(\d+)(\s+)(\d+)/); + if (values) maximum = values[4]; + + values = lines.match(/size(\s+)(\d+)(\s+)(\d+)/); + if (values) current = values[4]; + + // ZFS statistics + this._returnValue(callback, 'ARC Target', target, 'storage', 'storage'); + this._returnValue(callback, 'ARC Maximum', maximum, 'storage', 'storage'); + this._returnValue(callback, 'ARC Current', current, 'storage', 'storage'); + }).catch(err => { }); + + // check disk performance stats + new FileModule.File('/proc/diskstats').read("\n").then(lines => { + for (let line of Object.values(lines)) { + let loadArray = line.trim().split(/\s+/); + if ('/dev/' + loadArray[2] == this._storageDevice) { + var read = (loadArray[5] * 512); + var write = (loadArray[9] * 512); + this._returnValue(callback, 'Read total', read, 'storage', 'storage'); + this._returnValue(callback, 'Write total', write, 'storage', 'storage'); + this._returnValue(callback, 'Read rate', (read - this._lastRead) / dwell, 'storage', 'storage'); + this._returnValue(callback, 'Write rate', (write - this._lastWrite) / dwell, 'storage', 'storage'); + this._lastRead = read; + this._lastWrite = write; + break; + } + } + }).catch(err => { }); + + // skip rest of stats if gtop not available + if (!hasGTop) return; + + GTop.glibtop_get_fsusage(this.storage, this._settings.get_string('storage-path')); + + let total = this.storage.blocks * this.storage.block_size; + let avail = this.storage.bavail * this.storage.block_size; + let free = this.storage.bfree * this.storage.block_size; + let used = total - free; + let reserved = (total - avail) - used; + + this._returnValue(callback, 'Total', total, 'storage', 'storage'); + this._returnValue(callback, 'Used', used, 'storage', 'storage'); + this._returnValue(callback, 'Reserved', reserved, 'storage', 'storage'); + this._returnValue(callback, 'Free', avail, 'storage', 'storage'); + this._returnValue(callback, 'storage', avail, 'storage-group', 'storage'); + } + + _queryBattery(callback) { + let battery_slot = this._settings.get_int('battery-slot'); + + // addresses issue #161 + let batt_key = 'BAT'; + if (battery_slot == 3) { + batt_key = 'CMB'; + battery_slot = 0; + } + + let battery_path = '/sys/class/power_supply/' + batt_key + battery_slot + '/'; + + new FileModule.File(battery_path + 'status').read().then(value => { + this._returnValue(callback, 'State', value, 'battery', ''); + }).catch(err => { }); + + new FileModule.File(battery_path + 'cycle_count').read().then(value => { + if (value > 0 || (value == 0 && !this._settings.get_boolean('hide-zeros'))) + this._returnValue(callback, 'Cycles', value, 'battery', ''); + }).catch(err => { }); + + new FileModule.File(battery_path + 'charge_full').read().then(charge_full => { + new FileModule.File(battery_path + 'voltage_min_design').read().then(voltage_min_design => { + this._returnValue(callback, 'Energy (full)', charge_full * voltage_min_design, 'battery', 'watt-hour'); + new FileModule.File(battery_path + 'charge_full_design').read().then(charge_full_design => { + this._returnValue(callback, 'Capacity', (charge_full / charge_full_design), 'battery', 'percent'); + this._returnValue(callback, 'Energy (design)', charge_full_design * voltage_min_design, 'battery', 'watt-hour'); + }).catch(err => { }); + + new FileModule.File(battery_path + 'voltage_now').read().then(voltage_now => { + this._returnValue(callback, 'Voltage', voltage_now / 1000, 'battery', 'in'); + + new FileModule.File(battery_path + 'current_now').read().then(current_now => { + let watt = current_now * voltage_now; + this._returnValue(callback, 'Rate', watt, 'battery', 'watt'); + this._returnValue(callback, 'battery', watt, 'battery-group', 'watt'); + + new FileModule.File(battery_path + 'charge_now').read().then(charge_now => { + let rest_pwr = voltage_min_design * charge_now; + this._returnValue(callback, 'Energy (now)', rest_pwr, 'battery', 'watt-hour'); + + //let time_left_h = rest_pwr / last_pwr; + //this._returnValue(callback, 'time_left_h', time_left_h, 'battery', ''); + + let level = charge_now / charge_full; + this._returnValue(callback, 'Percentage', level, 'battery', 'percent'); + }).catch(err => { }); + }).catch(err => { }); + }).catch(err => { }); + }).catch(err => { }); + }).catch(err => { + new FileModule.File(battery_path + 'energy_full').read().then(energy_full => { + new FileModule.File(battery_path + 'voltage_min_design').read().then(voltage_min_design => { + this._returnValue(callback, 'Energy (full)', energy_full * 1000000, 'battery', 'watt-hour'); + new FileModule.File(battery_path + 'energy_full_design').read().then(energy_full_design => { + this._returnValue(callback, 'Capacity', (energy_full / energy_full_design), 'battery', 'percent'); + this._returnValue(callback, 'Energy (design)', energy_full_design * 1000000, 'battery', 'watt-hour'); + }).catch(err => { }); + + new FileModule.File(battery_path + 'voltage_now').read().then(voltage_now => { + this._returnValue(callback, 'Voltage', voltage_now / 1000, 'battery', 'in'); + + new FileModule.File(battery_path + 'power_now').read().then(power_now => { + this._returnValue(callback, 'Rate', power_now * 1000000, 'battery', 'watt'); + this._returnValue(callback, 'battery', power_now * 1000000, 'battery-group', 'watt'); + + new FileModule.File(battery_path + 'energy_now').read().then(energy_now => { + this._returnValue(callback, 'Energy (now)', energy_now * 1000000, 'battery', 'watt-hour'); + + //let time_left_h = energy_now / last_pwr; + //this._returnValue(callback, 'time_left_h', time_left_h, 'battery', ''); + + let level = energy_now / energy_full; + this._returnValue(callback, 'Percentage', level, 'battery', 'percent'); + }).catch(err => { }); + }).catch(err => { }); + }).catch(err => { }); + }).catch(err => { }); + }).catch(err => { }); + }); + } + + _returnValue(callback, label, value, type, format) { + callback(label, value, type, format); + } + + _discoverHardwareMonitors(callback) { + this._tempVoltFanSensors = { 'temperature': {}, 'voltage': {}, 'fan': {} }; + + let hwbase = '/sys/class/hwmon/'; + + // process sensor_types now so it is not called multiple times below + let sensor_types = {}; + + if (this._settings.get_boolean('show-temperature')) + sensor_types['temp'] = 'temperature'; + + if (this._settings.get_boolean('show-voltage')) + sensor_types['in'] = 'voltage'; + + if (this._settings.get_boolean('show-fan')) + sensor_types['fan'] = 'fan'; + + // a little informal, but this code has zero I/O block + new FileModule.File(hwbase).list().then(files => { + for (let file of files) { + // grab name of sensor + new FileModule.File(hwbase + file + '/name').read().then(name => { + // are we dealing with a CPU? + if (name == 'coretemp') { + // determine which processor (socket) we are dealing with + new FileModule.File(hwbase + file + '/temp1_label').read().then(prefix => { + this._processTempVoltFan(callback, sensor_types, prefix, hwbase + file, file); + }).catch(err => { + // this shouldn't be necessary, but just in case temp1_label doesn't exist + // attempt to fix #266 + this._processTempVoltFan(callback, sensor_types, name, hwbase + file, file); + }); + } else { + // not a CPU, process all other sensors + this._processTempVoltFan(callback, sensor_types, name, hwbase + file, file); + } + }).catch(err => { + new FileModule.File(hwbase + file + '/device/name').read().then(name => { + this._processTempVoltFan(callback, sensor_types, name, hwbase + file + '/device', file); + }).catch(err => { }); + }); + } + }).catch(err => { }); + + // does this system support cpu scaling? if so we will use it to grab Frequency and Boost below + new FileModule.File('/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq').read().then(value => { + this._processor_uses_cpu_info = false; + }).catch(err => { }); + + // grab static CPU information + new FileModule.File('/proc/cpuinfo').read("\n").then(lines => { + let vendor_id = ''; + let bogomips = ''; + let sockets = {}; + let cache = ''; + + for (let line of Object.values(lines)) { + // grab cpu vendor + let value = line.match(/^vendor_id(\s+): (\w+.*)/); + if (value) vendor_id = value[2]; + + // grab bogomips + value = line.match(/^bogomips(\s+): (\d*\.?\d*)$/); + if (value) bogomips = value[2]; + + // grab processor count + value = line.match(/^physical id(\s+): (\d+)$/); + if (value) sockets[value[2]] = 1; + + // grab cache + value = line.match(/^cache size(\s+): (\d+) KB$/); + if (value) cache = value[2]; + } + + this._returnValue(callback, 'Vendor', vendor_id, 'processor', 'string'); + this._returnValue(callback, 'Bogomips', bogomips, 'processor', 'string'); + this._returnValue(callback, 'Sockets', Object.keys(sockets).length, 'processor', 'string'); + this._returnValue(callback, 'Cache', cache, 'processor', 'memory'); + }).catch(err => { }); + } + + _processTempVoltFan(callback, sensor_types, name, path, file) { + let sensor_files = [ 'input', 'label' ]; + + // grab files from directory + new FileModule.File(path).list().then(files2 => { + let trisensors = {}; + + // loop over files from directory + for (let file2 of Object.values(files2)) { + // simple way of processing input and label (from above) + for (let key of Object.values(sensor_files)) { + // process toggled on sensors from extension preferences + for (let sensor_type in sensor_types) { + if (file2.substr(0, sensor_type.length) == sensor_type && file2.substr(-(key.length+1)) == '_' + key) { + let key2 = file + file2.substr(0, file2.indexOf('_')); + + if (!(key2 in trisensors)) { + trisensors[key2] = { + 'type': sensor_types[sensor_type], + 'format': sensor_type, + 'label': path + '/name' + }; + } + + trisensors[key2][key] = path + '/' + file2; + } + } + } + } + + for (let obj of Object.values(trisensors)) { + if (!('input' in obj)) + continue; + + new FileModule.File(obj['input']).read().then(value => { + let extra = (obj['label'].indexOf('_label')==-1) ? ' ' + obj['input'].substr(obj['input'].lastIndexOf('/')+1).split('_')[0] : ''; + + if (value > 0 || !this._settings.get_boolean('hide-zeros') || obj['type'] == 'fan') { + new FileModule.File(obj['label']).read().then(label => { + this._addTempVoltFan(callback, obj, name, label, extra, value); + }).catch(err => { + let tmpFile = obj['label'].substr(0, obj['label'].lastIndexOf('/')) + '/name'; + new FileModule.File(tmpFile).read().then(label => { + this._addTempVoltFan(callback, obj, name, label, extra, value); + }).catch(err => { }); + }); + } + }).catch(err => { }); + } + }).catch(err => { }); + } + + _addTempVoltFan(callback, obj, name, label, extra, value) { + // prepend module that provided sensor data + if (name != label) label = name + ' ' + label; + + //if (label == 'nvme Composite') label = 'NVMe'; + //if (label == 'nouveau') label = 'Nvidia'; + + label = label + extra; + + // in the future we will read /etc/sensors3.conf + if (label == 'acpitz temp1') label = 'ACPI Thermal Zone'; + if (label == 'pch_cannonlake temp1') label = 'Platform Controller Hub'; + if (label == 'iwlwifi_1 temp1') label = 'Wireless Adapter'; + if (label == 'Package id 0') label = 'Processor 0'; + if (label == 'Package id 1') label = 'Processor 1'; + label = label.replace('Package id', 'CPU'); + + let types = [ 'temperature', 'voltage', 'fan' ]; + for (let type of types) { + // check if this label already exists + if (label in this._tempVoltFanSensors[type]) { + for (let i = 2; i <= 9; i++) { + // append an incremented number to end + let new_label = label + ' ' + i; + + // if new label is available, use it + if (!(new_label in this._tempVoltFanSensors[type])) { + label = new_label; + break; + } + } + } + } + + // update screen on initial build to prevent delay on update + this._returnValue(callback, label, value, obj['type'], obj['format']); + + this._tempVoltFanSensors[obj['type']][label] = { + 'format': obj['format'], + 'path': obj['input'] + }; + } + + resetHistory() { + this._next_public_ip_check = 0; + this._hardware_detected = false; + this._processor_uses_cpu_info = true; + } +}); diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/stylesheet.css b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/stylesheet.css new file mode 100644 index 0000000..adec425 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/stylesheet.css @@ -0,0 +1,16 @@ +.vitals-icon { icon-size: 16px; } +.vitals-menu-button-container {} +.vitals-panel-icon-temperature { margin: 0 1px 0 8px; padding: 0; } +.vitals-panel-icon-voltage { margin: 0 0 0 8px; padding: 0; } +.vitals-panel-icon-fan { margin: 0 4px 0 8px; padding: 0; } +.vitals-panel-icon-memory { margin: 0 2px 0 8px; padding: 0; } +.vitals-panel-icon-processor { margin: 0 3px 0 8px; padding: 0; } +.vitals-panel-icon-system { margin: 0 3px 0 8px; padding: 0; } +.vitals-panel-icon-network { margin: 0 3px 0 8px; padding: 0; } +.vitals-panel-icon-storage { margin: 0 2px 0 8px; padding: 0; } +.vitals-panel-icon-battery { margin: 0 4px 0 8px; padding: 0; } +.vitals-panel-label { margin: 0 3px 0 0; padding: 0; } +.vitals-button-action { -st-icon-style: symbolic; border-radius: 32px; margin: 0px; min-height: 22px; min-width: 22px; padding: 10px; font-size: 100%; border: 1px solid transparent; } +.vitals-button-action:hover, .vitals-button-action:focus { border-color: #777; } +.vitals-button-action > StIcon { icon-size: 16px; } +.vitals-button-box { padding: 0px; spacing: 22px; } diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/values.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/values.js new file mode 100644 index 0000000..b3e72d9 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/Vitals@CoreCoding.com/values.js @@ -0,0 +1,337 @@ +/* + Copyright (c) 2018, Chris Monahan + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the GNOME nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +const GObject = imports.gi.GObject; +const Me = imports.misc.extensionUtils.getCurrentExtension(); + +const cbFun = (d, c) => { + let bb = d[1] % c[0], + aa = (d[1] - bb) / c[0]; + aa = aa > 0 ? aa + c[1] : ''; + + return [d[0] + aa, bb]; +}; + +var Values = GObject.registerClass({ + GTypeName: 'Values', +}, class Values extends GObject.Object { + + _init(settings, sensorIcons) { + this._settings = settings; + this._sensorIcons = sensorIcons; + + this._networkSpeedOffset = {}; + this._networkSpeeds = {}; + + this._history = {}; + //this._history2 = {}; + this.resetHistory(); + } + + _legible(value, sensorClass) { + let unit = 1000; + if (value === null) return 'N/A'; + let use_higher_precision = this._settings.get_boolean('use-higher-precision'); + let memory_measurement = this._settings.get_int('memory-measurement') + let storage_measurement = this._settings.get_int('storage-measurement') + let use_bps = (this._settings.get_int('network-speed-format') == 1); + + let format = ''; + let ending = ''; + let exp = 0; + + var decimal = [ 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' ]; + var binary = [ 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB' ]; + var hertz = [ 'Hz', 'KHz', 'MHz', 'GHz', 'THz', 'PHz', 'EHz', 'ZHz' ]; + + switch (sensorClass) { + case 'percent': + format = (use_higher_precision)?'%.1f%s':'%d%s'; + value = value * 100; + if (value > 100) value = 100; + ending = '%'; + break; + case 'temp': + value = value / 1000; + ending = '°C'; + + // are we converting to fahrenheit? + if (this._settings.get_int('unit') == 1) { + value = ((9 / 5) * value + 32); + ending = '°F'; + } + + format = (use_higher_precision)?'%.1f%s':'%d%s'; + break; + case 'fan': + format = '%d %s'; + ending = 'RPM'; + break; + case 'in': // voltage + value = value / 1000; + format = ((value >= 0) ? '+' : '-') + ((use_higher_precision)?'%.2f %s':'%.1f %s'); + ending = 'V'; + break; + case 'hertz': + if (value > 0) { + exp = Math.floor(Math.log(value) / Math.log(unit)); + if (value >= Math.pow(unit, exp) * (unit - 0.05)) exp++; + value = parseFloat((value / Math.pow(unit, exp))); + } + + format = (use_higher_precision)?'%.2f %s':'%.1f %s'; + ending = hertz[exp]; + break; + case 'memory': + unit = (memory_measurement)?1000:1024; + + if (value > 0) { + value *= unit; + exp = Math.floor(Math.log(value) / Math.log(unit)); + if (value >= Math.pow(unit, exp) * (unit - 0.05)) exp++; + value = parseFloat((value / Math.pow(unit, exp))); + } + + format = (use_higher_precision)?'%.2f %s':'%.1f %s'; + + if (memory_measurement) + ending = decimal[exp]; + else + ending = binary[exp]; + + break; + case 'storage': + unit = (storage_measurement)?1000:1024; + + if (value > 0) { + exp = Math.floor(Math.log(value) / Math.log(unit)); + if (value >= Math.pow(unit, exp) * (unit - 0.05)) exp++; + value = parseFloat((value / Math.pow(unit, exp))); + } + + format = (use_higher_precision)?'%.2f %s':'%.1f %s'; + + if (storage_measurement) + ending = decimal[exp]; + else + ending = binary[exp]; + + break; + case 'speed': + if (value > 0) { + if (use_bps) value *= 8; + exp = Math.floor(Math.log(value) / Math.log(unit)); + if (value >= Math.pow(unit, exp) * (unit - 0.05)) exp++; + value = parseFloat((value / Math.pow(unit, exp))); + } + + format = (use_higher_precision)?'%.1f %s':'%.0f %s'; + + if (use_bps) { + ending = decimal[exp].replace('B', 'bps'); + } else { + ending = decimal[exp] + '/s'; + } + + break; + case 'duration': + let scale = [24, 60, 60]; + let units = ['d ', 'h ', 'm ']; + + // show seconds on higher precision or if value under a minute + if (use_higher_precision || value < 60) { + scale.push(1); + units.push('s '); + } + + let rslt = scale.map((d, i, a) => a.slice(i).reduce((d, c) => d * c)) + .map((d, i) => ([d, units[i]])) + .reduce(cbFun, ['', value]); + + value = rslt[0].trim(); + + format = '%s'; + break; + case 'milliamp': + format = (use_higher_precision)?'%.1f %s':'%d %s'; + value = value / 1000; + ending = 'mA'; + break; + case 'milliamp-hour': + format = (use_higher_precision)?'%.1f %s':'%d %s'; + value = value / 1000; + ending = 'mAh'; + break; + case 'watt': + format = (use_higher_precision)?'%.2f %s':'%.1f %s'; + value = value / 1000000000000; + ending = 'W'; + break; + case 'watt-hour': + format = (use_higher_precision)?'%.2f %s':'%.1f %s'; + value = value / 1000000000000; + ending = 'Wh'; + break; + case 'load': + format = (use_higher_precision)?'%.2f %s':'%.1f %s'; + break; + default: + format = '%s'; + break; + } + + return format.format(value, ending); + } + + returnIfDifferent(dwell, label, value, type, format, key) { + let output = []; + + // make sure the keys exist + if (!(type in this._history)) this._history[type] = {}; + + // no sense in continuing when the raw value has not changed + if (type != 'network-rx' && type != 'network-tx' && + key in this._history[type] && this._history[type][key][1] == value) + return output; + + // is the value different from last time? + let legible = this._legible(value, format); + + // don't return early when dealing with network traffic + if (type != 'network-rx' && type != 'network-tx') { + // only update when we are coming through for the first time, or if a value has changed + if (key in this._history[type] && this._history[type][key][0] == legible) + return output; + + // add label as it was sent from sensors class + output.push([label, legible, type, key]); + } + + // save previous values to update screen on chnages only + let previousValue = this._history[type][key]; + this._history[type][key] = [legible, value]; + + // process average, min and max values + if (type == 'temperature' || type == 'voltage' || type == 'fan') { + let vals = Object.values(this._history[type]).map(x => parseFloat(x[1])); + + // show value in group even if there is one value present + let sum = vals.reduce((a, b) => a + b); + let avg = this._legible(sum / vals.length, format); + output.push([type, avg, type + '-group', '']); + + // If only one value is present, don't display avg, min and max + if (vals.length > 1) { + output.push(['Average', avg, type, '__' + type + '_avg__']); + + // calculate Minimum value + let min = Math.min(...vals); + min = this._legible(min, format); + output.push(['Minimum', min, type, '__' + type + '_min__']); + + // calculate Maximum value + let max = Math.max(...vals); + max = this._legible(max, format); + output.push(['Maximum', max, type, '__' + type + '_max__']); + } + } else if (type == 'network-rx' || type == 'network-tx') { + let direction = type.split('-')[1]; + + // appends total upload and download for all interfaces for #216 + let vals = Object.values(this._history[type]).map(x => parseFloat(x[1])); + let sum = vals.reduce((partialSum, a) => partialSum + a, 0); + output.push(['Boot ' + direction, this._legible(sum, format), type, '__' + type + '_boot__']); + + // keeps track of session start point + if (!(key in this._networkSpeedOffset) || this._networkSpeedOffset[key] <= 0) + this._networkSpeedOffset[key] = sum; + + // outputs session upload and download for all interfaces for #234 + output.push(['Session ' + direction, this._legible(sum - this._networkSpeedOffset[key], format), type, '__' + type + '_ses__']); + + // calculate speed for this interface + let speed = (value - previousValue[1]) / dwell; + output.push([label, this._legible(speed, 'speed'), type, key]); + + // store speed for Device report + if (!(direction in this._networkSpeeds)) this._networkSpeeds[direction] = {}; + if (!(label in this._networkSpeeds[direction])) this._networkSpeeds[direction][label] = 0; + + // store value for next go around + if (value > 0 || (value == 0 && !this._settings.get_boolean('hide-zeros'))) + this._networkSpeeds[direction][label] = speed; + + // calculate total upload and download device speed + for (let direction in this._networkSpeeds) { + let sum = 0; + for (let iface in this._networkSpeeds[direction]) + sum += parseFloat(this._networkSpeeds[direction][iface]); + + sum = this._legible(sum, 'speed'); + output.push(['Device ' + direction, sum, 'network-' + direction, '__network-' + direction + '_max__']); + // append download speed to group itself + if (direction == 'rx') output.push([type, sum, type + '-group', '']); + } + } + +/* + global.log('before', JSON.stringify(output)); + for (let i = output.length - 1; i >= 0; i--) { + let sensor = output[i]; + // sensor[0]=label, sensor[1]=value, sensor[2]=type, sensor[3]=key) + + //["CPU Core 5","46°C","temperature","_temperature_hwmon8temp7_"] + + // make sure the keys exist + if (!(sensor[2] in this._history2)) this._history2[sensor[2]] = {}; + + if (sensor[3] in this._history2[sensor[2]]) { + if (this._history2[sensor[2]][sensor[3]] == sensor[1]) { + output.splice(i, 1); + } + } + + this._history2[sensor[2]][sensor[3]] = sensor[1]; + } + + global.log(' after', JSON.stringify(output)); + global.log('***************************'); +*/ + + return output; + } + + resetHistory() { + // don't call this._history = {}, as we want to keep network-rx and network-tx + // otherwise network history statistics will start over + for (let sensor in this._sensorIcons) { + this._history[sensor] = {}; + this._history[sensor + '-group'] = {}; + //this._history2[sensor] = {}; + //this._history2[sensor + '-group'] = {}; + } + } +}); diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/appfolders.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/appfolders.js new file mode 100644 index 0000000..b69f49e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/appfolders.js @@ -0,0 +1,265 @@ +'use strict'; + +const { Shell, GLib, Clutter } = imports.gi; +const Main = imports.ui.main; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { PaintSignals } = Me.imports.effects.paint_signals; +const Tweener = imports.tweener.tweener; + +const transparent = Clutter.Color.from_pixel(0x00000000); +const FOLDER_DIALOG_ANIMATION_TIME = 200; +const FRAME_UPDATE_PERIOD = 16; + +const DIALOGS_STYLES = [ + "", + "appfolder-dialogs-transparent", + "appfolder-dialogs-light", + "appfolder-dialogs-dark" +]; + +let original_zoomAndFadeIn = null; +let original_zoomAndFadeOut = null; +let sigma; +let brightness; + +let _zoomAndFadeIn = function () { + let [sourceX, sourceY] = + this._source.get_transformed_position(); + let [dialogX, dialogY] = + this.child.get_transformed_position(); + + this.child.set({ + translation_x: sourceX - dialogX, + translation_y: sourceY - dialogY, + scale_x: this._source.width / this.child.width, + scale_y: this._source.height / this.child.height, + opacity: 0, + }); + + this.set_background_color(transparent); + + let blur_effect = this.get_effect("appfolder-blur"); + + blur_effect.sigma = 0; + blur_effect.brightness = 1.0; + Tweener.addTween(blur_effect, + { + sigma: sigma, + brightness: brightness, + time: FOLDER_DIALOG_ANIMATION_TIME / 1000, + transition: 'easeOutQuad' + } + ); + + this.child.ease({ + translation_x: 0, + translation_y: 0, + scale_x: 1, + scale_y: 1, + opacity: 255, + duration: FOLDER_DIALOG_ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + }); + + this._needsZoomAndFade = false; + + if (this._sourceMappedId === 0) { + this._sourceMappedId = this._source.connect( + 'notify::mapped', this._zoomAndFadeOut.bind(this)); + } +}; + +let _zoomAndFadeOut = function () { + if (!this._isOpen) + return; + + if (!this._source.mapped) { + this.hide(); + return; + } + + let [sourceX, sourceY] = + this._source.get_transformed_position(); + let [dialogX, dialogY] = + this.child.get_transformed_position(); + + this.set_background_color(transparent); + + let blur_effect = this.get_effect("appfolder-blur"); + Tweener.addTween(blur_effect, + { + sigma: 0, + brightness: 1.0, + time: FOLDER_DIALOG_ANIMATION_TIME / 1000, + transition: 'easeInQuad' + } + ); + + this.child.ease({ + translation_x: sourceX - dialogX, + translation_y: sourceY - dialogY, + scale_x: this._source.width / this.child.width, + scale_y: this._source.height / this.child.height, + opacity: 0, + duration: FOLDER_DIALOG_ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => { + this.child.set({ + translation_x: 0, + translation_y: 0, + scale_x: 1, + scale_y: 1, + opacity: 255, + }); + this.hide(); + + this._popdownCallbacks.forEach(func => func()); + this._popdownCallbacks = []; + }, + }); + + this._needsZoomAndFade = false; +}; + + +var AppFoldersBlur = class AppFoldersBlur { + constructor(connections, prefs) { + this.connections = connections; + this.paint_signals = new PaintSignals(connections); + this.prefs = prefs; + } + + enable() { + this._log("blurring appfolders"); + + brightness = this.prefs.appfolder.CUSTOMIZE + ? this.prefs.appfolder.BRIGHTNESS + : this.prefs.BRIGHTNESS; + sigma = this.prefs.appfolder.CUSTOMIZE + ? this.prefs.appfolder.SIGMA + : this.prefs.SIGMA; + + let appDisplay = Main.overview._overview.controls._appDisplay; + + if (appDisplay._folderIcons.length > 0) { + this.blur_appfolders(); + } + + this.connections.connect( + appDisplay, 'view-loaded', this.blur_appfolders.bind(this) + ); + } + + blur_appfolders() { + let appDisplay = Main.overview._overview.controls._appDisplay; + + if (this.prefs.HACKS_LEVEL === 1 || this.prefs.HACKS_LEVEL === 2) + this._log(`appfolders hack level ${this.prefs.HACKS_LEVEL}`); + + appDisplay._folderIcons.forEach(icon => { + icon._ensureFolderDialog(); + + if (original_zoomAndFadeIn == null) { + original_zoomAndFadeIn = icon._dialog._zoomAndFadeIn; + } + if (original_zoomAndFadeOut == null) { + original_zoomAndFadeOut = icon._dialog._zoomAndFadeOut; + } + + let blur_effect = new Shell.BlurEffect({ + name: "appfolder-blur", + sigma: sigma, + brightness: brightness, + mode: Shell.BlurMode.BACKGROUND + }); + + icon._dialog.remove_effect_by_name("appfolder-blur"); + icon._dialog.add_effect(blur_effect); + + DIALOGS_STYLES.forEach( + style => icon._dialog._viewBox.remove_style_class_name(style) + ); + + icon._dialog._viewBox.add_style_class_name( + DIALOGS_STYLES[this.prefs.appfolder.STYLE_DIALOGS] + ); + + // finally override the builtin functions + + icon._dialog._zoomAndFadeIn = _zoomAndFadeIn; + icon._dialog._zoomAndFadeOut = _zoomAndFadeOut; + + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (this.prefs.HACKS_LEVEL === 1 || this.prefs.HACKS_LEVEL === 2) { + this.paint_signals.disconnect_all_for_actor(icon._dialog); + this.paint_signals.connect(icon._dialog, blur_effect); + } else { + this.paint_signals.disconnect_all(); + } + }); + }; + + set_sigma(s) { + sigma = s; + if (this.prefs.appfolder.BLUR) + this.blur_appfolders(); + } + + set_brightness(b) { + brightness = b; + if (this.prefs.appfolder.BLUR) + this.blur_appfolders(); + } + + // not implemented for dynamic blur + set_color(c) { } + set_noise_amount(n) { } + set_noise_lightness(l) { } + + disable() { + this._log("removing blur from appfolders"); + + let appDisplay = Main.overview._overview.controls._appDisplay; + + if (original_zoomAndFadeIn != null) { + appDisplay._folderIcons.forEach(icon => { + if (icon._dialog) + icon._dialog._zoomAndFadeIn = original_zoomAndFadeIn; + }); + } + + if (original_zoomAndFadeOut != null) { + appDisplay._folderIcons.forEach(icon => { + if (icon._dialog) + icon._dialog._zoomAndFadeOut = original_zoomAndFadeOut; + }); + } + + appDisplay._folderIcons.forEach(icon => { + if (icon._dialog) { + icon._dialog.remove_effect_by_name("appfolder-blur"); + DIALOGS_STYLES.forEach( + s => icon._dialog._viewBox.remove_style_class_name(s) + ); + } + }); + + this.connections.disconnect_all(); + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > appfolders] ${str}`); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/applications.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/applications.js new file mode 100644 index 0000000..c040451 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/applications.js @@ -0,0 +1,541 @@ +'use strict'; + +const { Shell, Clutter, Meta, GLib } = imports.gi; +const Main = imports.ui.main; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { PaintSignals } = Me.imports.effects.paint_signals; +const { ApplicationsService } = Me.imports.dbus.services; + +var ApplicationsBlur = class ApplicationsBlur { + constructor(connections, prefs) { + this.connections = connections; + this.prefs = prefs; + this.paint_signals = new PaintSignals(connections); + + // stores every blurred window + this.window_map = new Map(); + // stores every blur actor + this.blur_actor_map = new Map(); + } + + enable() { + this._log("blurring applications..."); + + // export dbus service for preferences + this.service = new ApplicationsService; + this.service.export(); + + // blur already existing windows + this.update_all_windows(); + + // blur every new window + this.connections.connect( + global.display, + 'window-created', + (_meta_display, meta_window) => { + this._log("window created"); + + if (meta_window) { + let window_actor = meta_window.get_compositor_private(); + this.track_new(window_actor, meta_window); + } + } + ); + + this.connect_to_overview(); + } + + /// Connect to the overview being opened/closed to force the blur being + /// shown on every window of the workspaces viewer. + connect_to_overview() { + this.connections.disconnect_all_for(Main.overview); + + if (this.prefs.applications.BLUR_ON_OVERVIEW) { + // when the overview is opened, show every window actors (which + // allows the blur to be shown too) + this.connections.connect( + Main.overview, 'showing', + _ => this.window_map.forEach((meta_window, _pid) => { + let window_actor = meta_window.get_compositor_private(); + window_actor.show(); + }) + ); + + // when the overview is closed, hide every actor that is not on the + // current workspace (to mimic the original behaviour) + this.connections.connect( + Main.overview, 'hidden', + _ => { + let active_workspace = + global.workspace_manager.get_active_workspace(); + + this.window_map.forEach((meta_window, _pid) => { + let window_actor = meta_window.get_compositor_private(); + + if ( + meta_window.get_workspace() !== active_workspace + ) + window_actor.hide(); + }); + } + ); + } + } + + /// Iterate through all existing windows and add blur as needed. + update_all_windows() { + // remove all previously blurred windows, in the case where the + // whitelist was changed + this.window_map.forEach(((_meta_window, pid) => { + this.remove_blur(pid); + })); + + for ( + let i = 0; + i < global.workspace_manager.get_n_workspaces(); + ++i + ) { + let workspace = global.workspace_manager.get_workspace_by_index(i); + let windows = workspace.list_windows(); + + windows.forEach(meta_window => { + let window_actor = meta_window.get_compositor_private(); + + // disconnect previous signals + this.connections.disconnect_all_for(window_actor); + + this.track_new(window_actor, meta_window); + }); + } + } + + /// Adds the needed signals to every new tracked window, and adds blur if + /// needed. + track_new(window_actor, meta_window) { + let pid = ("" + Math.random()).slice(2, 16); + + window_actor['blur_provider_pid'] = pid; + meta_window['blur_provider_pid'] = pid; + + // remove the blur when the window is destroyed + this.connections.connect(window_actor, 'destroy', window_actor => { + let pid = window_actor.blur_provider_pid; + if (this.blur_actor_map.has(pid)) { + this.remove_blur(pid); + } + this.window_map.delete(pid); + }); + + // update the blur when mutter-hint or wm-class is changed + for (const prop of ['mutter-hints', 'wm-class']) { + this.connections.connect( + meta_window, + `notify::${prop}`, + _ => { + let pid = meta_window.blur_provider_pid; + this._log(`${prop} changed for pid ${pid}`); + + let window_actor = meta_window.get_compositor_private(); + this.check_blur(pid, window_actor, meta_window); + } + ); + } + + // update the position and size when the window size changes + this.connections.connect(meta_window, 'size-changed', () => { + if (this.blur_actor_map.has(pid)) { + let allocation = this.compute_allocation(meta_window); + let blur_actor = this.blur_actor_map.get(pid); + blur_actor.x = allocation.x; + blur_actor.y = allocation.y; + blur_actor.width = allocation.width; + blur_actor.height = allocation.height; + } + }); + + this.check_blur(pid, window_actor, meta_window); + } + + /// Checks if the given actor needs to be blurred. + /// + /// In order to be blurred, a window either: + /// - is whitelisted in the user preferences if not enable-all + /// - is not blacklisted if enable-all + /// - has a correct mutter hint, set to `blur-provider=sigma_value` + check_blur(pid, window_actor, meta_window) { + let mutter_hint = meta_window.get_mutter_hints(); + let window_wm_class = meta_window.get_wm_class(); + + let enable_all = this.prefs.applications.ENABLE_ALL; + let whitelist = this.prefs.applications.WHITELIST; + let blacklist = this.prefs.applications.BLACKLIST; + + this._log(`checking blur for ${pid}`); + + // either the window is included in whitelist + if (window_wm_class !== "" + && ((enable_all && !blacklist.includes(window_wm_class)) + || (!enable_all && whitelist.includes(window_wm_class)) + ) + && [ + Meta.FrameType.NORMAL, + Meta.FrameType.DIALOG, + Meta.FrameType.MODAL_DIALOG + ].includes(meta_window.get_frame_type()) + ) { + this._log(`application ${pid} listed, blurring it`); + + // get blur effect parameters + + let brightness, sigma; + + if (this.prefs.applications.CUSTOMIZE) { + brightness = this.prefs.applications.BRIGHTNESS; + sigma = this.prefs.applications.SIGMA; + } else { + brightness = this.prefs.BRIGHTNESS; + sigma = this.prefs.SIGMA; + } + + this.update_blur(pid, window_actor, meta_window, brightness, sigma); + } + + // or blur is asked by window itself + else if ( + mutter_hint != null && + mutter_hint.includes("blur-provider") + ) { + this._log(`application ${pid} has hint ${mutter_hint}, parsing`); + + // get blur effect parameters + let [brightness, sigma] = this.parse_xprop(mutter_hint); + + this.update_blur(pid, window_actor, meta_window, brightness, sigma); + } + + // remove blur if the mutter hint is no longer valid, and the window + // is not explicitly whitelisted or un-blacklisted + else if (this.blur_actor_map.has(pid)) { + this.remove_blur(pid); + } + } + + /// When given the xprop property, returns the brightness and sigma values + /// matching. If one of the two values is invalid, or missing, then it uses + /// default values. + /// + /// An xprop property is valid if it is in one of the following formats: + /// + /// blur-provider=sigma:60,brightness:0.9 + /// blur-provider=s:10,brightness:0.492 + /// blur-provider=b:1.0,s:16 + /// + /// Brightness is a floating-point between 0.0 and 1.0 included. + /// Sigma is an integer between 0 and 999 included. + /// + /// If sigma is set to 0, then the blur is removed. + /// Setting "default" instead of the two values will make the + /// extension use its default value. + /// + /// Note that no space can be inserted. + /// + parse_xprop(property) { + // set brightness and sigma to default values + let brightness, sigma; + if (this.prefs.applications.CUSTOMIZE) { + brightness = this.prefs.applications.BRIGHTNESS; + sigma = this.prefs.applications.SIGMA; + } else { + brightness = this.prefs.BRIGHTNESS; + sigma = this.prefs.SIGMA; + } + + // get the argument of the property + let arg = property.match("blur-provider=(.*)"); + this._log(`argument = ${arg}`); + + // if argument is valid, parse it + if (arg != null) { + // verify if there is only one value: in this case, this is sigma + let maybe_sigma = parseInt(arg[1]); + + if ( + !isNaN(maybe_sigma) && + maybe_sigma >= 0 && + maybe_sigma <= 999 + ) { + sigma = maybe_sigma; + } else { + // perform pattern matching + let res_b = arg[1].match("(brightness|b):(default|0?1?\.[0-9]*)"); + let res_s = arg[1].match("(sigma|s):(default|\\d{1,3})"); + + // if values are valid and not default, change them to the xprop one + if ( + res_b != null && res_b[2] !== 'default' + ) { + brightness = parseFloat(res_b[2]); + } + + if ( + res_s != null && res_s[2] !== 'default' + ) { + sigma = parseInt(res_s[2]); + } + } + } + + this._log(`brightness = ${brightness}, sigma = ${sigma}`); + + return [brightness, sigma]; + } + + /// Updates the blur on a window which needs to be blurred. + update_blur(pid, window_actor, meta_window, brightness, sigma) { + // the window is already blurred, update its blur effect + if (this.blur_actor_map.has(pid)) { + // window is already blurred, but sigma is null: remove the blur + if (sigma === 0) { + this.remove_blur(pid); + } + // window is already blurred and sigma is non-null: update it + else { + this.update_blur_effect( + this.blur_actor_map.get(pid), + brightness, + sigma + ); + } + } + + // the window is not blurred, and sigma is a non-null value: blur it + else if (sigma !== 0) { + // window is not blurred, blur it + this.create_blur_effect( + pid, + window_actor, + meta_window, + brightness, + sigma + ); + } + } + + /// Add the blur effect to the window. + create_blur_effect(pid, window_actor, meta_window, brightness, sigma) { + let blur_effect = new Shell.BlurEffect({ + sigma: sigma, + brightness: brightness, + mode: Shell.BlurMode.BACKGROUND + }); + + let blur_actor = this.create_blur_actor( + meta_window, + window_actor, + blur_effect + ); + + // if hacks are selected, force to repaint the window + if (this.prefs.HACKS_LEVEL === 1 || this.prefs.HACKS_LEVEL === 2) { + this._log("applications hack level 1 or 2"); + + this.paint_signals.disconnect_all(); + this.paint_signals.connect(blur_actor, blur_effect); + } else { + this.paint_signals.disconnect_all(); + } + + // insert the blurred widget + window_actor.insert_child_at_index(blur_actor, 0); + + // make sure window is blurred in overview + if (this.prefs.applications.BLUR_ON_OVERVIEW) + this.enforce_window_visibility_on_overview_for(window_actor); + + // set the window actor's opacity + this.set_window_opacity(window_actor, this.prefs.applications.OPACITY); + + // register the blur actor/effect + blur_actor['blur_provider_pid'] = pid; + this.blur_actor_map.set(pid, blur_actor); + this.window_map.set(pid, meta_window); + + // hide the blur if window is invisible + if (!window_actor.visible) { + blur_actor.hide(); + } + + // hide the blur if window becomes invisible + this.connections.connect( + window_actor, + 'notify::visible', + window_actor => { + let pid = window_actor.blur_provider_pid; + if (window_actor.visible) { + this.blur_actor_map.get(pid).show(); + } else { + this.blur_actor_map.get(pid).hide(); + } + } + ); + } + + /// Makes sure that, when the overview is visible, the window actor will + /// stay visible no matter what. + /// We can instead hide the last child of the window actor, which will + /// improve performances without hiding the blur effect. + enforce_window_visibility_on_overview_for(window_actor) { + this.connections.connect(window_actor, 'notify::visible', + _ => { + if (this.prefs.applications.BLUR_ON_OVERVIEW) { + if ( + !window_actor.visible + && Main.overview.visible + ) { + window_actor.show(); + window_actor.get_last_child().hide(); + } + else if ( + window_actor.visible + ) + window_actor.get_last_child().show(); + } + } + ); + } + + /// Set the opacity of the window actor that sits on top of the blur effect. + set_window_opacity(window_actor, opacity) { + window_actor.get_children().forEach(child => { + if (child.name !== "blur-actor") + child.opacity = opacity; + }); + } + + /// Compute the size and position for a blur actor. + /// On wayland, it seems like we need to divide by the scale to get the + /// correct result. + compute_allocation(meta_window) { + const is_wayland = Meta.is_wayland_compositor(); + const monitor_index = meta_window.get_monitor(); + const scale = is_wayland + ? Main.layoutManager.monitors[monitor_index].geometry_scale + : 1; + + let frame = meta_window.get_frame_rect(); + let buffer = meta_window.get_buffer_rect(); + + return { + x: (frame.x - buffer.x) / scale, + y: (frame.y - buffer.y) / scale, + width: frame.width / scale, + height: frame.height / scale + }; + } + + /// Returns a new already blurred widget, configured to follow the size and + /// position of its target window. + create_blur_actor(meta_window, window_actor, blur_effect) { + // compute the size and position + let allocation = this.compute_allocation(meta_window); + + // create the actor + let blur_actor = new Clutter.Actor({ + x: allocation.x, + y: allocation.y, + width: allocation.width, + height: allocation.height + }); + + // add the effect + blur_actor.add_effect_with_name('blur-effect', blur_effect); + + return blur_actor; + } + + /// Updates the blur effect by overwriting its sigma and brightness values. + update_blur_effect(blur_actor, brightness, sigma) { + let effect = blur_actor.get_effect('blur-effect'); + effect.sigma = sigma; + effect.brightness = brightness; + } + + /// Removes the blur actor from the shell and unregister it. + remove_blur(pid) { + this._log(`removing blur for pid ${pid}`); + + let meta_window = this.window_map.get(pid); + // disconnect needed signals and untrack window + if (meta_window) { + this.window_map.delete(pid); + let window_actor = meta_window.get_compositor_private(); + + let blur_actor = this.blur_actor_map.get(pid); + if (blur_actor) { + this.blur_actor_map.delete(pid); + + if (window_actor) { + // reset the opacity + this.set_window_opacity(window_actor, 255); + + // remove the blurred actor + window_actor.remove_child(blur_actor); + + // disconnect the signals about overview animation etc + this.connections.disconnect_all_for(window_actor); + } + } + } + } + + disable() { + this._log("removing blur from applications..."); + + this.service?.unexport(); + + this.blur_actor_map.forEach(((_blur_actor, pid) => { + this.remove_blur(pid); + })); + + this.connections.disconnect_all(); + this.paint_signals.disconnect_all(); + } + + /// Update the opacity of all window actors. + set_opacity() { + let opacity = this.prefs.applications.OPACITY; + + this.window_map.forEach(((meta_window, _pid) => { + let window_actor = meta_window.get_compositor_private(); + this.set_window_opacity(window_actor, opacity); + })); + } + + /// Updates each blur effect to use new sigma value + // FIXME set_sigma and set_brightness are called when the extension is + // loaded and when sigma is changed, and do not respect the per-app + // xprop behaviour + set_sigma(s) { + this.blur_actor_map.forEach((actor, _) => { + actor.get_effect('blur-effect').set_sigma(s); + }); + } + + /// Updates each blur effect to use new brightness value + set_brightness(b) { + this.blur_actor_map.forEach((actor, _) => { + actor.get_effect('blur-effect').set_brightness(b); + }); + } + + // not implemented for dynamic blur + set_color(c) { } + set_noise_amount(n) { } + set_noise_lightness(l) { } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > applications] ${str}`); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/dash_to_dock.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/dash_to_dock.js new file mode 100644 index 0000000..a4bdfad --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/dash_to_dock.js @@ -0,0 +1,320 @@ +'use strict'; + +const { St, Shell, GLib } = imports.gi; +const Main = imports.ui.main; +const Signals = imports.signals; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { PaintSignals } = Me.imports.effects.paint_signals; + +const DASH_STYLES = [ + "transparent-dash", + "light-dash", + "dark-dash" +]; + + +/// This type of object is created for every dash found, and talks to the main +/// DashBlur thanks to signals. +/// +/// This allows to dynamically track the created dashes for each screen. +class DashInfos { + constructor(dash_blur, dash, background_parent, effect, prefs) { + // the parent DashBlur object, to communicate + this.dash_blur = dash_blur; + // the blurred dash + this.dash = dash; + this.background_parent = background_parent; + this.effect = effect; + this.prefs = prefs; + this.old_style = this.dash._background.style; + + dash_blur.connections.connect(dash_blur, 'remove-dashes', () => { + this._log("removing blur from dash"); + this.dash.get_parent().remove_child(this.background_parent); + this.dash._background.style = this.old_style; + + DASH_STYLES.forEach( + style => this.dash.remove_style_class_name(style) + ); + }); + + dash_blur.connections.connect(dash_blur, 'update-sigma', () => { + this.effect.sigma = this.dash_blur.sigma; + }); + + dash_blur.connections.connect(dash_blur, 'update-brightness', () => { + this.effect.brightness = this.dash_blur.brightness; + }); + + dash_blur.connections.connect(dash_blur, 'override-background', () => { + this.dash._background.style = null; + + DASH_STYLES.forEach( + style => this.dash.remove_style_class_name(style) + ); + + this.dash.set_style_class_name( + DASH_STYLES[this.prefs.dash_to_dock.STYLE_DASH_TO_DOCK] + ); + }); + + dash_blur.connections.connect(dash_blur, 'reset-background', () => { + this.dash._background.style = this.old_style; + + DASH_STYLES.forEach( + style => this.dash.remove_style_class_name(style) + ); + }); + + dash_blur.connections.connect(dash_blur, 'show', () => { + this.effect.sigma = this.dash_blur.sigma; + }); + + dash_blur.connections.connect(dash_blur, 'hide', () => { + this.effect.sigma = 0; + }); + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > dash] ${str}`); + } +} + +var DashBlur = class DashBlur { + constructor(connections, prefs) { + this.dashes = []; + this.connections = connections; + this.prefs = prefs; + this.paint_signals = new PaintSignals(connections); + this.sigma = this.prefs.dash_to_dock.CUSTOMIZE + ? this.prefs.dash_to_dock.SIGMA + : this.prefs.SIGMA; + this.brightness = this.prefs.dash_to_dock.CUSTOMIZE + ? this.prefs.dash_to_dock.BRIGHTNESS + : this.prefs.BRIGHTNESS; + this.enabled = false; + } + + enable() { + this.connections.connect(Main.uiGroup, 'actor-added', (_, actor) => { + if ( + (actor.get_name() === "dashtodockContainer") && + (actor.constructor.name === 'DashToDock') + ) + this.try_blur(actor); + }); + + this.blur_existing_dashes(); + this.connect_to_overview(); + + this.enabled = true; + } + + // Finds all existing dashes on every monitor, and call `try_blur` on them + // We cannot only blur `Main.overview.dash`, as there could be several + blur_existing_dashes() { + this._log("searching for dash"); + + // blur every dash found, filtered by name + Main.uiGroup.get_children().filter((child) => { + return (child.get_name() === "dashtodockContainer") && + (child.constructor.name === 'DashToDock'); + }).forEach(this.try_blur.bind(this)); + } + + // Tries to blur the dash contained in the given actor + try_blur(dash_container) { + let dash_box = dash_container._slider.get_child(); + + // verify that we did not already blur that dash + if (!dash_box.get_children().some((child) => { + return child.get_name() === "dash-blurred-background-parent"; + })) { + this._log("dash to dock found, blurring it"); + + // finally blur the dash + let dash = dash_box.get_children().find(child => { + return child.get_name() === 'dash'; + }); + + this.dashes.push(this.blur_dash_from(dash, dash_container)); + } + } + + // Blurs the dash and returns a `DashInfos` containing its information + blur_dash_from(dash, dash_container) { + // the effect to be applied + let effect = new Shell.BlurEffect({ + brightness: this.brightness, + sigma: this.sigma, + mode: Shell.BlurMode.BACKGROUND + }); + + // dash background parent, not visible + let background_parent = new St.Widget({ + name: 'dash-blurred-background-parent', + style_class: 'dash-blurred-background-parent', + width: 0, + height: 0 + }); + + // dash background widget + let background = new St.Widget({ + name: 'dash-blurred-background', + style_class: 'dash-blurred-background', + x: 0, + y: dash_container._slider.y, + width: dash.width, + height: dash.height, + }); + + // updates size and position on change + this.connections.connect(dash_container._slider, 'notify::y', _ => { + background.y = dash_container._slider.y; + }); + this.connections.connect(dash, 'notify::width', _ => { + background.width = dash.width; + }); + this.connections.connect(dash, 'notify::height', _ => { + background.height = dash.height; + }); + + // add the widget to the dash + background.add_effect(effect); + background_parent.add_child(background); + dash.get_parent().insert_child_at_index(background_parent, 0); + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (this.prefs.HACKS_LEVEL === 1) { + this._log("dash hack level 1"); + this.paint_signals.disconnect_all(); + + let rp = () => { + effect.queue_repaint(); + }; + + dash._box.get_children().forEach((icon) => { + try { + let zone = icon.get_child_at_index(0); + + this.connections.connect(zone, [ + 'enter-event', 'leave-event', 'button-press-event' + ], rp); + } catch (e) { + this._log(`${e}, continuing`); + } + }); + + this.connections.connect(dash._box, 'actor-added', (_, actor) => { + try { + let zone = actor.get_child_at_index(0); + + this.connections.connect(zone, [ + 'enter-event', 'leave-event', 'button-press-event' + ], rp); + } catch (e) { + this._log(`${e}, continuing`); + } + }); + + let show_apps = dash._showAppsIcon; + + this.connections.connect(show_apps, [ + 'enter-event', 'leave-event', 'button-press-event' + ], rp); + + this.connections.connect(dash, 'leave-event', rp); + } else if (this.prefs.HACKS_LEVEL === 2) { + this._log("dash hack level 2"); + + this.paint_signals.connect(background, effect); + } else { + this.paint_signals.disconnect_all(); + } + + // create infos + let infos = new DashInfos( + this, dash, background_parent, effect, this.prefs + ); + + // update the background + this.update_background(); + + // returns infos + return infos; + } + + /// Connect when overview if opened/closed to hide/show the blur accordingly + connect_to_overview() { + this.connections.disconnect_all_for(Main.overview); + + if (this.prefs.dash_to_dock.UNBLUR_IN_OVERVIEW) { + this.connections.connect( + Main.overview, 'showing', this.hide.bind(this) + ); + this.connections.connect( + Main.overview, 'hidden', this.show.bind(this) + ); + } + }; + + /// Updates the background to either remove it or not, according to the + /// user preferences. + update_background() { + if (this.prefs.dash_to_dock.OVERRIDE_BACKGROUND) + this.emit('override-background', true); + else + this.emit('reset-background', true); + } + + set_sigma(sigma) { + this.sigma = sigma; + this.emit('update-sigma', true); + } + + set_brightness(brightness) { + this.brightness = brightness; + this.emit('update-brightness', true); + } + + // not implemented for dynamic blur + set_color(c) { } + set_noise_amount(n) { } + set_noise_lightness(l) { } + + disable() { + this._log("removing blur from dashes"); + + this.emit('remove-dashes', true); + + this.dashes = []; + this.connections.disconnect_all(); + + this.enabled = false; + } + + show() { + this.emit('show', true); + } + hide() { + this.emit('hide', true); + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > dash manager] ${str}`); + } +}; + +Signals.addSignalMethods(DashBlur.prototype); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/lockscreen.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/lockscreen.js new file mode 100644 index 0000000..b52acb6 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/lockscreen.js @@ -0,0 +1,171 @@ +'use strict'; + +const { St, Shell } = imports.gi; +const Main = imports.ui.main; +const Background = imports.ui.background; +const UnlockDialog = imports.ui.unlockDialog.UnlockDialog; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const ColorEffect = Me.imports.effects.color_effect.ColorEffect; +const NoiseEffect = Me.imports.effects.noise_effect.NoiseEffect; + +let sigma; +let brightness; +let color; +let noise; +let lightness; + +const original_createBackground = + UnlockDialog.prototype._createBackground; +const original_updateBackgroundEffects = + UnlockDialog.prototype._updateBackgroundEffects; + + +var LockscreenBlur = class LockscreenBlur { + constructor(connections, prefs) { + this.connections = connections; + this.prefs = prefs; + } + + enable() { + this._log("blurring lockscreen"); + + brightness = this.prefs.lockscreen.CUSTOMIZE + ? this.prefs.lockscreen.BRIGHTNESS + : this.prefs.BRIGHTNESS; + sigma = this.prefs.lockscreen.CUSTOMIZE + ? this.prefs.lockscreen.SIGMA + : this.prefs.SIGMA; + color = this.prefs.lockscreen.CUSTOMIZE + ? this.prefs.lockscreen.COLOR + : this.prefs.COLOR; + noise = this.prefs.lockscreen.CUSTOMIZE + ? this.prefs.lockscreen.NOISE_AMOUNT + : this.prefs.NOISE_AMOUNT; + lightness = this.prefs.lockscreen.CUSTOMIZE + ? this.prefs.lockscreen.NOISE_LIGHTNESS + : this.prefs.NOISE_LIGHTNESS; + + this.update_lockscreen(); + } + + update_lockscreen() { + UnlockDialog.prototype._createBackground = + this._createBackground; + UnlockDialog.prototype._updateBackgroundEffects = + this._updateBackgroundEffects; + } + + _createBackground(monitorIndex) { + let monitor = Main.layoutManager.monitors[monitorIndex]; + let widget = new St.Widget({ + style_class: "screen-shield-background", + x: monitor.x, + y: monitor.y, + width: monitor.width, + height: monitor.height, + }); + + let blur_effect = new Shell.BlurEffect({ + name: 'blur', + sigma: sigma, + brightness: brightness + }); + + // store the scale in the effect in order to retrieve later + blur_effect.scale = monitor.geometry_scale; + + let color_effect = new ColorEffect({ + name: 'color', + color: color + }); + + let noise_effect = new NoiseEffect({ + name: 'noise', + noise: noise, + lightness: lightness + }); + + widget.add_effect(color_effect); + widget.add_effect(noise_effect); + widget.add_effect(blur_effect); + + let bgManager = new Background.BackgroundManager({ + container: widget, + monitorIndex, + controlPosition: false, + }); + + this._bgManagers.push(bgManager); + + this._backgroundGroup.add_child(widget); + } + + _updateBackgroundEffects() { + for (const widget of this._backgroundGroup) { + const color_effect = widget.get_effect('blur'); + const noise_effect = widget.get_effect('blur'); + const blur_effect = widget.get_effect('blur'); + + if (color_effect) + color_effect.set({ + color: color + }); + + if (noise_effect) { + noise_effect.set({ + noise: noise, + lightness: lightness, + }); + } + + if (blur_effect) { + blur_effect.set({ + brightness: brightness, + sigma: sigma * blur_effect.scale, + }); + } + } + } + + set_sigma(s) { + sigma = s; + this.update_lockscreen(); + } + + set_brightness(b) { + brightness = b; + this.update_lockscreen(); + } + + set_color(c) { + color = c; + this.update_lockscreen(); + } + + set_noise_amount(n) { + noise = n; + this.update_lockscreen(); + } + + set_noise_lightness(l) { + lightness = l; + this.update_lockscreen(); + } + + disable() { + this._log("removing blur from lockscreen"); + + UnlockDialog.prototype._createBackground = + original_createBackground; + UnlockDialog.prototype._updateBackgroundEffects = + original_updateBackgroundEffects; + + this.connections.disconnect_all(); + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > lockscreen] ${str}`); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/overview.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/overview.js new file mode 100644 index 0000000..4217822 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/overview.js @@ -0,0 +1,294 @@ +'use strict'; + +const { Shell, Gio, Meta } = imports.gi; +const Main = imports.ui.main; + +const { WorkspaceAnimationController } = imports.ui.workspaceAnimation; +const wac_proto = WorkspaceAnimationController.prototype; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const ColorEffect = Me.imports.effects.color_effect.ColorEffect; +const NoiseEffect = Me.imports.effects.noise_effect.NoiseEffect; + +const OVERVIEW_COMPONENTS_STYLE = [ + "", + "overview-components-light", + "overview-components-dark", + "overview-components-transparent" +]; + + +var OverviewBlur = class OverviewBlur { + constructor(connections, prefs) { + this.connections = connections; + this.effects = []; + this.prefs = prefs; + this._workspace_switch_bg_actors = []; + this.enabled = false; + } + + enable() { + this._log("blurring overview"); + + // connect to every background change (even without changing image) + // FIXME this signal is fired very often, so we should find another one + // fired only when necessary (but that still catches all cases) + this.connections.connect( + Main.layoutManager._backgroundGroup, + 'notify', + _ => { + this._log("updated background"); + this.update_backgrounds(); + } + ); + + // connect to monitors change + this.connections.connect( + Main.layoutManager, + 'monitors-changed', + _ => { + if (Main.screenShield && !Main.screenShield.locked) { + this._log("changed monitors"); + this.update_backgrounds(); + } + } + ); + + // add css class name for workspace-switch background + Main.uiGroup.add_style_class_name("blurred-overview"); + + // add css class name to make components semi-transparent if wanted + this.update_components_classname(); + + // update backgrounds when the component is enabled + this.update_backgrounds(); + + + // part for the workspace animation switch + + // make sure not to do this part if the extension was enabled prior, as + // the functions would call themselves and cause infinite recursion + if (!this.enabled) { + // store original workspace switching methods for restoring them on + // disable() + this._original_PrepareSwitch = wac_proto._prepareWorkspaceSwitch; + this._original_FinishSwitch = wac_proto._finishWorkspaceSwitch; + + const w_m = global.workspace_manager; + const outer_this = this; + + // create a blurred background actor for each monitor during a workspace + // switch + wac_proto._prepareWorkspaceSwitch = function (...params) { + outer_this._log("prepare workspace switch"); + outer_this._original_PrepareSwitch.apply(this, params); + + // this permits to show the blur behind windows that are on + // workspaces on the left and right + if ( + outer_this.prefs.applications.BLUR + ) { + let ws_index = w_m.get_active_workspace_index(); + [ws_index - 1, ws_index + 1].forEach( + i => w_m.get_workspace_by_index(i)?.list_windows().forEach( + window => window.get_compositor_private().show() + ) + ); + } + + Main.layoutManager.monitors.forEach(monitor => { + if ( + !( + Meta.prefs_get_workspaces_only_on_primary() && + (monitor !== Main.layoutManager.primaryMonitor) + ) + ) { + const bg_actor = outer_this.create_background_actor( + monitor + ); + + Main.uiGroup.insert_child_above( + bg_actor, + global.window_group + ); + + // store the actors so that we can delete them later + outer_this._workspace_switch_bg_actors.push(bg_actor); + } + }); + }; + + // remove the workspace-switch actors when the switch is done + wac_proto._finishWorkspaceSwitch = function (...params) { + outer_this._log("finish workspace switch"); + outer_this._original_FinishSwitch.apply(this, params); + + // this hides windows that are not on the current workspace + if ( + outer_this.prefs.applications.BLUR + ) + for (let i = 0; i < w_m.get_n_workspaces(); i++) { + if (i != w_m.get_active_workspace_index()) + w_m.get_workspace_by_index(i)?.list_windows().forEach( + window => window.get_compositor_private().hide() + ); + } + + outer_this._workspace_switch_bg_actors.forEach(actor => { + actor.destroy(); + }); + outer_this._workspace_switch_bg_actors = []; + }; + } + + this.enabled = true; + } + + update_backgrounds() { + // remove every old background + Main.layoutManager.overviewGroup.get_children().forEach(actor => { + if (actor.constructor.name === 'Meta_BackgroundActor') { + Main.layoutManager.overviewGroup.remove_child(actor); + actor.destroy(); + } + }); + this.effects = []; + + // add new backgrounds + Main.layoutManager.monitors.forEach(monitor => { + const bg_actor = this.create_background_actor(monitor); + + Main.layoutManager.overviewGroup.insert_child_at_index( + bg_actor, + monitor.index + ); + }); + } + + create_background_actor(monitor) { + let bg_actor = new Meta.BackgroundActor; + let background = Main.layoutManager._backgroundGroup.get_child_at_index( + Main.layoutManager.monitors.length - monitor.index - 1 + ); + + if (!background) { + this._log("could not get background for overview"); + return bg_actor; + } + + bg_actor.set_content(background.get_content()); + + let blur_effect = new Shell.BlurEffect({ + brightness: this.prefs.overview.CUSTOMIZE + ? this.prefs.overview.BRIGHTNESS + : this.prefs.BRIGHTNESS, + sigma: this.prefs.overview.CUSTOMIZE + ? this.prefs.overview.SIGMA + : this.prefs.SIGMA + * monitor.geometry_scale, + mode: Shell.BlurMode.ACTOR + }); + + // store the scale in the effect in order to retrieve it in set_sigma + blur_effect.scale = monitor.geometry_scale; + + let color_effect = new ColorEffect({ + color: this.prefs.overview.CUSTOMIZE + ? this.prefs.overview.COLOR + : this.prefs.COLOR + }); + + let noise_effect = new NoiseEffect({ + noise: this.prefs.overview.CUSTOMIZE + ? this.prefs.overview.NOISE_AMOUNT + : this.prefs.NOISE_AMOUNT, + lightness: this.prefs.overview.CUSTOMIZE + ? this.prefs.overview.NOISE_LIGHTNESS + : this.prefs.NOISE_LIGHTNESS + }); + + bg_actor.add_effect(color_effect); + bg_actor.add_effect(noise_effect); + bg_actor.add_effect(blur_effect); + this.effects.push({ blur_effect, color_effect, noise_effect }); + + bg_actor.set_x(monitor.x); + bg_actor.set_y(monitor.y); + + return bg_actor; + } + + /// Updates the classname to style overview components with semi-transparent + /// backgrounds. + update_components_classname() { + OVERVIEW_COMPONENTS_STYLE.forEach( + style => Main.uiGroup.remove_style_class_name(style) + ); + + Main.uiGroup.add_style_class_name( + OVERVIEW_COMPONENTS_STYLE[this.prefs.overview.STYLE_COMPONENTS] + ); + } + + set_sigma(s) { + this.effects.forEach(effect => { + effect.blur_effect.sigma = s * effect.blur_effect.scale; + }); + } + + set_brightness(b) { + this.effects.forEach(effect => { + effect.blur_effect.brightness = b; + }); + } + + set_color(c) { + this.effects.forEach(effect => { + effect.color_effect.color = c; + }); + } + + set_noise_amount(n) { + this.effects.forEach(effect => { + effect.noise_effect.noise = n; + }); + } + + set_noise_lightness(l) { + this.effects.forEach(effect => { + effect.noise_effect.lightness = l; + }); + } + + disable() { + this._log("removing blur from overview"); + Main.layoutManager.overviewGroup.get_children().forEach(actor => { + if (actor.constructor.name === 'Meta_BackgroundActor') { + Main.layoutManager.overviewGroup.remove_child(actor); + } + }); + Main.uiGroup.remove_style_class_name("blurred-overview"); + OVERVIEW_COMPONENTS_STYLE.forEach( + style => Main.uiGroup.remove_style_class_name(style) + ); + + // make sure to absolutely not do this if the component was not enabled + // prior, as this would cause infinite recursion + if (this.enabled) { + // restore original behavior + if (this._original_PrepareSwitch) + wac_proto._prepareWorkspaceSwitch = this._original_PrepareSwitch; + if (this._original_FinishSwitch) + wac_proto._finishWorkspaceSwitch = this._original_FinishSwitch; + } + + this.effects = []; + this.connections.disconnect_all(); + this.enabled = false; + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > overview] ${str}`); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/panel.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/panel.js new file mode 100644 index 0000000..5df1756 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/panel.js @@ -0,0 +1,660 @@ +'use strict'; + +const { St, Shell, Meta, Gio, GLib } = imports.gi; +const Main = imports.ui.main; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { PaintSignals } = Me.imports.effects.paint_signals; +const ColorEffect = Me.imports.effects.color_effect.ColorEffect; +const NoiseEffect = Me.imports.effects.noise_effect.NoiseEffect; + +const DASH_TO_PANEL_UUID = 'dash-to-panel@jderose9.github.com'; + +const PANEL_STYLES = [ + "transparent-panel", + "light-panel", + "dark-panel" +]; + + +var PanelBlur = class PanelBlur { + constructor(connections, prefs) { + this.connections = connections; + this.window_signal_ids = new Map(); + this.prefs = prefs; + this.actors_list = []; + this.enabled = false; + } + + enable() { + this._log("blurring top panel"); + + // check for panels when Dash to Panel is activated + this.connections.connect( + Main.extensionManager, + 'extension-state-changed', + (_, extension) => { + if (extension.uuid === DASH_TO_PANEL_UUID + && extension.state === 1 + ) { + this.connections.connect( + global.dashToPanel, + 'panels-created', + _ => this.blur_dtp_panels() + ); + + this.blur_existing_panels(); + } + } + ); + + this.blur_existing_panels(); + + // connect to overview being opened/closed, and dynamically show or not + // the blur when a window is near a panel + this.connect_to_windows_and_overview(); + + // connect to every background change (even without changing image) + // FIXME this signal is fired very often, so we should find another one + // fired only when necessary (but that still catches all cases) + this.connections.connect( + Main.layoutManager._backgroundGroup, + 'notify', + _ => this.actors_list.forEach(actors => + this.update_wallpaper(actors) + ) + ); + + // connect to monitors change + this.connections.connect( + Main.layoutManager, + 'monitors-changed', + _ => { + if (Main.screenShield && !Main.screenShield.locked) { + this.reset(); + } + } + ); + + this.enabled = true; + } + + reset() { + this._log("resetting..."); + + this.disable(); + setTimeout(_ => this.enable(), 1); + } + + /// Check for already existing panels and blur them if they are not already + blur_existing_panels() { + // check if dash-to-panel is present + if (global.dashToPanel) { + // blur already existing ones + if (global.dashToPanel.panels) + this.blur_dtp_panels(); + } else { + // if no dash-to-panel, blur the main and only panel + this.maybe_blur_panel(Main.panel); + } + } + + blur_dtp_panels() { + // FIXME when Dash to Panel changes its size, it seems it creates new + // panels; but I can't get to delete old widgets + + // blur every panel found + global.dashToPanel.panels.forEach(p => { + this.maybe_blur_panel(p.panel); + }); + + // if main panel is not included in the previous panels, blur it + if ( + !global.dashToPanel.panels + .map(p => p.panel) + .includes(Main.panel) + ) + this.maybe_blur_panel(Main.panel); + }; + + /// Blur a panel only if it is not already blurred (contained in the list) + maybe_blur_panel(panel) { + // check if the panel is contained in the list + let actors = this.actors_list.find( + actors => actors.widgets.panel == panel + ); + + if (!actors) + // if the actors is not blurred, blur it + this.blur_panel(panel); + else + // if it is blurred, update the blur anyway + this.change_blur_type(actors); + } + + /// Blur a panel + blur_panel(panel) { + let panel_box = panel.get_parent(); + let is_dtp_panel = false; + if (!panel_box.name) { + is_dtp_panel = true; + panel_box = panel_box.get_parent(); + } + + let monitor = this.find_monitor_for(panel); + if (!monitor) + return; + + let background_parent = new St.Widget({ + name: 'topbar-blurred-background-parent', + x: 0, y: 0, width: 0, height: 0 + }); + + let background = this.prefs.panel.STATIC_BLUR + ? new Meta.BackgroundActor + : new St.Widget; + + background_parent.add_child(background); + + // insert background parent + panel_box.insert_child_at_index(background_parent, 0); + + let blur = new Shell.BlurEffect({ + brightness: this.prefs.panel.CUSTOMIZE + ? this.prefs.panel.BRIGHTNESS + : this.prefs.BRIGHTNESS, + sigma: this.prefs.panel.CUSTOMIZE + ? this.prefs.panel.SIGMA + : this.prefs.SIGMA + * monitor.geometry_scale, + mode: this.prefs.panel.STATIC_BLUR + ? Shell.BlurMode.ACTOR + : Shell.BlurMode.BACKGROUND + }); + + // store the scale in the effect in order to retrieve it in set_sigma + blur.scale = monitor.geometry_scale; + + let color = new ColorEffect({ + color: this.prefs.panel.CUSTOMIZE + ? this.prefs.panel.COLOR + : this.prefs.COLOR + }); + + let noise = new NoiseEffect({ + noise: this.prefs.panel.CUSTOMIZE + ? this.prefs.panel.NOISE_AMOUNT + : this.prefs.NOISE_AMOUNT, + lightness: this.prefs.panel.CUSTOMIZE + ? this.prefs.panel.NOISE_LIGHTNESS + : this.prefs.NOISE_LIGHTNESS + }); + + let paint_signals = new PaintSignals(this.connections); + + let actors = { + widgets: { panel, panel_box, background, background_parent }, + effects: { blur, color, noise }, + paint_signals, + monitor, + is_dtp_panel + }; + + this.actors_list.push(actors); + + // perform updates + this.change_blur_type(actors); + + // connect to panel, panel_box and its parent position or size change + // this should fire update_size every time one of its params change + this.connections.connect( + panel, + 'notify::position', + _ => this.update_size(actors) + ); + this.connections.connect( + panel_box, + ['notify::size', 'notify::position'], + _ => this.update_size(actors) + ); + this.connections.connect( + panel_box.get_parent(), + 'notify::position', + _ => this.update_size(actors) + ); + } + + update_all_blur_type() { + this.actors_list.forEach(actors => this.change_blur_type(actors)); + } + + change_blur_type(actors) { + let is_static = this.prefs.panel.STATIC_BLUR; + + // reset widgets to right state + actors.widgets.background_parent.remove_child(actors.widgets.background); + actors.widgets.background.remove_effect(actors.effects.blur); + actors.widgets.background.remove_effect(actors.effects.color); + actors.widgets.background.remove_effect(actors.effects.noise); + + // create new background actor + actors.widgets.background = is_static + ? new Meta.BackgroundActor + : new St.Widget; + + // change blur mode + actors.effects.blur.set_mode(is_static ? 0 : 1); + + // disable other effects if the blur is dynamic, as they makes it opaque + actors.effects.color._static = is_static; + actors.effects.noise._static = is_static; + actors.effects.color.update_enabled(); + actors.effects.noise.update_enabled(); + + // add the effects in order + actors.widgets.background.add_effect(actors.effects.color); + actors.widgets.background.add_effect(actors.effects.noise); + actors.widgets.background.add_effect(actors.effects.blur); + + // add the background actor behing the panel + actors.widgets.background_parent.add_child(actors.widgets.background); + + // perform updates + this.update_wallpaper(actors); + this.update_size(actors); + + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (!is_static) { + if (this.prefs.HACKS_LEVEL === 1) { + this._log("panel hack level 1"); + actors.paint_signals.disconnect_all(); + + let rp = () => { actors.effects.blur.queue_repaint(); }; + + this.connections.connect(actors.widgets.panel, [ + 'enter-event', 'leave-event', 'button-press-event' + ], rp); + + actors.widgets.panel.get_children().forEach(child => { + this.connections.connect(child, [ + 'enter-event', 'leave-event', 'button-press-event' + ], rp); + }); + } else if (this.prefs.HACKS_LEVEL === 2) { + this._log("panel hack level 2"); + actors.paint_signals.disconnect_all(); + + actors.paint_signals.connect( + actors.widgets.background, actors.effects.blur + ); + } else { + actors.paint_signals.disconnect_all(); + } + } + } + + update_wallpaper(actors) { + // if static blur, get right wallpaper and update blur with it + if (this.prefs.panel.STATIC_BLUR) { + let bg = Main.layoutManager._backgroundGroup.get_child_at_index( + Main.layoutManager.monitors.length + - this.find_monitor_for(actors.widgets.panel).index - 1 + ); + if (bg) + actors.widgets.background.set_content(bg.get_content()); + else + this._log("could not get background for panel"); + } + } + + update_size(actors) { + let panel = actors.widgets.panel; + let panel_box = actors.widgets.panel_box; + let background = actors.widgets.background; + let monitor = this.find_monitor_for(panel); + if (!monitor) + return; + + let [width, height] = panel_box.get_size(); + background.width = width; + background.height = height; + + // if static blur, need to clip the background + if (this.prefs.panel.STATIC_BLUR) { + // an alternative to panel.get_transformed_position, because it + // sometimes yields NaN (probably when the actor is not fully + // positionned yet) + let [p_x, p_y] = panel_box.get_position(); + let [p_p_x, p_p_y] = panel_box.get_parent().get_position(); + let x = p_x + p_p_x - monitor.x; + let y = p_y + p_p_y - monitor.y; + + background.set_clip(x, y, width, height); + background.x = -x; + background.y = -y; + + // fixes a bug where the blur is washed away when changing the sigma + this.invalidate_blur(actors); + } else { + background.x = panel.x; + background.y = panel.y; + } + + // update the monitor panel is on + actors.monitor = this.find_monitor_for(panel); + } + + /// An helper function to find the monitor in which an actor is situated, + /// there might be a pre-existing function in GLib already + find_monitor_for(actor) { + let extents = actor.get_transformed_extents(); + let rect = new Meta.Rectangle({ + x: extents.get_x(), + y: extents.get_y(), + width: extents.get_width(), + height: extents.get_height(), + }); + + let index = global.display.get_monitor_index_for_rect(rect); + + return Main.layoutManager.monitors[index]; + } + + /// Connect when overview if opened/closed to hide/show the blur accordingly + /// + /// If HIDETOPBAR is set, we need just to hide the blur when showing appgrid + /// (so no shadow is cropped) + connect_to_overview() { + // may be called when panel blur is disabled, if hidetopbar + // compatibility is toggled on/off + // if this is the case, do nothing as only the panel blur interfers with + // hidetopbar + if ( + this.prefs.panel.BLUR && + this.prefs.panel.UNBLUR_IN_OVERVIEW + ) { + if (!this.prefs.hidetopbar.COMPATIBILITY) { + this.connections.connect( + Main.overview, 'showing', this.hide.bind(this) + ); + this.connections.connect( + Main.overview, 'hidden', this.show.bind(this) + ); + } else { + let appDisplay = Main.overview._overview._controls._appDisplay; + + this.connections.connect( + appDisplay, 'show', this.hide.bind(this) + ); + this.connections.connect( + appDisplay, 'hide', this.show.bind(this) + ); + } + + } + } + + /// Connect to windows disable transparency when a window is too close + connect_to_windows() { + if ( + this.prefs.panel.OVERRIDE_BACKGROUND_DYNAMICALLY + ) { + // connect to overview opening/closing + this.connections.connect(Main.overview, ['showing', 'hiding'], + this.update_visibility.bind(this) + ); + + // connect to session mode update + this.connections.connect(Main.sessionMode, 'updated', + this.update_visibility.bind(this) + ); + + // manage already-existing windows + for (const meta_window_actor of global.get_window_actors()) { + this.on_window_actor_added( + meta_window_actor.get_parent(), meta_window_actor + ); + } + + // manage windows at their creation/removal + this.connections.connect(global.window_group, 'actor-added', + this.on_window_actor_added.bind(this) + ); + this.connections.connect(global.window_group, 'actor-removed', + this.on_window_actor_removed.bind(this) + ); + + // connect to a workspace change + this.connections.connect(global.window_manager, 'switch-workspace', + this.update_visibility.bind(this) + ); + + // perform early update + this.update_visibility(); + } else { + // reset transparency for every panels + this.actors_list.forEach( + actors => this.set_should_override_panel(actors, true) + ); + } + } + + /// An helper to connect to both the windows and overview signals. + /// This is the only function that should be directly called, to prevent + /// inconsistencies with signals not being disconnected. + connect_to_windows_and_overview() { + this.disconnect_from_windows_and_overview(); + this.connect_to_overview(); + this.connect_to_windows(); + } + + /// Disconnect all the connections created by connect_to_windows + disconnect_from_windows_and_overview() { + // disconnect the connections to actors + for (const actor of [ + Main.overview, Main.sessionMode, + global.window_group, global.window_manager, + Main.overview._overview._controls._appDisplay + ]) { + this.connections.disconnect_all_for(actor); + } + + // disconnect the connections from windows + for (const [actor, ids] of this.window_signal_ids) { + for (const id of ids) { + actor.disconnect(id); + } + } + this.window_signal_ids = new Map(); + } + + /// Callback when a new window is added + on_window_actor_added(container, meta_window_actor) { + this.window_signal_ids.set(meta_window_actor, [ + meta_window_actor.connect('notify::allocation', + _ => this.update_visibility() + ), + meta_window_actor.connect('notify::visible', + _ => this.update_visibility() + ) + ]); + this.update_visibility(); + } + + /// Callback when a window is removed + on_window_actor_removed(container, meta_window_actor) { + for (const signalId of this.window_signal_ids.get(meta_window_actor)) { + meta_window_actor.disconnect(signalId); + } + this.window_signal_ids.delete(meta_window_actor); + this.update_visibility(); + } + + /// Update the visibility of the blur effect + update_visibility() { + if ( + Main.panel.has_style_pseudo_class('overview') + || !Main.sessionMode.hasWindows + ) { + this.actors_list.forEach( + actors => this.set_should_override_panel(actors, true) + ); + return; + } + + if (!Main.layoutManager.primaryMonitor) + return; + + // get all the windows in the active workspace that are visible + const workspace = global.workspace_manager.get_active_workspace(); + const windows = workspace.list_windows().filter(meta_window => + meta_window.showing_on_its_workspace() + && !meta_window.is_hidden() + && meta_window.get_window_type() !== Meta.WindowType.DESKTOP + // exclude Desktop Icons NG + && meta_window.get_gtk_application_id() !== "com.rastersoft.ding" + ); + + // check if at least one window is near enough to each panel and act + // accordingly + const scale = St.ThemeContext.get_for_stage(global.stage).scale_factor; + this.actors_list + // do not apply for dtp panels, as it would only cause bugs and it + // can be done from its preferences anyway + .filter(actors => !actors.is_dtp_panel) + .forEach(actors => { + let panel = actors.widgets.panel; + let panel_top = panel.get_transformed_position()[1]; + let panel_bottom = panel_top + panel.get_height(); + + // check if at least a window is near enough the panel + let window_overlap_panel = false; + windows.forEach(meta_window => { + let window_monitor_i = meta_window.get_monitor(); + let same_monitor = actors.monitor.index == window_monitor_i; + + let window_vertical_pos = meta_window.get_frame_rect().y; + + // if so, and if in the same monitor, then it overlaps + if (same_monitor + && + window_vertical_pos < panel_bottom + 5 * scale + ) + window_overlap_panel = true; + }); + + // if no window overlaps, then the panel is transparent + this.set_should_override_panel( + actors, !window_overlap_panel + ); + }); + } + + /// Choose wether or not the panel background should be overriden, in + /// respect to its argument and the `override-background` setting. + set_should_override_panel(actors, should_override) { + let panel = actors.widgets.panel; + + PANEL_STYLES.forEach(style => panel.remove_style_class_name(style)); + + if ( + this.prefs.panel.OVERRIDE_BACKGROUND + && + should_override + ) + panel.add_style_class_name( + PANEL_STYLES[this.prefs.panel.STYLE_PANEL] + ); + } + + /// Fixes a bug where the blur is washed away when changing the sigma, or + /// enabling/disabling other effects. + invalidate_blur(actors) { + if (this.prefs.panel.STATIC_BLUR && actors.widgets.background) + actors.widgets.background.get_content().invalidate(); + } + + invalidate_all_blur() { + this.actors_list.forEach(actors => this.invalidate_blur(actors)); + } + + set_sigma(s) { + this.actors_list.forEach(actors => { + actors.effects.blur.sigma = s * actors.effects.blur.scale; + this.invalidate_blur(actors); + }); + } + + set_brightness(b) { + this.actors_list.forEach(actors => { + actors.effects.blur.brightness = b; + }); + } + + set_color(c) { + this.actors_list.forEach(actors => { + actors.effects.color.color = c; + }); + } + + set_noise_amount(n) { + this.actors_list.forEach(actors => { + actors.effects.noise.noise = n; + }); + } + + set_noise_lightness(l) { + this.actors_list.forEach(actors => { + actors.effects.noise.lightness = l; + }); + } + + show() { + this.actors_list.forEach(actors => { + actors.widgets.background_parent.show(); + }); + } + + hide() { + this.actors_list.forEach(actors => { + actors.widgets.background_parent.hide(); + }); + } + + disable() { + this._log("removing blur from top panel"); + + this.disconnect_from_windows_and_overview(); + + this.actors_list.forEach(actors => { + this.set_should_override_panel(actors, false); + try { + actors.widgets.panel_box.remove_child( + actors.widgets.background_parent + ); + } catch (e) { } + + }); + + this.actors_list = []; + + this.connections.disconnect_all(); + + this.enabled = false; + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > panel] ${str}`); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/screenshot.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/screenshot.js new file mode 100644 index 0000000..333eccd --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/screenshot.js @@ -0,0 +1,166 @@ +'use strict'; + +const { Shell, Gio, Meta } = imports.gi; +const Main = imports.ui.main; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const ColorEffect = Me.imports.effects.color_effect.ColorEffect; +const NoiseEffect = Me.imports.effects.noise_effect.NoiseEffect; + + +var ScreenshotBlur = class ScreenshotBlur { + constructor(connections, prefs) { + this.connections = connections; + this.effects = []; + this.prefs = prefs; + } + + enable() { + this._log("blurring screenshot's window selector"); + + // connect to every background change (even without changing image) + // FIXME this signal is fired very often, so we should find another one + // fired only when necessary (but that still catches all cases) + this.connections.connect( + Main.layoutManager._backgroundGroup, + 'notify', + _ => { + this._log("updated background for screenshot's window selector"); + this.update_backgrounds(); + } + ); + + // connect to monitors change + this.connections.connect( + Main.layoutManager, + 'monitors-changed', + _ => { + if (Main.screenShield && !Main.screenShield.locked) { + this._log("changed monitors for screenshot's window selector"); + this.update_backgrounds(); + } + } + ); + + // update backgrounds when the component is enabled + this.update_backgrounds(); + } + + update_backgrounds() { + // remove every old background + this.remove(); + + // add new backgrounds + for (let i = 0; i < Main.screenshotUI._windowSelectors.length; i++) { + const actor = Main.screenshotUI._windowSelectors[i]; + const monitor = Main.layoutManager.monitors[i]; + + if (!monitor) + continue; + + const bg_actor = this.create_background_actor(monitor); + actor.insert_child_at_index(bg_actor, 0); + actor._blur_actor = bg_actor; + } + } + + create_background_actor(monitor) { + let bg_actor = new Meta.BackgroundActor; + let background = Main.layoutManager._backgroundGroup.get_child_at_index( + Main.layoutManager.monitors.length - monitor.index - 1 + ); + + if (!background) { + this._log("could not get background for screenshot's window selector"); + return bg_actor; + } + + bg_actor.set_content(background.get_content()); + + let blur_effect = new Shell.BlurEffect({ + brightness: this.prefs.screenshot.CUSTOMIZE + ? this.prefs.screenshot.BRIGHTNESS + : this.prefs.BRIGHTNESS, + sigma: this.prefs.screenshot.CUSTOMIZE + ? this.prefs.screenshot.SIGMA + : this.prefs.SIGMA + * monitor.geometry_scale, + mode: Shell.BlurMode.ACTOR + }); + + // store the scale in the effect in order to retrieve it in set_sigma + blur_effect.scale = monitor.geometry_scale; + + let color_effect = new ColorEffect({ + color: this.prefs.screenshot.CUSTOMIZE + ? this.prefs.screenshot.COLOR + : this.prefs.COLOR + }); + + let noise_effect = new NoiseEffect({ + noise: this.prefs.screenshot.CUSTOMIZE + ? this.prefs.screenshot.NOISE_AMOUNT + : this.prefs.NOISE_AMOUNT, + lightness: this.prefs.screenshot.CUSTOMIZE + ? this.prefs.screenshot.NOISE_LIGHTNESS + : this.prefs.NOISE_LIGHTNESS + }); + + bg_actor.add_effect(color_effect); + bg_actor.add_effect(noise_effect); + bg_actor.add_effect(blur_effect); + this.effects.push({ blur_effect, color_effect, noise_effect }); + + return bg_actor; + } + + set_sigma(s) { + this.effects.forEach(effect => { + effect.blur_effect.sigma = s * effect.blur_effect; + }); + } + + set_brightness(b) { + this.effects.forEach(effect => { + effect.blur_effect.brightness = b; + }); + } + + set_color(c) { + this.effects.forEach(effect => { + effect.color_effect.color = c; + }); + } + + set_noise_amount(n) { + this.effects.forEach(effect => { + effect.noise_effect.noise = n; + }); + } + + set_noise_lightness(l) { + this.effects.forEach(effect => { + effect.noise_effect.lightness = l; + }); + } + + remove() { + Main.screenshotUI._windowSelectors.forEach(actor => { + if (actor._blur_actor) + actor.remove_child(actor._blur_actor); + }); + this.effects = []; + } + + disable() { + this._log("removing blur from screenshot's window selector"); + + this.remove(); + this.connections.disconnect_all(); + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > screenshot] ${str}`); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/window_list.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/window_list.js new file mode 100644 index 0000000..94883da --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/components/window_list.js @@ -0,0 +1,165 @@ +'use strict'; + +const { St, Shell, Meta, Gio } = imports.gi; +const Main = imports.ui.main; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const { PaintSignals } = Me.imports.effects.paint_signals; + + +var WindowListBlur = class WindowListBlur { + constructor(connections, prefs) { + this.connections = connections; + this.prefs = prefs; + this.paint_signals = new PaintSignals(connections); + this.effects = []; + } + + enable() { + this._log("blurring window list"); + + // blur if window-list is found + Main.layoutManager.uiGroup.get_children().forEach( + child => this.try_blur(child) + ); + + // listen to new actors in `Main.layoutManager.uiGroup` and blur it if + // if is window-list + this.connections.connect( + Main.layoutManager.uiGroup, + 'actor-added', + (_, child) => this.try_blur(child) + ); + + // connect to overview + this.connections.connect(Main.overview, 'showing', _ => { + this.hide(); + }); + this.connections.connect(Main.overview, 'hidden', _ => { + this.show(); + }); + } + + try_blur(child) { + if ( + child.constructor.name === "WindowList" && + child.style !== "background:transparent;" + ) { + this._log("found window list to blur"); + + let blur_effect = new Shell.BlurEffect({ + name: 'window-list-blur', + sigma: this.prefs.window_list.CUSTOMIZE + ? this.prefs.window_list.SIGMA + : this.prefs.SIGMA, + brightness: this.prefs.window_list.CUSTOMIZE + ? this.prefs.window_list.BRIGHTNESS + : this.prefs.BRIGHTNESS, + mode: Shell.BlurMode.BACKGROUND + }); + + child.set_style("background:transparent;"); + child.add_effect(blur_effect); + this.effects.push({ blur_effect }); + + child._windowList.get_children().forEach( + window => this.blur_window_button(window) + ); + + this.connections.connect( + child._windowList, + 'actor-added', + (_, window) => this.blur_window_button(window) + ); + + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (this.prefs.HACKS_LEVEL === 1) { + this._log("window list hack level 1"); + + this.paint_signals.connect(child, blur_effect); + + } else if (this.prefs.HACKS_LEVEL === 2) { + this._log("window list hack level 2"); + + this.paint_signals.connect(child, blur_effect); + } else { + this.paint_signals.disconnect_all(); + } + } + } + + blur_window_button(window) { + window.get_child_at_index(0).set_style( + "box-shadow:none; background-color:rgba(0,0,0,0.2); border-radius:5px;" + ); + } + + try_remove_blur(child) { + if ( + child.constructor.name === "WindowList" && + child.style === "background:transparent;" + ) { + child.style = null; + child.remove_effect_by_name('window-list-blur'); + + child._windowList.get_children().forEach( + child => child.get_child_at_index(0).set_style(null) + ); + } + } + + set_sigma(s) { + this.effects.forEach(effect => { + effect.blur_effect.sigma = s; + }); + } + + set_brightness(b) { + this.effects.forEach(effect => { + effect.blur_effect.brightness = b; + }); + } + + // not implemented for dynamic blur + set_color(c) { } + set_noise_amount(n) { } + set_noise_lightness(l) { } + + hide() { + this.set_sigma(0); + } + + show() { + this.set_sigma( + this.prefs.window_list.CUSTOMIZE + ? this.prefs.window_list.SIGMA + : this.prefs.SIGMA + ); + } + + disable() { + this._log("removing blur from window list"); + + Main.layoutManager.uiGroup.get_children().forEach( + child => this.try_remove_blur(child) + ); + + this.effects = []; + this.connections.disconnect_all(); + } + + _log(str) { + if (this.prefs.DEBUG) + log(`[Blur my Shell > window list] ${str}`); + } +}; \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/connections.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/connections.js new file mode 100644 index 0000000..ec2f51f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/connections.js @@ -0,0 +1,104 @@ +'use strict'; + +const GObject = imports.gi.GObject; + +/// An object to easily manage signals. +var Connections = class Connections { + constructor() { + this.buffer = []; + } + + /// Adds a connection. + /// + /// Takes as arguments: + /// - an actor, which fires the signal + /// - signal(s) (string or array of strings), which are watched for + /// - a callback, which is called when the signal is fired + connect(actor, signals, handler) { + if (signals instanceof Array) { + signals.forEach(signal => { + let id = actor.connect(signal, handler); + this.process_connection(actor, id); + }); + } else { + let id = actor.connect(signals, handler); + this.process_connection(actor, id); + } + + } + + /// Process the given actor and id. + /// + /// This makes sure that the signal is disconnected when the actor is + /// destroyed, and that the signal can be managed through other Connections + /// methods. + process_connection(actor, id) { + let infos = { + actor: actor, + id: id + }; + + // remove the signal when the actor is destroyed + if ( + actor.connect && + ( + !(actor instanceof GObject.Object) || + GObject.signal_lookup('destroy', actor) + ) + ) { + let destroy_id = actor.connect('destroy', () => { + actor.disconnect(id); + actor.disconnect(destroy_id); + + let index = this.buffer.indexOf(infos); + if (index >= 0) { + this.buffer.splice(index, 1); + } + }); + } + + this.buffer.push(infos); + } + + /// Disconnects every connection found for an actor. + disconnect_all_for(actor) { + // get every connection stored for the actor + let actor_connections = this.buffer.filter( + infos => infos.actor === actor + ); + + // remove each of them + actor_connections.forEach((connection) => { + // disconnect + try { + connection.actor.disconnect(connection.id); + } catch (e) { + this._log(`error removing connection: ${e}; continuing`); + } + + // remove from buffer + let index = this.buffer.indexOf(connection); + this.buffer.splice(index, 1); + }); + } + + /// Disconnect every connection for each actor. + disconnect_all() { + this.buffer.forEach((connection) => { + // disconnect + try { + connection.actor.disconnect(connection.id); + } catch (e) { + this._log(`error removing connection: ${e}; continuing`); + } + }); + + // reset buffer + this.buffer = []; + } + + _log(str) { + // no need to check if DEBUG here as this._log is only used on error + log(`[Blur my Shell > connections] ${str}`); + } +}; \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/keys.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/keys.js new file mode 100644 index 0000000..beaa8e9 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/keys.js @@ -0,0 +1,131 @@ +'use strict'; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); + +const { Type } = Me.imports.conveniences.settings; + +// This lists the preferences keys +var Keys = [ + { + component: "general", schemas: [ + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.B, name: "color-and-noise" }, + { type: Type.I, name: "hacks-level" }, + { type: Type.B, name: "debug" }, + ] + }, + { + component: "overview", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.I, name: "style-components" }, + ] + }, + { + component: "appfolder", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.I, name: "style-dialogs" }, + ] + }, + { + component: "panel", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.B, name: "static-blur" }, + { type: Type.B, name: "unblur-in-overview" }, + { type: Type.B, name: "override-background" }, + { type: Type.I, name: "style-panel" }, + { type: Type.B, name: "override-background-dynamically" }, + ] + }, + { + component: "dash-to-dock", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.B, name: "static-blur" }, + { type: Type.B, name: "unblur-in-overview" }, + { type: Type.B, name: "override-background" }, + { type: Type.I, name: "style-dash-to-dock" }, + ] + }, + { + component: "applications", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.I, name: "opacity" }, + { type: Type.B, name: "blur-on-overview" }, + { type: Type.B, name: "enable-all" }, + { type: Type.AS, name: "whitelist" }, + { type: Type.AS, name: "blacklist" }, + ] + }, + { + component: "lockscreen", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "window-list", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "screenshot", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "hidetopbar", schemas: [ + { type: Type.B, name: "compatibility" }, + ] + }, +]; \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/settings.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/settings.js new file mode 100644 index 0000000..5c07472 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/conveniences/settings.js @@ -0,0 +1,185 @@ +'use strict'; + +const { Gio, GLib } = imports.gi; +const Signals = imports.signals; + +const ExtensionUtils = imports.misc.extensionUtils; + +/// An enum non-extensively describing the type of gsettings key. +var Type = { + B: 'Boolean', + I: 'Integer', + D: 'Double', + S: 'String', + C: 'Color', + AS: 'StringArray' +}; + +/// An object to get and manage the gsettings preferences. +/// +/// Should be initialized with an array of keys, for example: +/// +/// let prefs = new Prefs([ +/// { type: Type.I, name: "panel-corner-radius" }, +/// { type: Type.B, name: "debug" } +/// ]); +/// +/// Each {type, name} object represents a gsettings key, which must be created +/// in the gschemas.xml file of the extension. +var Prefs = class Prefs { + constructor(keys) { + let settings = this.settings = ExtensionUtils.getSettings(); + this.keys = keys; + + this.keys.forEach(bundle => { + let component = this; + let component_settings = settings; + if (bundle.component !== "general") { + let bundle_component = bundle.component.replaceAll('-', '_'); + this[bundle_component] = { + settings: this.settings.get_child(bundle.component) + }; + component = this[bundle_component]; + component_settings = settings.get_child(bundle.component); + } + + + bundle.schemas.forEach(key => { + let property_name = this.get_property_name(key.name); + + switch (key.type) { + case Type.B: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_boolean(key.name); + }, + set(v) { + component_settings.set_boolean(key.name, v); + } + }); + break; + + case Type.I: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_int(key.name); + }, + set(v) { + component_settings.set_int(key.name, v); + } + }); + break; + + case Type.D: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_double(key.name); + }, + set(v) { + component_settings.set_double(key.name, v); + } + }); + break; + + case Type.S: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_string(key.name); + }, + set(v) { + component_settings.set_string(key.name, v); + } + }); + break; + + case Type.C: + Object.defineProperty(component, property_name, { + // returns the array [red, blue, green, alpha] with + // values between 0 and 1 + get() { + let val = component_settings.get_value(key.name); + return val.deep_unpack(); + }, + // takes an array [red, blue, green, alpha] with + // values between 0 and 1 + set(v) { + let val = new GLib.Variant("(dddd)", v); + component_settings.set_value(key.name, val); + } + }); + break; + + case Type.AS: + Object.defineProperty(component, property_name, { + get() { + let val = component_settings.get_value(key.name); + return val.deep_unpack(); + }, + set(v) { + let val = new GLib.Variant("as", v); + component_settings.set_value(key.name, val); + } + }); + break; + } + + component[property_name + '_reset'] = function () { + return component_settings.reset(key.name); + }; + + component[property_name + '_changed'] = function (cb) { + return component_settings.connect('changed::' + key.name, cb); + }; + + component[property_name + '_disconnect'] = function () { + return component_settings.disconnect.apply( + component_settings, arguments + ); + }; + }); + }); + }; + + /// Reset the preferences. + reset() { + this.keys.forEach(bundle => { + let component = this; + if (bundle.component !== "general") { + let bundle_component = bundle.component.replaceAll('-', '_'); + component = this[bundle_component]; + } + + bundle.schemas.forEach(key => { + let property_name = this.get_property_name(key.name); + component[property_name + '_reset'](); + }); + }); + + this.emit('reset', true); + } + + /// From the gschema name, returns the name of the associated property on + /// the Prefs object. + get_property_name(name) { + return name.replaceAll('-', '_').toUpperCase(); + } + + /// Remove all connections managed by the Prefs object, i.e. created with + /// `prefs.PROPERTY_changed(callback)`. + disconnect_all_settings() { + this.keys.forEach(bundle => { + let component = this; + if (bundle.component !== "general") { + let bundle_component = bundle.component.replaceAll('-', '_'); + component = this[bundle_component]; + } + + bundle.schemas.forEach(key => { + let property_name = this.get_property_name(key.name); + component[property_name + '_disconnect'](); + }); + }); + } +}; + +Signals.addSignalMethods(Prefs.prototype); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/client.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/client.js new file mode 100644 index 0000000..1aae9bb --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/client.js @@ -0,0 +1,60 @@ +'use strict'; + +const Gio = imports.gi.Gio; + +const bus_name = 'org.gnome.Shell'; +const iface_name = 'dev.aunetx.BlurMyShell'; +const obj_path = '/dev/aunetx/BlurMyShell'; + + +/// Call pick() from the DBus service, it will open the Inspector from +/// gnome-shell to pick an actor on stage. +function pick() { + Gio.DBus.session.call( + bus_name, + obj_path, + iface_name, + 'pick', + null, + null, + Gio.DBusCallFlags.NO_AUTO_START, + -1, + null, + null + ); +} + +/// Connect to DBus 'picking' signal, which will be emitted when the inspector +/// is picking a window. +function on_picking(cb) { + const id = Gio.DBus.session.signal_subscribe( + bus_name, + iface_name, + 'picking', + obj_path, + null, + Gio.DBusSignalFlags.NONE, + _ => { + cb(); + Gio.DBus.session.signal_unsubscribe(id); + } + ); +} + +/// Connect to DBus 'picked' signal, which will be emitted when a window is +/// picked. +function on_picked(cb) { + const id = Gio.DBus.session.signal_subscribe( + bus_name, + iface_name, + 'picked', + obj_path, + null, + Gio.DBusSignalFlags.NONE, + (conn, sender, obj_path, iface, signal, params) => { + const val = params.get_child_value(0); + cb(val.get_string()[0]); + Gio.DBus.session.signal_unsubscribe(id); + } + ); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/iface.xml b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/iface.xml new file mode 100644 index 0000000..4f298ad --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/iface.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/services.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/services.js new file mode 100644 index 0000000..bfd7e3b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/dbus/services.js @@ -0,0 +1,93 @@ +'use strict'; + +const { Gio, GLib } = imports.gi; +const Main = imports.ui.main; +const LookingGlass = imports.ui.lookingGlass; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); + +const load_file = path => { + const [, buffer] = GLib.file_get_contents(path); + const contents = imports.byteArray.toString(buffer); + GLib.free(buffer); + return contents; +}; + +const iface = load_file(Me.dir.get_path() + '/dbus/iface.xml'); + +var ApplicationsService = class ApplicationsService { + constructor() { + this.DBusImpl = Gio.DBusExportedObject.wrapJSObject(iface, this); + } + + /// Pick Window for Preferences Page, exported to DBus client. + pick() { + // emit `picking` signal to know we are listening + const send_picking_signal = _ => + this.DBusImpl.emit_signal( + 'picking', + null + ); + + // emit `picked` signal to send wm_class + const send_picked_signal = wm_class => + this.DBusImpl.emit_signal( + 'picked', + new GLib.Variant('(s)', [wm_class]) + ); + + // notify the preferences that we are listening + send_picking_signal(); + + // A very interesting way to pick a window: + // 1. Open LookingGlass to mask all event handles of window + // 2. Use inspector to pick window, thats is also lookingGlass do + // 3. Close LookingGlass when done + // It will restore event handles of window + + // open then hide LookingGlass + const looking_class = Main.createLookingGlass(); + looking_class.open(); + looking_class.hide(); + + // inspect window now + const inspector = new LookingGlass.Inspector(Main.createLookingGlass()); + inspector.connect('target', (me, target, x, y) => { + // remove border effect when window is picked. + const effect_name = 'lookingGlass_RedBorderEffect'; + target + .get_effects() + .filter(e => e.toString().includes(effect_name)) + .forEach(e => target.remove_effect(e)); + + // get wm_class_instance property of window, then pass it to DBus + // client + const type_str = target.toString(); + + let actor = target; + if (type_str.includes('MetaSurfaceActor')) + actor = target.get_parent(); + + if (!actor.toString().includes('WindowActor')) + return send_picked_signal('window-not-found'); + + send_picked_signal( + actor.meta_window.get_wm_class() ?? 'window-not-found' + ); + }); + + // close LookingGlass when we're done + inspector.connect('closed', _ => looking_class.close()); + } + + export() { + this.DBusImpl.export( + Gio.DBus.session, + '/dev/aunetx/BlurMyShell' + ); + } + + unexport() { + this.DBusImpl.unexport(); + } +}; diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.glsl b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.glsl new file mode 100644 index 0000000..142b89b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.glsl @@ -0,0 +1,13 @@ +uniform sampler2D tex; +uniform float red; +uniform float green; +uniform float blue; +uniform float blend; + +void main() { + vec4 c = texture2D(tex, cogl_tex_coord_in[0].st); + vec3 pix_color = c.xyz; + vec3 color = vec3(red, green, blue); + + cogl_color_out = vec4(mix(pix_color, color, blend), 1.); +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.js new file mode 100644 index 0000000..a550f90 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/color_effect.js @@ -0,0 +1,186 @@ +'use strict'; + +const { GLib, GObject, Gio, Clutter, Shell } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const { Prefs } = Me.imports.conveniences.settings; +const { Keys } = Me.imports.conveniences.keys; + + +const SHADER_PATH = GLib.build_filenamev( + [Me.path, 'effects', 'color_effect.glsl'] +); + +const get_shader_source = _ => { + try { + return Shell.get_file_contents_utf8_sync(SHADER_PATH); + } catch (e) { + log(`[Blur my Shell] error loading shader from ${SHADER_PATH}: ${e}`); + return null; + } +}; + +/// New Clutter Shader Effect that simply mixes a color in, the class applies +/// the GLSL shader programmed into vfunc_get_static_shader_source and applies +/// it to an Actor. +/// +/// Clutter Shader Source Code: +/// https://github.com/GNOME/clutter/blob/master/clutter/clutter-shader-effect.c +/// +/// GJS Doc: +/// https://gjs-docs.gnome.org/clutter10~10_api/clutter.shadereffect +var ColorEffect = new GObject.registerClass({ + GTypeName: "ColorEffect", + Properties: { + 'red': GObject.ParamSpec.double( + `red`, + `Red`, + `Red value in shader`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.4, + ), + 'green': GObject.ParamSpec.double( + `green`, + `Green`, + `Green value in shader`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.4, + ), + 'blue': GObject.ParamSpec.double( + `blue`, + `Blue`, + `Blue value in shader`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.4, + ), + 'blend': GObject.ParamSpec.double( + `blend`, + `Blend`, + `Amount of blending between the colors`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.4, + ), + } +}, class ColorShader extends Clutter.ShaderEffect { + _init(params) { + this._red = null; + this._green = null; + this._blue = null; + this._blend = null; + + this._static = true; + this._prefs = new Prefs(Keys); + + // initialize without color as a parameter + + let _color = params.color; + delete params.color; + + super._init(params); + + // set shader source + + this._source = get_shader_source(); + + if (this._source) + this.set_shader_source(this._source); + + // set shader color + + if (_color) + this.color = _color; + + this.update_enabled(); + } + + get red() { + return this._red; + } + + set red(value) { + if (this._red !== value) { + this._red = value; + + this.set_uniform_value('red', parseFloat(this._red - 1e-6)); + } + } + + get green() { + return this._green; + } + + set green(value) { + if (this._green !== value) { + this._green = value; + + this.set_uniform_value('green', parseFloat(this._green - 1e-6)); + } + } + + get blue() { + return this._blue; + } + + set blue(value) { + if (this._blue !== value) { + this._blue = value; + + this.set_uniform_value('blue', parseFloat(this._blue - 1e-6)); + } + } + + get blend() { + return this._blend; + } + + set blend(value) { + if (this._blend !== value) { + this._blend = value; + + this.set_uniform_value('blend', parseFloat(this._blend - 1e-6)); + } + this.update_enabled(); + } + + set color(rgba) { + let [r, g, b, a] = rgba; + this.red = r; + this.green = g; + this.blue = b; + this.blend = a; + } + + get color() { + return [this.red, this.green, this.blue, this.blend]; + } + + /// False set function, only cares about the color. Too hard to change. + set(params) { + this.color = params.color; + } + + update_enabled() { + this.set_enabled( + this.blend > 0 && + this._prefs.COLOR_AND_NOISE && + this._static + ); + } + + + vfunc_paint_target(paint_node = null, paint_context = null) { + this.set_uniform_value("tex", 0); + + if (paint_node && paint_context) + super.vfunc_paint_target(paint_node, paint_context); + else if (paint_node) + super.vfunc_paint_target(paint_node); + else + super.vfunc_paint_target(); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.glsl b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.glsl new file mode 100644 index 0000000..9140f33 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.glsl @@ -0,0 +1,18 @@ +uniform sampler2D tex; +uniform float noise; +uniform float lightness; + +float PHI = 1.61803398874989484820459; +float SEED = 24; + +float noise_gen(in vec2 xy) { + return fract(tan(distance(xy * PHI, xy) * SEED) * xy.x); +} + +void main() { + vec4 c = texture2D(tex, cogl_tex_coord_in[0].st); + vec3 pix_color = c.xyz; + float blend = noise * (1. - noise_gen(gl_FragCoord.xy)); + + cogl_color_out = vec4(mix(pix_color, lightness * pix_color, blend), 1.); +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.js new file mode 100644 index 0000000..f795364 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/noise_effect.js @@ -0,0 +1,106 @@ +'use strict'; + +const { GLib, GObject, Gio, Clutter, Shell } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const { Prefs } = Me.imports.conveniences.settings; +const { Keys } = Me.imports.conveniences.keys; + + +const SHADER_PATH = GLib.build_filenamev( + [Me.path, 'effects', 'noise_effect.glsl'] +); + +const get_shader_source = _ => { + try { + return Shell.get_file_contents_utf8_sync(SHADER_PATH); + } catch (e) { + log(`[Blur my Shell] error loading shader from ${SHADER_PATH}: ${e}`); + return null; + } +}; + +var NoiseEffect = new GObject.registerClass({ + GTypeName: "NoiseEffect", + Properties: { + 'noise': GObject.ParamSpec.double( + `noise`, + `Noise`, + `Amount of noise integrated with the image`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.4, + ), + 'lightness': GObject.ParamSpec.double( + `lightness`, + `Lightness`, + `Lightness of the grey used for the noise`, + GObject.ParamFlags.READWRITE, + 0.0, 2.0, + 0.4, + ), + } +}, class NoiseShader extends Clutter.ShaderEffect { + _init(params) { + this._noise = null; + this._lightness = null; + + this._static = true; + this._prefs = new Prefs(Keys); + + super._init(params); + + // set shader source + this._source = get_shader_source(); + if (this._source) + this.set_shader_source(this._source); + + this.update_enabled(); + } + + get noise() { + return this._noise; + } + + set noise(value) { + if (this._noise !== value) { + this._noise = value; + + this.set_uniform_value('noise', parseFloat(this._noise - 1e-6)); + } + this.update_enabled(); + } + + get lightness() { + return this._lightness; + } + + set lightness(value) { + if (this._lightness !== value) { + this._lightness = value; + + this.set_uniform_value('lightness', parseFloat(this._lightness - 1e-6)); + } + } + + update_enabled() { + this.set_enabled( + this.noise > 0 && + this._prefs.COLOR_AND_NOISE && + this._static + ); + } + + + vfunc_paint_target(paint_node = null, paint_context = null) { + this.set_uniform_value("tex", 0); + + if (paint_node && paint_context) + super.vfunc_paint_target(paint_node, paint_context); + else if (paint_node) + super.vfunc_paint_target(paint_node); + else + super.vfunc_paint_target(); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/paint_signals.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/paint_signals.js new file mode 100644 index 0000000..8c836fd --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/effects/paint_signals.js @@ -0,0 +1,90 @@ +'use strict'; + +const { GObject, Clutter } = imports.gi; + + +var PaintSignals = class PaintSignals { + constructor(connections) { + this.buffer = []; + this.connections = connections; + } + + connect(actor, blur_effect) { + let paint_effect = new EmitPaintSignal(); + let infos = { + actor: actor, + paint_effect: paint_effect + }; + let counter = 0; + + actor.add_effect(paint_effect); + this.connections.connect(paint_effect, 'update-blur', () => { + try { + // checking if blur_effect.queue_repaint() has been recently called + if (counter === 0) { + counter = 2; + blur_effect.queue_repaint(); + } + else counter--; + } catch (e) { } + }); + + // remove the actor from buffer when it is destroyed + if ( + actor.connect && + ( + !(actor instanceof GObject.Object) || + GObject.signal_lookup('destroy', actor) + ) + ) + this.connections.connect(actor, 'destroy', () => { + this.buffer.forEach(infos => { + if (infos.actor === actor) { + // remove from buffer + let index = this.buffer.indexOf(infos); + this.buffer.splice(index, 1); + } + }); + }); + + this.buffer.push(infos); + } + + disconnect_all_for_actor(actor) { + this.buffer.forEach(infos => { + if (infos.actor === actor) { + this.connections.disconnect_all_for(infos.paint_effect); + infos.actor.remove_effect(infos.paint_effect); + + // remove from buffer + let index = this.buffer.indexOf(infos); + this.buffer.splice(index, 1); + } + }); + } + + disconnect_all() { + this.buffer.forEach(infos => { + this.connections.disconnect_all_for(infos.paint_effect); + infos.actor.remove_effect(infos.paint_effect); + }); + + this.buffer = []; + } +}; + +var EmitPaintSignal = GObject.registerClass({ + GTypeName: 'EmitPaintSignal', + Signals: { + 'update-blur': { + param_types: [] + }, + } +}, + class EmitPaintSignal extends Clutter.Effect { + vfunc_paint(node, paint_context, paint_flags) { + this.emit("update-blur"); + super.vfunc_paint(node, paint_context, paint_flags); + } + } +); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/extension.js new file mode 100644 index 0000000..d8de89e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/extension.js @@ -0,0 +1,642 @@ +'use strict'; + +const { St, Shell, Gio, Gtk, Meta, Clutter } = imports.gi; +const Main = imports.ui.main; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); + +const { Connections } = Me.imports.conveniences.connections; +const { Prefs } = Me.imports.conveniences.settings; +const { Keys } = Me.imports.conveniences.keys; + +const Panel = Me.imports.components.panel; +const Overview = Me.imports.components.overview; +const DashToDock = Me.imports.components.dash_to_dock; +const Lockscreen = Me.imports.components.lockscreen; +const AppFolders = Me.imports.components.appfolders; +const WindowList = Me.imports.components.window_list; +const Applications = Me.imports.components.applications; +const Screenshot = Me.imports.components.screenshot; + +// This lists the components that need to be connected in order to either use +// general sigma/brightness or their own. +const INDEPENDENT_COMPONENTS = [ + "overview", "appfolder", "panel", "dash_to_dock", "applications", + "lockscreen", "window_list", "screenshot" +]; + + +/// The main extension class, created when the GNOME Shell is loaded. +class Extension { + constructor() { } + + /// Enables the extension + enable() { + // add the extension to global to make it accessible to other extensions + // create it first as it is very useful when debugging crashes + + global.blur_my_shell = this; + + // create a Prefs instance, to manage extension's preferences + // it needs to be loaded before logging, as it checks for DEBUG + + this._prefs = new Prefs(Keys); + + this._log("enabling extension..."); + + // create main extension Connections instance + + this._connection = new Connections; + + // store it in a global array + + this._connections = [this._connection]; + + // create an instance of each component, with its associated Connections + + let init = _ => { + // create a Connections instance, to manage signals + let connection = new Connections; + + // store it to keeps track of them globally + this._connections.push(connection); + + return [connection, this._prefs]; + }; + + this._panel_blur = new Panel.PanelBlur(...init()); + this._dash_to_dock_blur = new DashToDock.DashBlur(...init()); + this._overview_blur = new Overview.OverviewBlur(...init()); + this._lockscreen_blur = new Lockscreen.LockscreenBlur(...init()); + this._appfolder_blur = new AppFolders.AppFoldersBlur(...init()); + this._window_list_blur = new WindowList.WindowListBlur(...init()); + this._applications_blur = new Applications.ApplicationsBlur(...init()); + this._screenshot_blur = new Screenshot.ScreenshotBlur(...init()); + + // maybe disable clipped redraw + + this._update_clipped_redraws(); + + // connect each component to preferences change + + this._connect_to_settings(); + + // enable every component + // if the shell is still starting up, wait for it to be entirely loaded; + // this should prevent bugs like #136 and #137 + if (Main.layoutManager._startingUp) { + this._connection.connect( + Main.layoutManager, + 'startup-complete', + this._enable_components.bind(this) + ); + } else { + this._enable_components(); + } + + // try to enable the components as soon as possible anyway, this way the + // overview may load before the user sees it + try { + if (this._prefs.overview.BLUR && !this._overview_blur.enabled) + this._overview_blur.enable(); + } catch (e) { } + try { + if (this._prefs.dash_to_dock.BLUR + && !this._dash_to_dock_blur.enabled) + this._dash_to_dock_blur.enable(); + } catch (e) { } + try { + if (this._prefs.panel.BLUR && !this._panel_blur.enabled) + this._panel_blur.enable(); + } catch (e) { } + } + + /// Disables the extension + disable() { + this._log("disabling extension..."); + + // disable every component + + this._panel_blur.disable(); + this._dash_to_dock_blur.disable(); + this._overview_blur.disable(); + this._lockscreen_blur.disable(); + this._appfolder_blur.disable(); + this._window_list_blur.disable(); + this._applications_blur.disable(); + this._screenshot_blur.disable(); + + // untrack them + + this._panel_blur = null; + this._dash_to_dock_blur = null; + this._overview_blur = null; + this._lockscreen_blur = null; + this._appfolder_blur = null; + this._window_list_blur = null; + this._applications_blur = null; + + // make sure no settings change can re-enable them + + this._prefs.disconnect_all_settings(); + + // force disconnecting every signal, even if component crashed + + this._connections.forEach((connections) => { + connections.disconnect_all(); + }); + this._connections = []; + + // remove the clipped redraws flag + + this._reenable_clipped_redraws(); + + // remove the extension from GJS's global + + delete global.blur_my_shell; + + this._log("extension disabled."); + + this._prefs = null; + } + + /// Restart the extension. + _restart() { + this._log("restarting..."); + + this.disable(); + this.enable(); + + this._log("restarted."); + } + + /// Add or remove the clutter debug flag to disable clipped redraws. + /// This will entirely fix the blur effect, but should not be used except if + /// the user really needs it, as clipped redraws are a huge performance + /// boost for the compositor. + _update_clipped_redraws() { + if (this._prefs.HACKS_LEVEL === 3) + this._disable_clipped_redraws(); + else + this._reenable_clipped_redraws(); + } + + /// Add the Clutter debug flag. + _disable_clipped_redraws() { + Meta.add_clutter_debug_flags( + null, Clutter.DrawDebugFlag.DISABLE_CLIPPED_REDRAWS, null + ); + } + + /// Remove the Clutter debug flag. + _reenable_clipped_redraws() { + Meta.remove_clutter_debug_flags( + null, Clutter.DrawDebugFlag.DISABLE_CLIPPED_REDRAWS, null + ); + } + + /// Enables every component needed, should be called when the shell is + /// entirely loaded as the `enable` methods interact with it. + _enable_components() { + // enable each component if needed, and if it is not already enabled + + if (this._prefs.panel.BLUR && !this._panel_blur.enabled) + this._panel_blur.enable(); + + if (this._prefs.dash_to_dock.BLUR && !this._dash_to_dock_blur.enabled) + this._dash_to_dock_blur.enable(); + + if (this._prefs.overview.BLUR && !this._overview_blur.enabled) + this._overview_blur.enable(); + + if (this._prefs.lockscreen.BLUR) + this._lockscreen_blur.enable(); + + if (this._prefs.appfolder.BLUR) + this._appfolder_blur.enable(); + + if (this._prefs.applications.BLUR) + this._applications_blur.enable(); + + if (this._prefs.window_list.BLUR) + this._window_list_blur.enable(); + + if (this._prefs.screenshot.BLUR) + this._screenshot_blur.enable(); + + this._log("all components enabled."); + } + + /// Updates needed things in each component when a preference changed + _connect_to_settings() { + + // global blur values changed, update everybody + + this._prefs.SIGMA_changed(() => { + this._update_sigma(); + }); + this._prefs.BRIGHTNESS_changed(() => { + this._update_brightness(); + }); + this._prefs.COLOR_changed(() => { + this._update_color(); + }); + this._prefs.NOISE_AMOUNT_changed(() => { + this._update_noise_amount(); + }); + this._prefs.NOISE_LIGHTNESS_changed(() => { + this._update_noise_lightness(); + }); + this._prefs.COLOR_AND_NOISE_changed(() => { + // both updating noise amount and color calls `update_enabled` on + // each color and noise effects + this._update_noise_amount(); + this._update_color(); + }); + + // restart the extension when hacks level is changed, easier than + // restarting individual components and should not happen often either + this._prefs.HACKS_LEVEL_changed(_ => this._restart()); + + // connect each component to use the proper sigma/brightness/color + + INDEPENDENT_COMPONENTS.forEach(component => { + this._connect_to_individual_settings(component); + }); + + // other component's preferences changed + + // ---------- OVERVIEW ---------- + + // toggled on/off + this._prefs.overview.BLUR_changed(() => { + if (this._prefs.overview.BLUR) { + this._overview_blur.enable(); + } else { + this._overview_blur.disable(); + } + }); + + // overview components style changed + this._prefs.overview.STYLE_COMPONENTS_changed(() => { + if (this._prefs.overview.BLUR) { + this._overview_blur.update_components_classname(); + } + }); + + + // ---------- APPFOLDER ---------- + + // toggled on/off + this._prefs.appfolder.BLUR_changed(() => { + if (this._prefs.appfolder.BLUR) { + this._appfolder_blur.enable(); + } else { + this._appfolder_blur.disable(); + } + }); + + // appfolder dialogs style changed + this._prefs.appfolder.STYLE_DIALOGS_changed(() => { + if (this._prefs.appfolder.BLUR) + this._appfolder_blur.blur_appfolders(); + }); + + + // ---------- PANEL ---------- + + // toggled on/off + this._prefs.panel.BLUR_changed(() => { + if (this._prefs.panel.BLUR) { + this._panel_blur.enable(); + } else { + this._panel_blur.disable(); + } + }); + + this._prefs.COLOR_AND_NOISE_changed(() => { + // permits making sure that the blur is not washed out when disabling + // the other effects + if (this._prefs.panel.BLUR) + this._panel_blur.invalidate_all_blur(); + }); + + // static blur toggled on/off + this._prefs.panel.STATIC_BLUR_changed(() => { + if (this._prefs.panel.BLUR) + this._panel_blur.update_all_blur_type(); + }); + + // panel blur's overview connection toggled on/off + this._prefs.panel.UNBLUR_IN_OVERVIEW_changed(() => { + this._panel_blur.connect_to_windows_and_overview(); + }); + + // panel override background toggled on/off + this._prefs.panel.OVERRIDE_BACKGROUND_changed(() => { + if (this._prefs.panel.BLUR) + this._panel_blur.connect_to_windows_and_overview(); + }); + + // panel style changed + this._prefs.panel.STYLE_PANEL_changed(() => { + if (this._prefs.panel.BLUR) + this._panel_blur.connect_to_windows_and_overview(); + }); + + // panel background's dynamic overriding toggled on/off + this._prefs.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_changed(() => { + if (this._prefs.panel.BLUR) + this._panel_blur.connect_to_windows_and_overview(); + }); + + + // ---------- DASH TO DOCK ---------- + + // toggled on/off + this._prefs.dash_to_dock.BLUR_changed(() => { + if (this._prefs.dash_to_dock.BLUR) { + this._dash_to_dock_blur.enable(); + } else { + this._dash_to_dock_blur.disable(); + } + }); + + // TODO implement static blur for dash + // static blur toggled on/off + this._prefs.dash_to_dock.STATIC_BLUR_changed(() => { + //if (this._prefs.dash_to_dock.BLUR) + // this._dash_to_dock_blur.change_blur_type(); + }); + + // dash-to-dock override background toggled on/off + this._prefs.dash_to_dock.OVERRIDE_BACKGROUND_changed(() => { + if (this._prefs.dash_to_dock.BLUR) + this._dash_to_dock_blur.update_background(); + }); + + // dash-to-dock style changed + this._prefs.dash_to_dock.STYLE_DASH_TO_DOCK_changed(() => { + if (this._prefs.dash_to_dock.BLUR) + this._dash_to_dock_blur.update_background(); + }); + + // dash-to-dock blur's overview connection toggled on/off + this._prefs.dash_to_dock.UNBLUR_IN_OVERVIEW_changed(() => { + if (this._prefs.dash_to_dock.BLUR) + this._dash_to_dock_blur.connect_to_overview(); + }); + + + // ---------- APPLICATIONS ---------- + + // toggled on/off + this._prefs.applications.BLUR_changed(() => { + if (this._prefs.applications.BLUR) { + this._applications_blur.enable(); + } else { + this._applications_blur.disable(); + } + }); + + // application opacity changed + this._prefs.applications.OPACITY_changed(_ => { + if (this._prefs.applications.BLUR) + this._applications_blur.set_opacity( + this._prefs.applications.OPACITY + ); + }); + + // application blur-on-overview changed + this._prefs.applications.BLUR_ON_OVERVIEW_changed(_ => { + if (this._prefs.applications.BLUR) + this._applications_blur.connect_to_overview(); + }); + + // application enable-all changed + this._prefs.applications.ENABLE_ALL_changed(_ => { + if (this._prefs.applications.BLUR) + this._applications_blur.update_all_windows(); + }); + + // application whitelist changed + this._prefs.applications.WHITELIST_changed(_ => { + if ( + this._prefs.applications.BLUR + && !this._prefs.applications.ENABLE_ALL + ) + this._applications_blur.update_all_windows(); + }); + + // application blacklist changed + this._prefs.applications.BLACKLIST_changed(_ => { + if ( + this._prefs.applications.BLUR + && this._prefs.applications.ENABLE_ALL + ) + this._applications_blur.update_all_windows(); + }); + + + // ---------- LOCKSCREEN ---------- + + // toggled on/off + this._prefs.lockscreen.BLUR_changed(() => { + if (this._prefs.lockscreen.BLUR) { + this._lockscreen_blur.enable(); + } else { + this._lockscreen_blur.disable(); + } + }); + + + // ---------- WINDOW LIST ---------- + + // toggled on/off + this._prefs.window_list.BLUR_changed(() => { + if (this._prefs.window_list.BLUR) { + this._window_list_blur.enable(); + } else { + this._window_list_blur.disable(); + } + }); + + + // ---------- HIDETOPBAR ---------- + + // toggled on/off + this._prefs.hidetopbar.COMPATIBILITY_changed(() => { + // no need to verify if it is enabled or not, it is done anyway + this._panel_blur.connect_to_windows_and_overview(); + }); + + + // ---------- SCREENSHOT ---------- + + // toggled on/off + this._prefs.screenshot.BLUR_changed(() => { + if (this._prefs.screenshot.BLUR) { + this._screenshot_blur.enable(); + } else { + this._screenshot_blur.disable(); + } + }); + } + + /// Select the component by its name and connect it to its preferences + /// changes for general values, sigma and brightness. + /// + /// Doing this in such a way is less accessible but prevents a lot of + /// boilerplate and headaches. + _connect_to_individual_settings(name) { + // get component and preferences needed + let component = this['_' + name + '_blur']; + let component_prefs = this._prefs[name]; + + // general values switch is toggled + component_prefs.CUSTOMIZE_changed(() => { + if (component_prefs.CUSTOMIZE) { + component.set_sigma(component_prefs.SIGMA); + component.set_brightness(component_prefs.BRIGHTNESS); + component.set_color(component_prefs.COLOR); + component.set_noise_amount(component_prefs.NOISE_AMOUNT); + component.set_noise_lightness(component_prefs.NOISE_LIGHTNESS); + } + else { + component.set_sigma(this._prefs.SIGMA); + component.set_brightness(this._prefs.BRIGHTNESS); + component.set_color(this._prefs.COLOR); + component.set_noise_amount(this._prefs.NOISE_AMOUNT); + component.set_noise_lightness(this._prefs.NOISE_LIGHTNESS); + } + }); + + // sigma is changed + component_prefs.SIGMA_changed(() => { + if (component_prefs.CUSTOMIZE) + component.set_sigma(component_prefs.SIGMA); + else + component.set_sigma(this._prefs.SIGMA); + }); + + // brightness is changed + component_prefs.BRIGHTNESS_changed(() => { + if (component_prefs.CUSTOMIZE) + component.set_brightness(component_prefs.BRIGHTNESS); + else + component.set_brightness(this._prefs.BRIGHTNESS); + }); + + // color is changed + component_prefs.COLOR_changed(() => { + if (component_prefs.CUSTOMIZE) + component.set_color(component_prefs.COLOR); + else + component.set_color(this._prefs.COLOR); + }); + + // noise amount is changed + component_prefs.NOISE_AMOUNT_changed(() => { + if (component_prefs.CUSTOMIZE) + component.set_noise_amount(component_prefs.NOISE_AMOUNT); + else + component.set_noise_amount(this._prefs.NOISE_AMOUNT); + }); + + // noise lightness is changed + component_prefs.NOISE_LIGHTNESS_changed(() => { + if (component_prefs.CUSTOMIZE) + component.set_noise_lightness(component_prefs.NOISE_LIGHTNESS); + else + component.set_noise_lightness(this._prefs.NOISE_LIGHTNESS); + }); + } + + /// Update each component's sigma value + _update_sigma() { + INDEPENDENT_COMPONENTS.forEach(name => { + // get component and preferences needed + let component = this['_' + name + '_blur']; + let component_prefs = this._prefs[name]; + + // update sigma accordingly + if (component_prefs.CUSTOMIZE) { + component.set_sigma(component_prefs.SIGMA); + } + else { + component.set_sigma(this._prefs.SIGMA); + } + }); + } + + /// Update each component's brightness value + _update_brightness() { + INDEPENDENT_COMPONENTS.forEach(name => { + // get component and preferences needed + let component = this['_' + name + '_blur']; + let component_prefs = this._prefs[name]; + + // update brightness accordingly + if (component_prefs.CUSTOMIZE) + component.set_brightness(component_prefs.BRIGHTNESS); + else + component.set_brightness(this._prefs.BRIGHTNESS); + }); + } + + /// Update each component's color value + _update_color() { + INDEPENDENT_COMPONENTS.forEach(name => { + // get component and preferences needed + let component = this['_' + name + '_blur']; + let component_prefs = this._prefs[name]; + + // update color accordingly + if (component_prefs.CUSTOMIZE) + component.set_color(component_prefs.COLOR); + else + component.set_color(this._prefs.COLOR); + }); + } + + /// Update each component's noise amount value + _update_noise_amount() { + INDEPENDENT_COMPONENTS.forEach(name => { + // get component and preferences needed + let component = this['_' + name + '_blur']; + let component_prefs = this._prefs[name]; + + // update color accordingly + if (component_prefs.CUSTOMIZE) + component.set_noise_amount(component_prefs.NOISE_AMOUNT); + else + component.set_noise_amount(this._prefs.NOISE_AMOUNT); + }); + } + + /// Update each component's noise lightness value + _update_noise_lightness() { + INDEPENDENT_COMPONENTS.forEach(name => { + // get component and preferences needed + let component = this['_' + name + '_blur']; + let component_prefs = this._prefs[name]; + + // update color accordingly + if (component_prefs.CUSTOMIZE) + component.set_noise_lightness(component_prefs.NOISE_LIGHTNESS); + else + component.set_noise_lightness(this._prefs.NOISE_LIGHTNESS); + }); + } + + _log(str) { + if (this._prefs.DEBUG) + log(`[Blur my Shell > extension] ${str}`); + } +} + + +// Called on gnome-shell loading, even if extension is deactivated +function init() { + return new Extension(); +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-window-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-window-symbolic.svg new file mode 100644 index 0000000..bdab309 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-window-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg new file mode 100644 index 0000000..87f307f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg new file mode 100644 index 0000000..2eda98b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg @@ -0,0 +1,44 @@ + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg new file mode 100644 index 0000000..5a78b46 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg @@ -0,0 +1,44 @@ + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/general-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/general-symbolic.svg new file mode 100644 index 0000000..e11da07 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/general-symbolic.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-filled-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-filled-symbolic.svg new file mode 100644 index 0000000..8378c9c --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-filled-symbolic.svg @@ -0,0 +1,40 @@ + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg new file mode 100644 index 0000000..45e703e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg new file mode 100644 index 0000000..445f662 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-window-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-window-symbolic.svg new file mode 100644 index 0000000..a8da14f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-window-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg new file mode 100644 index 0000000..e443de4 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-mode-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-mode-symbolic.svg new file mode 100644 index 0000000..cad2da8 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-mode-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg new file mode 100644 index 0000000..cad2da8 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..b20cc9ab6f672ac62cb64bfa6fe2d6bab07bd78e GIT binary patch literal 5625 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 e9n7W*ySVyB?402T{C^A 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 QD)-H0pCeoSz=rDo0a9%EUjP6A literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..00b61a7594ea69a9ce4aa55dee61569c6c15d1cb GIT binary patch literal 8265 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 O&bO)(SpK-SS^XFMru()4 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..0e10fb092b2e98cf0f5898cfe898348a9aeeaaea GIT binary patch literal 7998 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/hu/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/hu/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..76cf64a722ec23dcf12a1f07f095607b5f8e5b4e GIT binary patch literal 1013 zcmZvaOK%e~5XToNuLUlg5aKXMNPws}4=NOG8`K94RHCA414Rf9-t1&|8?PPN-q7S* zaNx$J#~}5}7g!;cFTjyIC+?gWC#9u;rJw#Y_RQEb^0%uq?>$-ds%0y8M{*4e1Uk zkRFh_`@fS?>SUciR2NU%leeBb+&fJ=kWvb-}tFmxA3ccI+&0NGS;hToeeo%ZHrza1v;7*Fws5j2f&0jXVw} zH8W{Zn#>OWEE#y)X=YJm#(EoC?NE8P7PA+q4Lv)YT+8wyGbswO$P0;f*Wbjx(w428 zB#YT{kr>uiA^025*d`7#m&hJ*iy_pj^*XCQVD&kuHNslsUX_;rlpD+1noA?NRXT)a zlpTb2p)**BoNdXhFD5z9M9@+BLrRfJ!4qU{9JGfvirE?R4>`z?Ntk1*LY)ZJoR7*qqk1PjK#{7v+!I4(%6&@_{P$ODm18+X z{rR1@H7fU|w>0`U7`oFS+`(DEWJn(?;RedFw&l175>p&u6qRF|Ly9(|zi39~rvWC| f10@FB(2eDu4gO!<-EK@dPB8FVm{M8y^|<#7KF>K& literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/it/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/it/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..21b14fe9a870aee1ac88bc85bc524c3045ab6fb0 GIT binary patch literal 8009 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 O^ROk(AYRi~oBspGoN$5w literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ko/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ko/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..6d7fc9f318749063b8ca1a9258f91f92318e4869 GIT binary patch literal 4504 zcmZ`)TW}j!89s#qL6jECrG#4#Es$nv$(NQPI0-a~leRjL>#%b(Y4w7+ZoLezPO`OCX9A@B!8D`*#;gJVsctB@0@CJ{3|2eCRov@?T zr@fs2eE;`<|F6G2{_q^bu?^=JaSlJk*f)UFAHWxmpMH?BF9R*$=Yb_)4ES@P0A2+? z0(|6Q#y$t!3j8Q=0Qd>ut_TkS_u%>`Kw7^9%mIH1{19*}zMcR+3H&thn?O8b2Z5gi zeh>I5U<&vhU=jEk;9cMt@K3;x0Ea%z*iPURiW9%v5Ss?Lx7f3q%7Dzh$75F2d0utYskW3MH7)aND01~f118Lnq zf%ve8K5p`P6!h+br5$tU}s$i`b~AA z=nfJL`vpz!cB`bUQbyCU(oh> z;f+WyXSpfCErjp`D``7+FwSk?F9;u8@_ENjS%EEGf5U~@`kAB%tnF;CW2HtZC;TdS zT)JG232)36MROzXi4oxmY~!07L00f2)?_?cz`meDcZMuKOEL_})F>Ax0^$1Dw};y! z+zvpAgLXQ>_Ih?E8@R&v*}kmhW`wU-r=%mXw+W?{G(V= zi#%6IWupy}j?u_=K|_Nn7Mk^b8|lk`+9Z5Tg9RUx^iDL@o{6X&K^`*bNeV+@U0LVho!Lgc)SRn?*GfE` zn+j`X9@g)1_0A1-xt93<3zq1$uvTfmNvlk>`xiCV>gv{7xO6hCuB*#cthuf(nh5hV zZ4Nio*-3SFIS~uX@2ROPT-DEm(qy7zUDIA%pjA`L&8amOR+iPxvbtM0d_h~Q z*G_Mt(zuD7%gbQ6@t>)=Fb8V9Ia>zb#@#iwcpWr&cxolQbVJQl)YL4;+VB!W*X#5P zvNvlp*t>Canuj+l_|=?i3Bpvp1_`5$N%Zja8{z4bv`XD7VSW4Ep7tYD=FVhuaz(u} zq0X0S#|_1&D9y?`Ei`6KuCYaeR0vLy@i8Ye->SW|37M?jrH8Kf?i>N7z zR;w^IT?)@u)vZ-^vAR*BNXyL{hx0RG8A`ujZZ1?2vbiw3ah=w2Q(>@(tBcF1I=rlI ztZvMdQtFP^mDq!Pd0~ckw!V*^HoP(K;)QU2f`^rp;ry>OgYMn}5ol0F{^Z!^g(}Ga zp`q~Q8t+huA)hW!hqZNe2P?0Y!g+Y3GDCH1wS#T|3askY@N}&?hYp&A7ZxYOF6$#g zy}}x6w6TJjT2HKpxoH{fqpo99TgA@+VX7MixC^_94?nw#|c={ zb)|bZGAZ(bSr$sXQD30)sq+h+QLx$dYNpB?w^y{AF3pB#rXybMnzYlNKhu?Vhey;a z;T-yZoptvB+K74$CDVOfTPN+|OO%Fs^x9<9V3Db*rmgX~)Umv7zqcNO#?$+n}+`%;D%Q5^}HwMjXHJtrn%n9RLyM4)Ues~KC&ol8KQrHt~q1) zqQ=C&43m)E)j60r;{3+FuBwsU>zG4tR>&b_dfol40fbR+=87I8aJ!zLo$*3mi83@V T>VGf&QkTLg2%^K`oyq<`ltxAE literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..c58b4c009ee3e89b2948fbbf24fce9803458cbfd GIT binary patch literal 3918 zcmZveO^h5z6~~L<@UeUZLI?yxQV9e*WP5hK1{AMtg4b)uCcF0HUE2r=p_=L1nR0hm z4^=g@*>K|k2!X_fLyi%$gg`>dg+w9;)nS8XS`rln$ z^*;XZ)qC^i{YQSGxH^o789#lGQfI)s_i*F-=X;fU7Q6$V1y3GP>cimo!B2xf2JZu3 z0zU@642rDV-~xCDya3(>EAZUCO7T-KbNdwd3iuK5b?^c34UnbkUm!pAZ*K1g{|9~o zy!U-d@ly|RlX(q_o@1cwKLLt;7boAZfgJc3a1^AS+qPk>(nH$jp2Jos(!2cYo%1}OGChp`WW-vmDj z4#4}tJy5>?1Vpv^If#ksMNss-H2MC!$@kYlvFDGV?Ef<;@%tMn{M`Xb74;ub;(Hf7 z4nDvlOi>rWE$}KRasDMJ`hNv}9Q-XPcKl&7|0huL>U9uN>aU>K^$$?;^&Xs&{f~kY zuP4Aw@FaL0{1JE#d=nIY9w$hTfr}t?H`gQF#pcg5#0KGMkL70d>v(of5OS<7}HC* zm|nsM?lo~Z21;H$&iE`te4SojkcYE*uDj(Z=v3=8u)1q{ML*OdpX++Jnb~tbulIDc zrR}9UXy=>h*bCPBIH;4pcB%6YIrZ3vv9o(~0vGitI^S=Fnz9_4p$&TIdTA6a5{ARl z^-OZLk8gQt?K{@B$vmmnX7-8MYE5h(2D@v6^*tNg3GpP=Lp?O!mUC+7ymOW5qjfE~ z{vdf9qdGS*zRx~kL8MOnFY8{>Ix8HFqO5RH+vgMRW9-p5ufH=96B{|bx`eTbAQ9Tp zJBY7`rsvZB^h3LG_-eZ2%4`Q z7Pen;sjh}F+I1!B)VWbib>&{L7+k}Ba`3foLZQ}echu*;Yer>K>n<9!N~EV@RO_`j z$*O0qx51R^B4N;_9a|n@tlAK&)y9m^CW4!$Xi0Aq zEh}A2Gf7P-g3TAT+no?X2=b1)+&F3~QZ-Fq@PERk@kf*HT5WpCjWL{T_B!A9rXt14 za(^n8_0_QU)~C3rqmXVSa?sACC`s6^u8G;hyNPD8-9>sLl?Cj!-L_ezd*4-<2mCQVYdkzGX8KqwxYa%6QS z#Oi8FWFiiFU_#FEB4>g%@O3TPsC&~4m>l|99>A}UiIr1r_#Zj+q+omACy{Ub>8R@_ zxOxOj!{)q-8f1-y9bxn^=k%US16>P$vzW$?x-oFcN~G0|w!FMc)Tb0?m-6ho4RY32 z^+HQ!wi){_&!97AJ2lf=SF)>i>|{~4PQX|7%JRxew)~ZBWtqp-<10@sb1iI`n6jN< zd@K#sY*n8vOXKzBI^=_cSNHX4A{Eoujc;rwcD}dY@%7i(==&qyvmI-yRoSp-`;M(^ zbx|GMD)s3>O2fFiv@}2f8M_)CS%&ih`S zQ-fFa(_NPqwy?&O*@Ze(5pBcfHJ({HrQ63dUO#q5A3wG5t*i}y!`O}1G5zJv@e^5Y z$9&zYZSGRGW}+qbgH_$>ECn0uQJ^F*jofU>wl$$Q*kVz(%(4Zw^txz!Qb`1Y9*p@=?b}9eYU%@83Cx_WQR-7c za(2`Ok=x#N-PbX3ye40RdTy>r*d$C1O{A%E-eMvD3)Ch#QK+-yviZ}X$Wdw?#j^+_ zA;dMUNn&ihG$(d6DQf9o(ws8y#s|0Nno~9*LS2+&ULcGLL^q;c@_z&V)y9nDcMUKU zv^goY${zB%2r={v*luG%b=wwSE9?8YZJ&jJhEiQnF&s>5Q_z{yh(r}m0Df$KA53&CNxOk ztt%n;ZKrI0`&_G1TvBeWm$c1o)lk(`jYyK*{>?NiZvUQ?tb?2( x&L{u#B%PXEM=L&dNs6~5WphyZONCvdB%Q5{Hgwd*u}e(?%)30RSM#}{{tv^udvyQ+ literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..994eba35f64dadaf2036a67dc17b4cdffc3c1a20 GIT binary patch literal 8008 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 JG_aCj^FM9IWe5NO literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/pl/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/pl/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..2db8df944bfd32f11b3abf5c578124b02355e3c8 GIT binary patch literal 7888 zcmbW5TZ|>gS;q^6&wT zPIuRFU*@=5mOz$F6d@k`ki^y|iWDhPqy+Kchuk&_!aE}50R^N0QUVeZ4b;6pvd(MDE2Yn{ou3U1@J2%|I||N}QZ#(qXU%J_UXjd;okMJO_T5AP~Dh2jU9#4N%tmV^HS* z8TdCpr_?`!qQ{@SBgE6+fuhI1gO7o?p!6B=6JQQr0cE}0FuwTreIQ$^`$5t76e#O$ zf)bx8DDn5Z;77slfinLMP~^T9XUn=hQ1t#G$UpTX{veuq9Yhp$(|dwn-VI6|-T}%! z9{@$KBcQB%8hk(a3GhDfS@0R~^WbUlXQ1fy2th7-{yrFkFN3J2ZbE3;?>*p4-~mwL z;M?Gn;A^1BbqAX>MRh>={v;@NcoLNO7=ohDv!DhipzQlHxCQ<_DE@v7XUOlTK$-tX zpv?OLD0cWuQ1tx?DE56Fl=a^Le+7Iqf8_f+L6PGCDDig`l=b2kYf$v~6exPW1Reyx z1l|Sy5R~=*1C;e{g{&}@x()mt@GkHI_+^l-)xU!GgSQg|5%?(haqthoKKN5m^7=O* zH(B=!pxFCsASP5_2MIq#IQx0>?rz3C3@Fmik^LoCrq`Re5t~deLdaht*D;3pWy579yFB)R?≪nb=wZgAj4tCrhFnJ(sG~kCKe$j`br|ALxgKEL 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/pt/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/pt/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..0d784a19900bfbdaab7d67ff6d35c306c24160b4 GIT binary patch literal 7796 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 VZz)XOwA>3G?n`gYWTp&h{ue|sCs_ah literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..04fa33295b9ffff33f1555b886e18efc7555cfb8 GIT binary patch literal 10050 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 Nh;g^1bktcA{4epNueJaH literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/sv/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/sv/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..258596cb3cba46eb4cf7fd8209fb57faa814ed7f GIT binary patch literal 326 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/tr/LC_MESSAGES/blur-my-shell@aunetx.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/locale/tr/LC_MESSAGES/blur-my-shell@aunetx.mo new file mode 100644 index 0000000000000000000000000000000000000000..bd7437caa5ed7bcd4434a11aa83e399657dd7c56 GIT binary patch literal 6084 zcma)uGg-=>br{VVfI_uZ+NRxkAsJ<;=ne(TB+mUli)J=B6tY=7x)42+G~`0 z4|p4R9e4zk_g26z_;qjr{3ZA(_!1a_SHGPd%)pz#3HUDXJKzoAHYhGUU*U`3d%1oI zl0Q?5H4(@{T{vigt2;L0JdryL5_i0eR|0XDYe+$I4 z`Z0Jj__ONy9>`DqhJ%dvYK4CWWxRiaGLCwu`>AWdA(z*K=fN%TgW${Hec*N5I>` zhrmyQ7W@MEZBXX*Cs6DkzFw&T*a2m{XF=iZN8l6SPe9S#zrh>9Lj;9Wbr=+T_k$9* zRZzw|1&Yod14U0cC_Mcd#8q_*;*~fof-=stpnU&ag+B*n-oFCn{ojJZ=N~~APn-}x zuHhi|Zv_d7x(oa$codZPz6fGc^}rO|1iuWv4$Al^-(SYP4@$hh56bhuffAob37YWu z3@H5l03_`09-!XF&QNX>-OF}2`-k0`QukJ0 z$)-&=eS4`j;G!-vKOUBYnlK!ju}$^Z@8?Bo8DTsQ{l3ZlB+m9-l>Xh(v$?rbt<3!s zx7CXHK2GhxrZ(=|th{mMnXH;@B=cNN`hm7j<+zWrMePr?pKCwEKkIepBjm|gk4
gRy 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%0DYg{08Re}+wK^@zHtQh`br(=U(0qmB zWjIo*+!k;4BvfiHY^xqbDQiF!BHLQ5Hcr89>TXezqLcb~*DlEB23uO_16_cYiD(w* zqNxT<6bBL(HN*B|MGZQ79pa;K8a0>+uom7T^p+MkEe8c9TA!b7=VhhF(A%B-16ri4 zT-CVOp>*X1qWv36sKHQU=$28Wk6eM7n4gc}V#THsSIJ0Z4PnhIi540XdNpFhc8G4l zc7Spg+W|K$gt=sI;O}U^DBP4N0tbn|JE;?je{K!isUvFz-lI#2J&KwRlB*-f!KiB6 z@Bxr8=U4$2wvHZ)`mf zZSb?|;-1JeU(NSS*-}`w9*(K3x>!$)8mUMKNfvz%sZ+6+ey~w;BG)FOl$fYl@8iu@ zMXk!6SU~`=`6(*uH=Do`M=O?U^_1U+G*DAoKfK=KxBD)Qt3e`zBu z*@6~W4YP#Z^*VJV*l${B8(J7yf%i|^s3Wzskr9vi=DAo*EwmM?7jbGREDYv%9C=PE z?mMVh!*(>aa8g1A*x(>`a&bhGorzP<&z@2(-AtfP;{5PIk%X)|sspO2!X78uu89DZ zbRe8uc13hY<7W_YbW^s2*G%4jNKeT#-nS*>dx|J(8WlX`zF33LCibpV6NctIUnZ)- zx6KagAs;Hj_SKjbO4-gGz9+Ogofi74&|@l;W#!A3`N|*ml`m7umsTuW{y;gdvaKMY zuZDIfbZXP8P#SOup%GG_)0H(#SC+3>UcPeWvWM2~+2e<+k6?unPM{8bHJTc$P}bwP zhZ70>5d6mmqFb%k~oDTfv{77(p|HeZN9k70{isov=ua`mh(q>}x*33?8gq z!Y^foe<^;xkXBd5(#gZ#@L=X*Yo>31W~AHgIO#TbX9tIW-}oZS4(R-~s+3t`^*Q^E#JD45C<#}^CvVhznWF_3Nf zK0b>Zyg^KJjU8T3I~2MHDdOqWL3eZ?-0&`6c8@f>&Eus)(#i8!#iKn$YJ?yOZbz%z zJK~-k7YdnsVA>s>MBrJrX@o>iwzwBwp=YnJ8-}p-6c{?_9q*WbR2K?ac6?uUtV_~~ z5r-P5KtnQNXfJZk+?kgIp}h9f*}0=$_eB1~z%XL(9yl#l6h6#P9vl&x$Pqcegy@A; zA~D6O1+}@Ck3+5eoL4R$DcJeAl6bfMRrk!H+{t$D_%wHAz9OVSm@c${N8UiAdwM3F zM5Xk4jk3to$;Rw!mqq4Ds(1K^+j>?;$UQI&7P&{pcxa|mZu5kYMv)Wh;4m*k_cG`+ z;I^eec<=nl%;2ckGn+Y;g3K}$m)kLh8ca|3xntAWrc2P8PW8J}6WO^}z2;-cAHIsJ z|yspqtIAjA{-Ij03{+jz|{Wq)I`w*e%8*U&bZCz_+eYA!RB6xaz@Fw2f6$;7d}R4K$GStGoa2@7QP%EOj8WDAMZ5O^hvNTDZ?6WP(T zvX*CGa+^}wv7yY=L9hF?JJ(G`jR~TOM#LY` z#zcX5-N(I)T@d58g2g2*TSOz-nm4A+8|#F5pqSfo7^z4nM~brZec|G;x4(n7g#yJ8 z{Rvbpwu6J2{$rxU@Sb+2S%PfdT%V+&U@9x6H}l$#!XwIfazxfvGa6uDcCHC3G8d+h zC$!AWnQ^gwKq=XW{+Q_>%?-W=Va#hi?H+9v1Yx2 zMza>2rm2SV-ItWe{i`&~!U(y=x!^q7W@*7NcWhD+LbN2gCHCzX`JoQbMfu{5`xFIn zU^qR~POFfI)DR}1`MQ%`R4C2IGPCXO`5`F^yICjSgG&`)fyfe-aM!roIGvqnB@Q2J za?f|uecvpacdq9^c5I3}#do4YhZa8Yl>aZwg&vwJ{3q2Vl<+!diMA!;)02nb2DzHI z3if!(177bqNf9+EqDO(@E5$ZN&hV { + let list_box = prefs_group + .get_first_child() + .get_last_child() + .get_first_child(); + + let elements = []; + let i = 0; + let element = list_box.get_row_at_index(i); + while (element) { + elements.push(element); + i++; + element = list_box.get_row_at_index(i); + } + + return elements; +}; + + +var Applications = GObject.registerClass({ + GTypeName: 'Applications', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'applications.ui'])}`, + InternalChildren: [ + 'blur', + 'customize', + 'opacity', + 'blur_on_overview', + 'enable_all', + 'whitelist', + 'add_window_whitelist', + 'blacklist', + 'add_window_blacklist' + ], +}, class Applications extends Adw.PreferencesPage { + constructor(preferences, preferences_window) { + super({}); + this._preferences_window = preferences_window; + + this.preferences = preferences; + + this.preferences.applications.settings.bind( + 'blur', this._blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'opacity', this._opacity, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'blur-on-overview', this._blur_on_overview, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'enable-all', this._enable_all, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._customize.connect_to(this.preferences.applications, false); + + // connect 'enable all' button to whitelist/blacklist visibility + this._enable_all.bind_property( + 'active', this._whitelist, 'visible', + GObject.BindingFlags.INVERT_BOOLEAN + ); + this._enable_all.bind_property( + 'active', this._blacklist, 'visible', + GObject.BindingFlags.DEFAULT + ); + + // make sure that blacklist / whitelist is correctly hidden + if (this._enable_all.active) + this._whitelist.visible = false; + this._blacklist.visible = !this._whitelist.visible; + + // listen to app row addition + this._add_window_whitelist.connect('clicked', + _ => this.add_to_whitelist() + ); + this._add_window_blacklist.connect('clicked', + _ => this.add_to_blacklist() + ); + + // add initial applications + this.add_widgets_from_lists(); + + this.preferences.connect('reset', _ => { + this.remove_all_widgets(); + this.add_widgets_from_lists(); + }); + } + + // A way to retriew the whitelist widgets. + get _whitelist_elements() { + return make_array(this._whitelist); + } + + // A way to retriew the blacklist widgets. + get _blacklist_elements() { + return make_array(this._blacklist); + } + + add_widgets_from_lists() { + this.preferences.applications.WHITELIST.forEach( + app_name => this.add_to_whitelist(app_name) + ); + + this.preferences.applications.BLACKLIST.forEach( + app_name => this.add_to_blacklist(app_name) + ); + + } + + close_all_expanded_rows() { + this._whitelist_elements.forEach( + element => element.set_expanded(false) + ); + this._blacklist_elements.forEach( + element => element.set_expanded(false) + ); + } + + remove_all_widgets() { + this._whitelist_elements.forEach( + element => this._whitelist.remove(element) + ); + this._blacklist_elements.forEach( + element => this._blacklist.remove(element) + ); + } + + add_to_whitelist(app_name = null) { + let window_row = new WindowRow('whitelist', this, app_name); + this._whitelist.add(window_row); + } + + add_to_blacklist(app_name = null) { + let window_row = new WindowRow('blacklist', this, app_name); + this._blacklist.add(window_row); + } + + update_whitelist_titles() { + let titles = this._whitelist_elements + .map(element => element._window_class.buffer.text) + .filter(title => title != ""); + + this.preferences.applications.WHITELIST = titles; + } + + update_blacklist_titles() { + let titles = this._blacklist_elements + .map(element => element._window_class.buffer.text) + .filter(title => title != ""); + + this.preferences.applications.BLACKLIST = titles; + } + + remove_from_whitelist(widget) { + this._whitelist.remove(widget); + this.update_whitelist_titles(); + } + + remove_from_blacklist(widget) { + this._blacklist.remove(widget); + this.update_blacklist_titles(); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/customize_row.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/customize_row.js new file mode 100644 index 0000000..f51fa43 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/customize_row.js @@ -0,0 +1,168 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio, Gtk } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const { Prefs } = Me.imports.conveniences.settings; +const { Keys } = Me.imports.conveniences.keys; + + +/// Given a component (described by its preferences node), a gschema key and +/// a Gtk.ColorButton, binds everything transparently. +let bind_color = function (component, key, widget) { + let property_name = key.replaceAll('-', '_').toUpperCase(); + + let parse_color = _ => { + let [r, g, b, a] = component[property_name]; + let w = widget.rgba; + w.red = r; + w.green = g; + w.blue = b; + w.alpha = a; + widget.rgba = w; + }; + component.settings.connect('changed::' + key, parse_color); + + widget.connect('color-set', _ => { + let c = widget.rgba; + component[property_name] = [c.red, c.green, c.blue, c.alpha]; + }); + + parse_color(); +}; + +var CustomizeRow = GObject.registerClass({ + GTypeName: 'CustomizeRow', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'customize-row.ui'])}`, + InternalChildren: [ + 'sigma', + 'brightness', + 'color', + 'color_row', + 'noise_amount', + 'noise_amount_row', + 'noise_lightness', + 'noise_lightness_row', + 'noise_color_notice' + ], +}, class CustomizeRow extends Adw.ExpanderRow { + /// Makes the required connections between the widgets and the preferences. + /// + /// This function may be bound to another object than CustomizeRow, if we + /// are using it for the General page; some things will then change (no + /// expansion row, and no notice) + /// + /// The color_and_noise parameter is either a boolean (true by default) or + /// a widget; and permits selecting weather or not we want to show the color + /// and noise buttons to the user. If it is a widget, it means we need to + /// dynamically update their visibility, according to the widget's state. + connect_to(component_prefs, color_and_noise = true) { + let s = component_prefs.settings; + + // is not fired if in General page + if (this instanceof CustomizeRow) + // bind the customize button + s.bind( + 'customize', this, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + + // bind sigma and brightness + s.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + s.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + + // bind the color button + bind_color(component_prefs, 'color', this._color); + + // bind noise sliders + s.bind( + 'noise-amount', this._noise_amount, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + s.bind( + 'noise-lightness', this._noise_lightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + + // color_and_noise is either a boolean or a widget, if true, or it is a + // widget, this will appropriately show the required preferences about + // setting the color and noise + if (color_and_noise) { + // if we gave the static_blur widget, we are dealing with the panel, + // and binding it to enable/disable the required components when + // switching between static and dynamic blur + if (color_and_noise instanceof Gtk.Switch) { + // bind its state to dynamically toggle the notice and rows + color_and_noise.bind_property( + 'state', this._color_row, 'visible', + GObject.BindingFlags.SYNC_CREATE + ); + color_and_noise.bind_property( + 'state', this._noise_amount_row, 'visible', + GObject.BindingFlags.SYNC_CREATE + ); + color_and_noise.bind_property( + 'state', this._noise_lightness_row, 'visible', + GObject.BindingFlags.SYNC_CREATE + ); + color_and_noise.bind_property( + 'state', this._noise_color_notice, 'visible', + GObject.BindingFlags.INVERT_BOOLEAN + ); + + // only way to get the correct state when first opening the + // window... + setTimeout(_ => { + let is_visible = color_and_noise.state; + this._color_row.visible = is_visible; + this._noise_amount_row.visible = is_visible; + this._noise_lightness_row.visible = is_visible; + this._noise_color_notice.visible = !is_visible; + }, 10); + } + + // if in General page, there is no notice at all + if (this instanceof CustomizeRow) { + // disable the notice + this._noise_color_notice.visible = false; + } + } else { + // enable the notice and disable color and noise preferences + this._color_row.visible = false; + this._noise_amount_row.visible = false; + this._noise_lightness_row.visible = false; + this._noise_color_notice.visible = true; + } + + const Preferences = new Prefs(Keys); + + // now we bind the color-and-noise preference to the sensitivity of the + // associated widgets, this will grey them out if the user choose not to + // have color and noise enabled + // note: I would love to bind to the visibility instead, but this part + // is already dirty enough, it would look like I obfuscate my code + // intentionally... (I am not) + Preferences.settings.bind( + 'color-and-noise', + this._color_row, 'sensitive', + Gio.SettingsBindFlags.DEFAULT + ); + Preferences.settings.bind( + 'color-and-noise', + this._noise_amount_row, 'sensitive', + Gio.SettingsBindFlags.DEFAULT + ); + Preferences.settings.bind( + 'color-and-noise', + this._noise_lightness_row, 'sensitive', + Gio.SettingsBindFlags.DEFAULT + ); + }; +}); diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/dash.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/dash.js new file mode 100644 index 0000000..b00181b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/dash.js @@ -0,0 +1,45 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); + + +var Dash = GObject.registerClass({ + GTypeName: 'Dash', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'dash.ui'])}`, + InternalChildren: [ + 'blur', + 'customize', + 'override_background', + 'style_dash_to_dock', + 'unblur_in_overview' + ], +}, class Dash extends Adw.PreferencesPage { + constructor(preferences) { + super({}); + + this.preferences = preferences; + + this.preferences.dash_to_dock.settings.bind( + 'blur', this._blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'override-background', + this._override_background, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'style-dash-to-dock', this._style_dash_to_dock, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'unblur-in-overview', this._unblur_in_overview, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._customize.connect_to(this.preferences.dash_to_dock, false); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/general.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/general.js new file mode 100644 index 0000000..74f494a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/general.js @@ -0,0 +1,50 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const { CustomizeRow } = Me.imports.preferences.customize_row; + + +var General = GObject.registerClass({ + GTypeName: 'General', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'general.ui'])}`, + InternalChildren: [ + 'sigma', + 'brightness', + 'color', + 'color_row', + 'noise_amount', + 'noise_amount_row', + 'noise_lightness', + 'noise_lightness_row', + 'color_and_noise', + 'hack_level', + 'debug', + 'reset' + ], +}, class General extends Adw.PreferencesPage { + constructor(preferences) { + super({}); + + this.preferences = preferences; + + CustomizeRow.prototype.connect_to.call(this, this.preferences); + + this.preferences.settings.bind( + 'color-and-noise', this._color_and_noise, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.settings.bind( + 'hacks-level', this._hack_level, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.settings.bind( + 'debug', this._debug, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._reset.connect('clicked', _ => this.preferences.reset()); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/menu.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/menu.js new file mode 100644 index 0000000..a319a2d --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/menu.js @@ -0,0 +1,64 @@ +'use strict'; + +const { Gdk, Gtk, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); + +function addMenu(window) { + const builder = new Gtk.Builder(); + + // add a dummy page and remove it immediately, to access headerbar + builder.add_from_file(`${Me.path}/ui/menu.ui`); + let menu_util = builder.get_object('menu_util'); + window.add(menu_util); + addMenuToHeader(window, builder); + window.remove(menu_util); +} + +function addMenuToHeader(window, builder) { + // a little hack to get to the headerbar + const page = builder.get_object('menu_util'); + const pages_stack = page.get_parent(); // AdwViewStack + const content_stack = pages_stack.get_parent().get_parent(); // GtkStack + const preferences = content_stack.get_parent(); // GtkBox + const headerbar = preferences.get_first_child(); // AdwHeaderBar + headerbar.pack_start(builder.get_object('info_menu')); + + // setup menu actions + const actionGroup = new Gio.SimpleActionGroup(); + window.insert_action_group('prefs', actionGroup); + + // a list of actions with their associated link + const actions = [ + { + name: 'open-bug-report', + link: 'https://github.com/aunetx/blur-my-shell/issues' + }, + { + name: 'open-readme', + link: 'https://github.com/aunetx/blur-my-shell' + }, + { + name: 'open-license', + link: 'https://github.com/aunetx/blur-my-shell/blob/master/LICENSE' + }, + { + name: 'donate-github', + link: 'https://github.com/sponsors/aunetx' + }, + { + name: 'donate-kofi', + link: 'https://ko-fi.com/aunetx' + }, + ]; + + actions.forEach(action => { + let act = new Gio.SimpleAction({ name: action.name }); + act.connect( + 'activate', + _ => Gtk.show_uri(window, action.link, Gdk.CURRENT_TIME) + ); + actionGroup.add_action(act); + }); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/other.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/other.js new file mode 100644 index 0000000..4ba3a88 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/other.js @@ -0,0 +1,51 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); + + +var Other = GObject.registerClass({ + GTypeName: 'Other', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'other.ui'])}`, + InternalChildren: [ + 'lockscreen_blur', + 'lockscreen_customize', + + 'screenshot_blur', + 'screenshot_customize', + + 'window_list_blur', + 'window_list_customize', + ], +}, class Overview extends Adw.PreferencesPage { + constructor(preferences) { + super({}); + + this.preferences = preferences; + + this.preferences.lockscreen.settings.bind( + 'blur', this._lockscreen_blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._lockscreen_customize.connect_to(this.preferences.lockscreen); + + this.preferences.screenshot.settings.bind( + 'blur', this._screenshot_blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._screenshot_customize.connect_to(this.preferences.screenshot); + + this.preferences.window_list.settings.bind( + 'blur', this._window_list_blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._window_list_customize.connect_to( + this.preferences.window_list, false + ); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/overview.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/overview.js new file mode 100644 index 0000000..f60b61e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/overview.js @@ -0,0 +1,49 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); + + +var Overview = GObject.registerClass({ + GTypeName: 'Overview', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'overview.ui'])}`, + InternalChildren: [ + 'overview_blur', + 'overview_customize', + 'overview_style_components', + + 'appfolder_blur', + 'appfolder_customize', + 'appfolder_style_dialogs' + ], +}, class Overview extends Adw.PreferencesPage { + constructor(preferences) { + super({}); + + this.preferences = preferences; + + this.preferences.overview.settings.bind( + 'blur', this._overview_blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.overview.settings.bind( + 'style-components', this._overview_style_components, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + + this._overview_customize.connect_to(this.preferences.overview); + + this.preferences.appfolder.settings.bind( + 'blur', this._appfolder_blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'style-dialogs', this._appfolder_style_dialogs, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + + this._appfolder_customize.connect_to(this.preferences.appfolder, false); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/panel.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/panel.js new file mode 100644 index 0000000..e127feb --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/panel.js @@ -0,0 +1,62 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); + + +var Panel = GObject.registerClass({ + GTypeName: 'Panel', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'panel.ui'])}`, + InternalChildren: [ + 'blur', + 'customize', + 'static_blur', + 'unblur_in_overview', + 'override_background', + 'style_panel', + 'override_background_dynamically', + 'hidetopbar_compatibility' + ], +}, class Panel extends Adw.PreferencesPage { + constructor(preferences) { + super({}); + + this.preferences = preferences; + + this.preferences.panel.settings.bind( + 'blur', this._blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'static-blur', this._static_blur, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'unblur-in-overview', this._unblur_in_overview, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'override-background', + this._override_background, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'style-panel', this._style_panel, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'override-background-dynamically', + this._override_background_dynamically, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + + this._customize.connect_to(this.preferences.panel, this._static_blur); + + this.preferences.hidetopbar.settings.bind( + 'compatibility', this._hidetopbar_compatibility, 'state', + Gio.SettingsBindFlags.DEFAULT + ); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/window_row.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/window_row.js new file mode 100644 index 0000000..9415c8e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/preferences/window_row.js @@ -0,0 +1,108 @@ +'use strict'; + +const { Adw, GLib, GObject, Gio, Gtk } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const { pick, on_picking, on_picked } = Me.imports.dbus.client; + + +var WindowRow = GObject.registerClass({ + GTypeName: 'WindowRow', + Template: `file://${GLib.build_filenamev([Me.path, 'ui', 'window-row.ui'])}`, + InternalChildren: [ + 'window_picker', + 'window_class', + 'picking_failure_toast' + ], +}, class WindowRow extends Adw.ExpanderRow { + constructor(list, app_page, app_name) { + super({}); + this._list = list; + this._app_page = app_page; + + // add a 'remove' button before the text + let action_row = this.child.get_first_child().get_first_child(); + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-window-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6, + }); + remove_button.add_css_class('circular'); + remove_button.add_css_class('flat'); + action_row.add_prefix(remove_button); + + // connect the button to the whitelist / blacklist removal + remove_button.connect('clicked', _ => this._remove_row()); + + // bind row title to text buffer + this._window_class.buffer.bind_property( + 'text', this, 'title', + Gio.SettingsBindFlags.BIDIRECTIONNAL + ); + + // set application name if it exists, or open the revealer and pick one + if (app_name) + this._window_class.buffer.text = app_name; + else { + app_page.close_all_expanded_rows(); + this.set_expanded(true); + this._do_pick_window(true); + } + + // pick a window when the picker button is clicked + this._window_picker.connect('clicked', _ => this._do_pick_window()); + + // update list on text buffer change + this._window_class.connect('changed', + _ => this._update_rows_titles() + ); + } + + _remove_row() { + this._app_page["remove_from_" + this._list](this); + } + + _update_rows_titles() { + this._app_page["update_" + this._list + "_titles"](this); + } + + _do_pick_window(remove_if_failed = false) { + // a mechanism to know if the extension is listening correcly + let has_responded = false; + let should_take_answer = true; + setTimeout(_ => { + if (!has_responded) { + // show toast about failure + this._app_page._preferences_window.add_toast( + this._picking_failure_toast + ); + + // prevent title from changing with later picks + should_take_answer = false; + + // remove row if asked + if (remove_if_failed) + this._remove_row(); + } + }, 15); + + on_picking(_ => + has_responded = true + ); + + on_picked(wm_class => { + if (should_take_answer) { + if (wm_class == 'window-not-found') { + log("Can't pick window from here"); + return; + } + this._window_class.buffer.text = wm_class; + } + }); + + pick(); + } +}); diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/prefs.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/prefs.js new file mode 100644 index 0000000..10dc080 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/prefs.js @@ -0,0 +1,43 @@ +'use strict'; + +const { Adw, Gdk, GLib, Gtk, GObject, Gio } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const { Prefs } = Me.imports.conveniences.settings; +const { Keys } = Me.imports.conveniences.keys; + +const { addMenu } = Me.imports.preferences.menu; +const { CustomizeRow } = Me.imports.preferences.customize_row; +const { WindowRow } = Me.imports.preferences.window_row; +const { General } = Me.imports.preferences.general; +const { Panel } = Me.imports.preferences.panel; +const { Overview } = Me.imports.preferences.overview; +const { Dash } = Me.imports.preferences.dash; +const { Applications } = Me.imports.preferences.applications; +const { Other } = Me.imports.preferences.other; + + +function init() { + ExtensionUtils.initTranslations(Me.metadata.uuid); + + // load the icon theme + let iconPath = Me.dir.get_child("icons").get_path(); + let iconTheme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()); + iconTheme.add_search_path(iconPath); +} + +function fillPreferencesWindow(window) { + addMenu(window); + + const preferences = new Prefs(Keys); + + window.add(new General(preferences)); + window.add(new Panel(preferences)); + window.add(new Overview(preferences)); + window.add(new Dash(preferences)); + window.add(new Applications(preferences, window)); + window.add(new Other(preferences)); + + window.search_enabled = true; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/schemas/gschemas.compiled b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..7f7ba2183028adfc9d6d2d4b975ae3e5aebb328e GIT binary patch literal 7773 zcmeI1Z;V`38OCq1g_gFqmV#UUSq+V|f!SSJYE~3k6VRFz+-Pm8Qqq~7ac9Ep%(ye# zKMHm~*kq$MRxH?<)>ILx|B^*XY+@xeQQU|aNJy*^W6{R&ftWQZf}ufwzdLhw?#gVP zZv5Z}Z}Rkc_U*Z6=AQGs?|EnDgIhDB#Z0*#HLoss%Yyii)Y4|`P4FUcF}NgwCFo0m zxu7x$9aM2 z7ytf!k-2G?8c$J_Vk?yze89 zS37>$$|zd-mMAKp-T$cZb*rMNhxiuw%wYG5)>qudj}x%II*)QujdZ_yYV5u;lFRzjeHNCGko4IC$aCZx0$*uOL1JKL@`4$iaJ!s}~YK1?!ty zad;#{{8|vDirqtFwR&Zw_?f(a$5$%b4eLpU$Lpqz-5=}|U#??zv^ZR-m-Dq+Beo&F z{(Nhc%5@J_N|n(@_&@)fO69n^yUUegEuYSeRK{9KJMQ?11-gxhO zTc+rpWs2Tlie4VNR^L;~r-v#d)k-;EuJfLKCZE6YvZdJ%6aQbX+xZqmtVhR2+*K^+ zD!bC9Vy#&SQm$jT+z;0@tgF6sU9AUU-%U*SeJ%WP;QqSaYWKGQ*Ma+MTrvRd&i5^`hHl+l8-y=r_9tP+qz{AFeW$_ibJ=X(zGd#PuRLy?BQA~pa(~wm%=BV{A)HTlm_iq9|076|;yH7{qhe6m^wflMuo&uq+sr8d)IRipn zQ#=1OyoMJKbxp0GQt(Y6_*?Dx0eBY(^-Hb4C*Xr1)GxLEJ_H{DPagT+7hG@ka^jP) z=Udq8u+MGRo%xO9HU14 zAb3%&7dOFMK=7{G_p<~35?Hn1T`xF~dMWWk@NdA@ZPlD{wei#N6+HaU{&e^IjH`{O z;JZP{RkiaM;3`-s8)lxy)#xkS z`}pX9xi$8I{?SXcmvP^rZ)hdi%Xn+zd^K;`F7}J{$dvOX-0#(?e>sP^i8_(X)C%c( zC7r7b-NPIm-=DmXX~@D-aVS%_8}+SpJWuk*^BiyU?|YcEHZ+>2Q!Z5M9=o0O(5-uz zpis=^>y>IYGum9{&Y!P!EAy0C2w$AZHcXwev2sbioveW2zof0=O zMdwFC=yMAhmLy%u@6?U0J~Ua?jd%QhW^N4cCY>qg(s7&9n4i3xv*}?3eN@MoEf1( zD3wCxq3$G%89t{pTJxFx=2f})Uc&m}KDx)&C@w>QV3%)qK%DCEiAKVZ0x^Z=!+wdL0 zTr#dUm$t#%fjMJb9p?-@2CN;%)xQ66ctTCy_TT3|cL3fDLT{rsHwNL4fzaEi&4C?o z354E8?fkppaS(bNwYhfyJ`6%{qjvl;_*r$+qiQ|+96Sv|Z=*H`B7T?fH;Vbyzt$rD zzrUINA(%yfL!V>)4K-N*h8i6D9BYlRKYIPD2daAB-;6F{pH9K2LFj+fasLCK13x + + + + + + 30 + Global sigma (gaussian blur radius) to use + + + + 0.6 + Global brightness to use + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + true + Boolean, controls wether or not the color and noise effects are in use globally + + + + 1 + Level of hacks to use (from 0 to 3, 3 disabling clipped redraws entirely) + + + + false + Boolean, set to true to activate debug mode (more verbose journalctl logs) + + + + + + + + + + + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + 1 + Enum to select the style of the components in overview (0 not styled, 1 light, 2 dark, 3 transparent) + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + 1 + Enum to select the style of the appfolder dialogs (0 not styled, 1 transparent, 2 light, 3 dark) + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + true + Boolean, whether to use a static or dynamic blur for this component + + + + true + Boolean, whether to disable blur from this component when opening the overview or not + + + + true + Boolean, whether to override the background or not + + + + 0 + Enum to select the style of the panel (0 transparent, 1 light, 2 dark) + + + + false + Boolean, whether to disable blur from this component when a window is close to the panel + + + + + + + + false + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + true + Boolean, whether to use static or dynamic blur for this component + + + + true + Boolean, whether to override the background or not + + + + 1 + Enum to select the style of dash to dock (0 transparent, 1 light, 2 dark) + + + + false + Boolean, whether to disable blur from this component when opening the overview or not + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + true + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 1. + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + 230 + Opacity of the window actor on top of the blur effect + + + + false + Wether or not to blur applications on the overview + + + + false + Wether or not to blur all applications by default + + + + [] + List of applications to blur + + + + ["Plank"] + List of applications not to blur + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + + + + + true + Boolean, whether to blur activate the blur for this component or not + + + + false + Boolean, whether to customize the blur effect sigma/brightness or use general values + + + + 30 + Sigma (gaussian blur radius) to use for the blur effect + + + + 0.6 + Brightness to use for the blur effect + + + + (0.,0.,0.,0.) + Color to mix with the blur effect + + + + 0. + Amount of noise to add to the blur effect + + + + 0. + Lightness of the noise added to the blur effect + + + + + + + + false + Boolean, whether to try compatibility with hidetopbar@mathieu.bidon.ca or not + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/stylesheet.css b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/stylesheet.css new file mode 100644 index 0000000..dbe5f37 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/stylesheet.css @@ -0,0 +1,257 @@ +/*** PANEL ***/ + +/* +* `.transparent-panel` +*/ +#panel.transparent-panel { + background: transparent; + transition-duration: 500ms; +} + +/* +* `.dark-panel` +*/ +#panel.dark-panel { + background-color: rgba(100, 100, 100, 0.35); + transition-duration: 500ms; +} + +/* +* `.light-panel` +*/ +#panel.light-panel { + background-color: rgba(200, 200, 200, 0.2); + transition-duration: 500ms; +} + + +/*** DASH ***/ + +/* +* `.transparent-dash` +*/ +.transparent-dash .dash-background { + background-color: transparent !important; +} + +/* +* `.light-dash` +*/ +.light-dash .dash-background { + background-color: rgba(200, 200, 200, 0.2) !important; +} + +/* +* `.dark-dash` +*/ +.dark-dash .dash-background { + background-color: rgba(100, 100, 100, 0.35) !important; +} + + +/*** OVERVIEW ***/ + +/* +* Add transparency to the workspace animation (between workspaces) +*/ +.blurred-overview .workspace-animation { + background-color: transparent !important; +} + + +/* +* `.overview-components-transparent` +*/ + +.overview-components-transparent .search-entry { + color: white; + background-color: rgba(0, 0, 0, 0); + border-color: transparent; + box-shadow: none; +} + +.overview-components-transparent .search-entry .search-entry-icon { + color: rgba(255, 255, 255, 0.65); +} + +.overview-components-transparent .search-section-content, +.overview-components-transparent .app-folder .overview-icon { + background-color: rgba(0, 0, 0, 0); +} + +/* prevents the extension from interfering with Just Perfection */ +.overview-components-transparent.just-perfection .search-section-content { + background-color: transparent; +} + +.overview-components-transparent .app-folder .overview-icon { + border-color: transparent; +} + +.overview-components-transparent .app-folder:hover .overview-icon, +.overview-components-transparent .app-folder:focus .overview-icon { + background-color: rgba(230, 230, 230, 0.08); +} + +.overview-components-transparent .app-folder:active .overview-icon, +.overview-components-transparent .app-folder:focus:hover .overview-icon, +.overview-components-transparent .app-folder:drop .overview-icon { + background-color: rgba(230, 230, 230, 0.12); +} + +.overview-components-transparent .app-folder:focus:active .overview-icon { + background-color: rgba(230, 230, 230, 0.15); +} + +/* this shouldn't apply to Dash to Dock */ +.overview-components-transparent StBoxLayout>StWidget>#dash>.dash-background { + background-color: rgba(0, 0, 0, 0); +} + +/* +* `.overview-components-light` +*/ + +.overview-components-light .search-entry { + color: white; + background-color: rgba(200, 200, 200, 0.2); + border-color: transparent; + box-shadow: none; +} + +.overview-components-light .search-entry .search-entry-icon { + color: rgba(255, 255, 255, 0.65); +} + +.overview-components-light .search-section-content, +.overview-components-light .app-folder .overview-icon { + background-color: rgba(200, 200, 200, 0.2); +} + +/* prevents the extension from interfering with Just Perfection */ +.overview-components-light.just-perfection .search-section-content { + background-color: transparent; +} + +.overview-components-light .app-folder .overview-icon { + border-color: transparent; +} + +.overview-components-light .app-folder:hover .overview-icon, +.overview-components-light .app-folder:focus .overview-icon { + background-color: rgba(230, 230, 230, 0.2); +} + +.overview-components-light .app-folder:active .overview-icon, +.overview-components-light .app-folder:focus:hover .overview-icon, +.overview-components-light .app-folder:drop .overview-icon { + background-color: rgba(230, 230, 230, 0.25); +} + +.overview-components-light .app-folder:focus:active .overview-icon { + background-color: rgba(230, 230, 230, 0.3); +} + +/* this shouldn't apply to Dash to Dock */ +.overview-components-light StBoxLayout>StWidget>#dash>.dash-background { + background-color: rgba(200, 200, 200, 0.2); +} + + +/* +* `.overview-components-dark` +*/ + +.overview-components-dark .search-entry { + color: white; + background-color: rgba(100, 100, 100, 0.35); + border-color: transparent; + box-shadow: none; +} + +.overview-components-dark .search-entry .search-entry-icon { + color: rgba(255, 255, 255, 0.65); +} + +.overview-components-dark .search-section-content, +.overview-components-dark .app-folder .overview-icon { + background-color: rgba(100, 100, 100, 0.35); +} + +/* prevents the extension from interfering with Just Perfection */ +.overview-components-dark.just-perfection .search-section-content { + background-color: transparent; +} + +.overview-components-dark .app-folder .overview-icon { + border-color: transparent; +} + +.overview-components-dark .app-folder:hover .overview-icon, +.overview-components-dark .app-folder:focus .overview-icon { + background-color: rgba(120, 120, 120, 0.35); +} + +.overview-components-dark .app-folder:active .overview-icon, +.overview-components-dark .app-folder:focus:hover .overview-icon, +.overview-components-dark .app-folder:drop .overview-icon { + background-color: rgba(120, 120, 120, 0.4); +} + +.overview-components-dark .app-folder:focus:active .overview-icon { + background-color: rgba(120, 120, 120, 0.45); +} + +/* this shouldn't apply to Dash to Dock */ +.overview-components-dark StBoxLayout>StWidget>#dash>.dash-background { + background-color: rgba(100, 100, 100, 0.35); +} + + +/*** APPFOLDER DIALOG ***/ + +/* +* `.appfolder-dialogs-transparent` +*/ + +.appfolder-dialogs-transparent { + background-color: rgba(0, 0, 0, 0); +} + +.appfolder-dialogs-transparent .folder-name-entry { + color: white; + background-color: rgba(0, 0, 0, 0); + border: 0; + box-shadow: none; +} + +/* +* `.appfolder-dialogs-light` +*/ + +.appfolder-dialogs-light { + background-color: rgba(200, 200, 200, 0.2); +} + +.appfolder-dialogs-light .folder-name-entry { + color: white; + background-color: rgba(200, 200, 200, 0.2); + border: 0; + box-shadow: none; +} + + +/* +* `.appfolder-dialogs-dark` +*/ + +.appfolder-dialogs-dark { + background-color: rgba(100, 100, 100, 0.35); +} + +.appfolder-dialogs-dark .folder-name-entry { + color: white; + background-color: rgba(100, 100, 100, 0.35); + border: 0; + box-shadow: none; +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/applications.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/applications.ui new file mode 100644 index 0000000..0b4b83c --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/applications.ui @@ -0,0 +1,163 @@ + + + + + + 25 + 255 + 1 + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/customize-row.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/customize-row.ui new file mode 100644 index 0000000..313bc48 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/customize-row.ui @@ -0,0 +1,143 @@ + + + + + + 0 + 200 + 1 + + + + 0.0 + 1.0 + 0.01 + + + + 0.0 + 1.0 + 0.01 + + + + 0.0 + 2.0 + 0.01 + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/dash.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/dash.ui new file mode 100644 index 0000000..5eac21b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/dash.ui @@ -0,0 +1,73 @@ + + + + + + + Transparent + Light + Dark + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/general.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/general.ui new file mode 100644 index 0000000..73c6b29 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/general.ui @@ -0,0 +1,234 @@ + + + + + + 0 + 200 + 1 + + + + 0.0 + 1.0 + 0.01 + + + + 0.0 + 1.0 + 0.01 + + + + 0.0 + 2.0 + 0.01 + + + + + High performances + Default + High quality + No artifact + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/menu.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/menu.ui new file mode 100644 index 0000000..e7b9210 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/menu.ui @@ -0,0 +1,37 @@ + + + +
+ + Project page + prefs.open-readme + + + Report a Bug + prefs.open-bug-report + + + License + prefs.open-license + + + Donate + + GitHub + prefs.donate-github + + + Ko-fi + prefs.donate-kofi + + +
+
+ + + info_menu_model + heart-filled-symbolic + + + +
\ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/other.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/other.ui new file mode 100644 index 0000000..d1d24f8 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/other.ui @@ -0,0 +1,62 @@ + + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/overview.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/overview.ui new file mode 100644 index 0000000..191c70b --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/overview.ui @@ -0,0 +1,94 @@ + + + + + + + Do not style + Light + Dark + Transparent + + + + + + Do not style + Transparent + Light + Dark + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/panel.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/panel.ui new file mode 100644 index 0000000..3979f8e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/panel.ui @@ -0,0 +1,126 @@ + + + + + + + Transparent + Light + Dark + + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/window-row.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/window-row.ui new file mode 100644 index 0000000..c4d8201 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/blur-my-shell@aunetx/ui/window-row.ui @@ -0,0 +1,43 @@ + + + + + + Could not pick window, make sure that the extension is enabled. + + \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/LICENSE b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/extension.js new file mode 100644 index 0000000..09b0aba --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/extension.js @@ -0,0 +1,1330 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ,-. ,--. ,-. , , ,---. ,-. ;-. ,-. . . ,-. ,--. // +// | \ | ( ` | / | / \ | ) / | | | ) | // +// | | |- `-. |< | | | |-' | | | |-< |- // +// | / | . ) | \ | \ / | \ | | | ) | // +// `-' `--' `-' ' ` ' `-' ' `-' `--` `-' `--' // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {Clutter, Graphene, GObject, Shell, St, Meta, Gio} = imports.gi; + +const Util = imports.misc.util; +const Main = imports.ui.main; +const Layout = imports.ui.layout; +const WorkspacesView = imports.ui.workspacesView.WorkspacesView; +const FitMode = imports.ui.workspacesView.FitMode; +const WorkspaceAnimationController = + imports.ui.workspaceAnimation.WorkspaceAnimationController; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; +const DragGesture = Me.imports.src.DragGesture.DragGesture; +const Skybox = Me.imports.src.Skybox.Skybox; + +////////////////////////////////////////////////////////////////////////////////////////// +// This extensions tweaks the positioning of workspaces in overview mode and while // +// switching workspaces in desktop mode to make them look like cube faces. // +////////////////////////////////////////////////////////////////////////////////////////// + +// Maximum degrees the cube can be rotated up and down. +const MAX_VERTICAL_ROTATION = 50; + +// Spacing to the screen sides of the vertically rotated cube. +const PADDING_V_ROTATION = 0.2; + +class Extension { + // The constructor is called once when the extension is loaded, not enabled. + constructor() { + this._lastWorkspaceWidth = 0; + } + + // ------------------------------------------------------------------------ public stuff + + // This function could be called after the extension is enabled, which could be done + // from GNOME Tweaks, when you log in or when the screen is unlocked. + enable() { + + // Store a reference to the settings object. + this._settings = ExtensionUtils.getSettings(); + + // We will monkey-patch these methods. Let's store the original ones. + this._origUpdateWorkspacesState = WorkspacesView.prototype._updateWorkspacesState; + this._origGetSpacing = WorkspacesView.prototype._getSpacing; + this._origUpdateVisibility = WorkspacesView.prototype._updateVisibility; + this._origAnimateSwitch = WorkspaceAnimationController.prototype.animateSwitch; + this._origPrepSwitch = WorkspaceAnimationController.prototype._prepareWorkspaceSwitch; + this._origFinalSwitch = WorkspaceAnimationController.prototype._finishWorkspaceSwitch; + + // We may also override these animation times. + this._origWorkspaceSwitchTime = imports.ui.workspacesView.WORKSPACE_SWITCH_TIME; + this._origToOverviewTime = imports.ui.overview.ANIMATION_TIME; + this._origToAppDrawerTime = imports.ui.overviewControls.SIDE_CONTROLS_ANIMATION_TIME; + + // We will use extensionThis to refer to the extension inside the patched methods of + // the WorkspacesView. + const extensionThis = this; + + // Connect the animation times to our settings. + const loadAnimationTimes = () => { + { + const t = this._settings.get_int('overview-transition-time'); + imports.ui.overview.ANIMATION_TIME = (t > 0 ? t : this._origToOverviewTime); + } + { + const t = this._settings.get_int('appgrid-transition-time'); + imports.ui.overviewControls.SIDE_CONTROLS_ANIMATION_TIME = + (t > 0 ? t : this._origToAppDrawerTime); + } + { + const t = this._settings.get_int('workspace-transition-time'); + imports.ui.workspacesView.WORKSPACE_SWITCH_TIME = + (t > 0 ? t : this._origWorkspaceSwitchTime); + } + }; + + this._settings.connect('changed::overview-transition-time', loadAnimationTimes); + this._settings.connect('changed::appgrid-transition-time', loadAnimationTimes); + this._settings.connect('changed::workspace-transition-time', loadAnimationTimes); + + loadAnimationTimes(); + + + // ----------------------------------------------------------------------------------- + // ------------------------------- cubify the overview ------------------------------- + // ----------------------------------------------------------------------------------- + + // Normally, all workspaces outside the current field-of-view are hidden. We want to + // show all workspaces, so we patch this method. The original code is about here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L420 + WorkspacesView.prototype._updateVisibility = function() { + this._workspaces.forEach((w) => { + w.show(); + }); + }; + + // Usually, workspaces are placed next to each other separated by a few pixels (this + // separation is usually computed by the method below). To create the desktop cube, we + // have to position all workspaces on top of each other and rotate the around a pivot + // point in the center of the cube. + // The original arrangement of the workspaces is implemented in WorkspacesView's + // vfunc_allocate() which cannot be monkey-patched. As a workaround, we return a + // negative spacing in the method below... + // The original code is about here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L219 + WorkspacesView.prototype._getSpacing = function(box, fitMode, vertical) { + // We use the "normal" workspace spacing in desktop and app-grid mode. + const origValue = + extensionThis._origGetSpacing.apply(this, [box, fitMode, vertical]); + + if (fitMode == FitMode.ALL) { + return origValue; + } + + // Compute the negative spacing required to arrange workspaces on top of each other. + const overlapValue = -this._workspaces[0].get_preferred_width(box.get_size()[1])[1]; + + // Blend between the negative overlap-spacing and the "normal" spacing value. + const cubeMode = extensionThis._getCubeMode(this); + return Util.lerp(origValue, overlapValue, cubeMode); + }; + + // This is the main method which is called whenever the workspaces need to be + // repositioned. + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L255 + WorkspacesView.prototype._updateWorkspacesState = function() { + // Use the original method if we have just one workspace. + const faceCount = this._workspaces.length; + if (faceCount <= 1) { + extensionThis._origUpdateWorkspacesState.apply(this); + return; + } + + // Here's a minor hack to improve the performance: During the transitions to / from + // the app drawer, this._updateWorkspacesState is called twice a frame. Once from + // the notify handler of this._fitModeAdjustment and thereafter once from the notify + // handler of this._overviewAdjustment. As this seems not so useful (and degrades + // performance a lot), we skip the first call. I am not aware of any cases where + // this._fitModeAdjustment is changed without any of the over adjustments to change + // as well... + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L109 + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L45 + if ((new Error()).stack.includes('fitModeNotify')) { + return; + } + + // Compute blending state from and to the overview, from and to the app grid, and + // from and to the desktop mode. We will use cubeMode to fold and unfold the + // cube, overviewMode to add some depth between windows and backgrounds, and + // appDrawerMode to attenuate the scaling effect of the active workspace. + const appDrawerMode = extensionThis._getAppDrawerMode(this); + const overviewMode = extensionThis._getOverviewMode(this); + const cubeMode = extensionThis._getCubeMode(this); + + // First we need the width of a single workspace. Simply calling + // this._workspaces[0]._background.width does not work in all cases, as this method + // seems to be called also when the background actor is not on the stage. As a hacky + // workaround, we store the last valid workspace width we got and use that value if + // we cannot get a new one... + let workspaceWidth = extensionThis._lastWorkspaceWidth; + const bg = this._workspaces[0]._background; + if (bg.get_stage() && bg.allocation.get_width() > 0) { + workspaceWidth = bg.allocation.get_width(); + + // Add gaps between workspaces in overview mode. + workspaceWidth += + overviewMode * 2 * extensionThis._settings.get_int('workpace-separation'); + + extensionThis._lastWorkspaceWidth = workspaceWidth; + } + + // That's the angle between consecutive workspaces. + const faceAngle = extensionThis._getFaceAngle(faceCount); + + // That's the z-distance from the cube faces to the rotation pivot. + const centerDepth = extensionThis._getCenterDist(workspaceWidth, faceAngle); + + // Apply vertical rotation if required. This comes from the pitch value of the + // modified SwipeTracker created by _addOverviewDragGesture() further below. + this.pivot_point_z = -centerDepth; + this.set_pivot_point(0.5, 0.5); + this.rotation_angle_x = extensionThis._pitch.value * MAX_VERTICAL_ROTATION; + + // During rotations, the cube is scaled down and the windows are "exploded". If we + // are directly facing a cube side, the strengths of both effects are approaching + // zero. The strengths of both effects are small during horizontal rotations to make + // workspace-switching not so obtrusive. However, during vertical rotations, the + // effects are stronger. + const [depthOffset, explode] = extensionThis._getExplodeFactors( + this._scrollAdjustment.value, extensionThis._pitch.value, centerDepth, + this._monitorIndex); + + // Now loop through all workspace and compute the individual rotations. + this._workspaces.forEach((w, index) => { + // First update the corner radii. Corners are only rounded in overview. + w.stateAdjustment.value = overviewMode; + + // Now update the rotation of the cube face. The rotation center is -centerDepth + // units behind the front face. + w.pivot_point_z = -centerDepth; + + // Make cube smaller during rotations. + w.translation_z = -depthOffset; + + // The rotation angle is transitioned proportional to cubeMode^1.5. This slows + // down the rotation a bit closer to the desktop and to the app drawer. + w.rotation_angle_y = + Math.pow(cubeMode, 1.5) * (-this._scrollAdjustment.value + index) * faceAngle; + + // Distance to being the active workspace in [-1...0...1]. + const dist = Math.clamp(index - this._scrollAdjustment.value, -1, 1); + + // This moves next and previous workspaces a bit to the left and right. This + // ensures that we can actually see them if we look at the cube from the front. + // The value is set to zero if we have five or more workspaces. + if (faceCount <= 4) { + w.translation_x = + dist * overviewMode * extensionThis._settings.get_int('horizontal-stretch'); + } else { + w.translation_x = 0; + } + + // Update opacity only in overview mode. + const opacityA = extensionThis._settings.get_int('active-workpace-opacity'); + const opacityB = extensionThis._settings.get_int('inactive-workpace-opacity'); + const opacity = Util.lerp(opacityA, opacityB, Math.abs(dist)); + w._background.set_opacity(Util.lerp(255, opacity, overviewMode)); + + // Update workspace scale only in app grid mode. The 0.94 is supposed to be the + // same value as the WORKSPACE_INACTIVE_SCALE defined here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L21 + // As this is defined as 'const', we cannot access it here. But the exact value + // also not really matters... + const scale = Util.lerp(1, 0.94, Math.abs(dist) * appDrawerMode); + w.set_scale(scale, scale); + + // Now we add some depth separation between the window clones. If the explode + // factor becomes too small, the depth sorting becomes non-deterministic. + if (explode > 0.001) { + + const sortedActors = w._container.layout_manager._sortedWindows; + + // Distribute the window clones translation_z values between zero and + // explode. + sortedActors.forEach((windowActor, j) => { + windowActor.translation_z = explode * (j + 1) / sortedActors.length; + }); + + // Now sort the window clones according to the orthogonal distance of the actor + // planes to the camera. This ensures proper depth sorting among the window + // clones. + if (sortedActors.length > 1) { + extensionThis._depthSortWindowActors(w._container.get_children(), + this._monitorIndex); + } + } + + // Now we sort the children of the workspace (e.g. the background actor + // and the container for the window clones) by their orthogonal distance to the + // virtual camera. We add a tiny translation to the window-clone container to + // allow for proper sorting. + w._container.translation_z = 1; + extensionThis._depthSortWindowActors(w.get_children(), this._monitorIndex); + }); + + // The depth-sorting of cube faces is quite simple, we sort them by increasing + // rotation angle so that they are drawn back-to-front. + extensionThis._depthSortCubeFaces(this._workspaces); + }; + + + // ----------------------------------------------------------------------------------- + // --------------------- cubify workspace-switch in desktop mode --------------------- + // ----------------------------------------------------------------------------------- + + // Here, we extend the WorkspaceAnimationController's animateSwitch method in order to + // be able to modify the animation duration for switching workspaces in desktop mode. + // We have to do it like this since the time is hard-coded with a constant: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspaceAnimation.js#L11 + WorkspaceAnimationController.prototype.animateSwitch = function(...params) { + // Call the original method. This sets up the progress transitions which we tweak + // thereafter. + extensionThis._origAnimateSwitch.apply(this, params); + + // Now update the transition durations. + const duration = extensionThis._settings.get_int('workspace-transition-time'); + if (duration > 0) { + for (const monitorGroup of this._switchData.monitors) { + monitorGroup.get_transition('progress').set_duration(duration); + } + } + }; + + // This override rotates the workspaces during the transition to look like cube + // faces. The original movement of the workspaces is implemented in the setter of + // the progress property. We do not touch this, as keeping track of this progress + // is rather important. Instead, we listen to progress changes and tweak the + // transformation accordingly. + // This lambda is called in two places (further down), once for updates of the + // progress property, once for updates during gesture swipes. The latter does not + // trigger notify signals of the former for some reason... + const updateMonitorGroup = (group) => { + // First, we prevent any horizontal movement by countering the translation. We + // cannot simply set the x property to zero as this is used to track the + // progress. + group._container.translation_x = -group._container.x; + + // That's the desired angle between consecutive workspaces. + const faceAngle = extensionThis._getFaceAngle(group._workspaceGroups.length); + + // That's the z-distance from the cube faces to the rotation pivot. + const centerDepth = + extensionThis._getCenterDist(group._workspaceGroups[0].width, faceAngle); + + // Apply vertical rotation if required. This comes from the pitch value of the + // modified SwipeTracker created by _addDesktopDragGesture() further below. + group._container.pivot_point_z = -centerDepth; + group._container.set_pivot_point(0.5, 0.5); + group._container.rotation_angle_x = + extensionThis._pitch.value * MAX_VERTICAL_ROTATION; + + // During rotations, the cube is scaled down and the windows are "exploded". If we + // are directly facing a cube side, the strengths of both effects are approaching + // zero. The strengths of both effects are small during horizontal rotations to make + // workspace-switching not so obtrusive. However, during vertical rotations, the + // effects are stronger. + const [depthOffset, explode] = extensionThis._getExplodeFactors( + group.progress, extensionThis._pitch.value, centerDepth, group._monitor.index); + + // Rotate the individual faces. + group._workspaceGroups.forEach((child, i) => { + child.set_pivot_point_z(-centerDepth); + child.set_pivot_point(0.5, 0.5); + child.rotation_angle_y = (i - group.progress) * faceAngle; + child.translation_z = -depthOffset; + child.clip_to_allocation = false; + + // Counter the horizontal movement. + child.translation_x = -child.x; + + // Make cube transparent during vertical rotations. + child._background.opacity = 255 * (1.0 - Math.abs(extensionThis._pitch.value)); + + // Now we add some depth separation between the window clones. We get the stacking + // order from the global window list. If the explode factor becomes too small, the + // depth sorting becomes non-deterministic. + if (explode > 0.001) { + const windowActors = global.get_window_actors().filter(w => { + return child._shouldShowWindow(w.meta_window); + }); + + // Distribute the window clones translation_z values between zero and + // explode. + windowActors.forEach((windowActor, j) => { + const record = child._windowRecords.find(r => r.windowActor === windowActor); + if (record) { + record.clone.translation_z = explode * (j + 1) / windowActors.length; + } + }); + + // Now sort the window clones and the background actor according to the + // orthogonal distance of the actor planes to the camera. This ensures proper + // depth sorting. + extensionThis._depthSortWindowActors(child.get_children(), + group._monitor.index); + } + }); + + // The depth-sorting of cube faces is quite simple, we sort them by increasing + // rotation angle. + extensionThis._depthSortCubeFaces(group._workspaceGroups); + + // Update horizontal rotation of the background panorama during workspace switches. + if (this._skybox) { + this._skybox.yaw = + 2 * Math.PI * group.progress / global.workspaceManager.get_n_workspaces(); + } + }; + + // Whenever a workspace-switch is about to happen, we tweak the MonitorGroup class a + // bit to arrange the workspaces in a cube-like fashion. We have to adjust to parts of + // the code as the automatic transitions (e.g. when switching with key combinations) + // are handled differently than the gesture based switches. + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspaceAnimation.js#L299 + WorkspaceAnimationController.prototype._prepareWorkspaceSwitch = function() { + // Here, we call the original method without any arguments. Usually, GNOME Shell + // "skips" workspaces when switching to a workspace which is more than one workspace + // to the left or the right. This behavior is not desirable for thr cube, as it + // messes with your spatial memory. If no workspaceIndices are given to this method, + // all workspaces will be shown during the workspace switch. + extensionThis._origPrepSwitch.apply(this, []); + + // Now tweak the monitor groups. + this._switchData.monitors.forEach(m => { + // Call the method above whenever the transition progress changes. + m.connect('notify::progress', () => updateMonitorGroup(m)); + + // Call the method above whenever a gesture is active. + const orig = m.updateSwipeForMonitor; + m.updateSwipeForMonitor = function(progress, baseMonitorGroup) { + orig.apply(m, [progress, baseMonitorGroup]); + updateMonitorGroup(m); + }; + }); + + // Make sure that the background panorama is drawn above the window group during a + // workspace switch. + if (extensionThis._skybox) { + extensionThis._skybox.get_parent().remove_child(extensionThis._skybox); + Main.uiGroup.insert_child_above(extensionThis._skybox, global.window_group); + + // If the workspaces are only on the primary monitor, the skybox would cover all + // other non-rotating screens. Therefore, we temporarily limit its size to the + // primary monitor's size. + if (Meta.prefs_get_workspaces_only_on_primary()) { + const monitor = + global.display.get_monitor_geometry(global.display.get_primary_monitor()); + extensionThis._skybox.width = monitor.width; + extensionThis._skybox.height = monitor.height; + extensionThis._skybox.x = monitor.x; + extensionThis._skybox.y = monitor.y; + } + } + }; + + // Re-attach the background panorama to the stage once the workspace switch is done. + WorkspaceAnimationController.prototype._finishWorkspaceSwitch = function(...params) { + extensionThis._origFinalSwitch.apply(this, params); + + // Make sure that the skybox covers the entire stage again. + if (extensionThis._skybox) { + extensionThis._skybox.get_parent().remove_child(extensionThis._skybox); + global.stage.insert_child_below(extensionThis._skybox, null); + + if (Meta.prefs_get_workspaces_only_on_primary()) { + extensionThis._skybox.width = global.stage.width; + extensionThis._skybox.height = global.stage.height; + extensionThis._skybox.x = global.stage.x; + extensionThis._skybox.y = global.stage.y; + } + } + }; + + + // ----------------------------------------------------------------------------------- + // ------------------------- enable cube rotation by dragging ------------------------ + // ----------------------------------------------------------------------------------- + + // Usually, in GNOME Shell 40+, workspaces are move horizontally. We tweaked this to + // look like a horizontal rotation above. To store the current vertical rotation, we + // use the adjustment below. + this._pitch = new St.Adjustment({actor: global.stage, lower: -1, upper: 1}); + + // The overview's SwipeTracker will control the _overviewAdjustment of the + // WorkspacesDisplay. However, only horizontal swipes will update this adjustment. If + // only our pitch adjustment is changed (e.g. the user moved the mouse only + // vertically), the _overviewAdjustment will not change and therefore the workspaces + // will not been redrawn. Here we force redrawing by notifying changes if the pitch + // value changes. + this._pitch.connect('notify::value', () => { + if (Main.actionMode == Shell.ActionMode.OVERVIEW) { + Main.overview._overview._controls._workspacesDisplay._overviewAdjustment.notify( + 'value'); + } + }); + + // In GNOME Shell, SwipeTrackers are used all over the place to capture swipe + // gestures. There's one for entering the overview, one for switching workspaces in + // desktop mode, one for switching workspaces in overview mode, one for horizontal + // scrolling in the app drawer, and many more. The ones used for workspace-switching + // usually do not respond to single-click dragging but only to multi-touch gestures. + // We want to be able to rotate the cube with the left mouse button, so we add an + // additional gesture to these two SwipeTracker instances tracking single-click drags. + + // Add single-click drag gesture to the desktop. + if (this._settings.get_boolean('enable-desktop-dragging')) { + this._addDesktopDragGesture(); + } + + this._settings.connect('changed::enable-desktop-dragging', () => { + if (this._settings.get_boolean('enable-desktop-dragging')) { + this._addDesktopDragGesture(); + } else { + this._removeDesktopDragGesture(); + } + }); + + // Add single-click drag gesture to the panel. + if (this._settings.get_boolean('enable-panel-dragging')) { + this._addPanelDragGesture(); + } + + this._settings.connect('changed::enable-panel-dragging', () => { + if (this._settings.get_boolean('enable-panel-dragging')) { + this._addPanelDragGesture(); + } else { + this._removePanelDragGesture(); + } + }); + + // Add single-click drag gesture to the overview. + if (this._settings.get_boolean('enable-overview-dragging')) { + this._addOverviewDragGesture(); + } + + this._settings.connect('changed::enable-overview-dragging', () => { + if (this._settings.get_boolean('enable-overview-dragging')) { + this._addOverviewDragGesture(); + } else { + this._removeOverviewDragGesture(); + } + }); + + + // ----------------------------------------------------------------------------------- + // ---------------------------------- add the skybox --------------------------------- + // ----------------------------------------------------------------------------------- + + // This is called whenever the skybox texture setting is changed. + const updateSkybox = () => { + // First, delete the existing skybox. + if (this._skybox) { + this._skybox.destroy(); + delete this._skybox; + } + + const file = this._settings.get_string('background-panorama'); + + // Then, load a new one (if any). + if (file != '') { + try { + this._skybox = new Skybox(file); + + // We add the skybox below everything. + global.stage.insert_child_below(this._skybox, null); + + // Make sure that the skybox covers the entire stage. + global.stage.bind_property('width', this._skybox, 'width', + GObject.BindingFlags.SYNC_CREATE); + global.stage.bind_property('height', this._skybox, 'height', + GObject.BindingFlags.SYNC_CREATE); + + } catch (error) { + utils.debug('Failed to set skybox: ' + error); + } + } + }; + + // Update the skybox whenever the corresponding setting is changed. + this._settings.connect('changed::background-panorama', updateSkybox); + updateSkybox(); + + // Update vertical rotation of the background panorama. + this._pitch.connect('notify::value', () => { + if (this._skybox) { + this._skybox.pitch = (this._pitch.value * MAX_VERTICAL_ROTATION) * Math.PI / 180; + } + }); + + // Update horizontal rotation of the background panorama during workspace switches in + // the overview. + Main.overview._overview.controls._workspaceAdjustment.connect('notify::value', () => { + if (this._skybox) { + this._skybox.yaw = 2 * Math.PI * + Main.overview._overview.controls._workspaceAdjustment.value / + global.workspaceManager.get_n_workspaces(); + } + }); + + + // ----------------------------------------------------------------------------------- + // ----------------------- enable edge-drag workspace-switches ----------------------- + // ----------------------------------------------------------------------------------- + + // We add two Meta.Barriers, one at each side of the stage. If the pointer hits one of + // these with enough pressure while dragging a window, we initiate a workspace-switch. + // The last parameter (0) is actually supposed to be a bitwise combination of + // Shell.ActionModes. The pressure barrier will only trigger, if Main.actionMode + // equals one of the given action modes. This works well for Shell.ActionMode.NORMAL + // and Shell.ActionMode.OVERVIEW, however it does not work for Shell.ActionMode.NONE + // (which actually equals zero). However, when we want the barriers to also trigger in + // Shell.ActionMode.NONE, as this is the mode during a drag-operation in the overview. + // Therefore, we modify the _onBarrierHit method of the pressure barrier to completely + // ignore this parameter. Instead, we check for the correct action mode in the trigger + // handler. + this._pressureBarrier = + new Layout.PressureBarrier(this._settings.get_int('edge-switch-pressure'), + Layout.HOT_CORNER_PRESSURE_TIMEOUT, 0); + + // Update pressure threshold when the corresponding settings key changes. + this._settings.connect('changed::edge-switch-pressure', () => { + this._pressureBarrier._threshold = this._settings.get_int('edge-switch-pressure'); + }); + + // This is an exact copy of the original _onBarrierHit, with only one line disabled to + // ignore the given ActionMode. + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/layout.js#L1366 + this._pressureBarrier._onBarrierHit = function(barrier, event) { + barrier._isHit = true; + + // If we've triggered the barrier, wait until the pointer has the + // left the barrier hitbox until we trigger it again. + if (this._isTriggered) return; + + if (this._eventFilter && this._eventFilter(event)) return; + + // Throw out all events not in the proper keybinding mode + // if (!(this._actionMode & Main.actionMode)) return; + + let slide = this._getDistanceAlongBarrier(barrier, event); + let distance = this._getDistanceAcrossBarrier(barrier, event); + + if (distance >= this._threshold) { + this._trigger(); + return; + } + + // Throw out events where the cursor is move more + // along the axis of the barrier than moving with + // the barrier. + if (slide > distance) return; + + this._lastTime = event.time; + + this._trimBarrierEvents(); + distance = Math.min(15, distance); + + this._barrierEvents.push([event.time, distance]); + this._currentPressure += distance; + + if (this._currentPressure >= this._threshold) this._trigger(); + }; + + // Now we add the left and right barrier to the pressure barrier. + const createBarriers = () => { + if (this._leftBarrier) { + this._pressureBarrier.removeBarrier(this._leftBarrier); + this._leftBarrier.destroy(); + } + + if (this._rightBarrier) { + this._pressureBarrier.removeBarrier(this._rightBarrier); + this._rightBarrier.destroy(); + } + + this._leftBarrier = new Meta.Barrier({ + display: global.display, + x1: 0, + x2: 0, + y1: 1, + y2: global.stage.height, + directions: Meta.BarrierDirection.POSITIVE_X, + }); + + this._rightBarrier = new Meta.Barrier({ + display: global.display, + x1: global.stage.width, + x2: global.stage.width, + y1: 1, + y2: global.stage.height, + directions: Meta.BarrierDirection.NEGATIVE_X, + }); + + this._pressureBarrier.addBarrier(this._leftBarrier); + this._pressureBarrier.addBarrier(this._rightBarrier); + }; + + // Re-create the barriers whenever the stage's allocation is changed. + this._stageAllocationID = global.stage.connect('notify::allocation', createBarriers); + createBarriers(); + + // When the pressure barrier is triggered, the corresponding setting is enabled, and a + // window is currently dragged, we move the dragged window to the adjacent workspace + // and activate it as well. + this._pressureBarrier.connect('trigger', () => { + const direction = + this._leftBarrier._isHit ? Meta.MotionDirection.LEFT : Meta.MotionDirection.RIGHT; + + const newWorkspace = + global.workspace_manager.get_active_workspace().get_neighbor(direction); + + if (Main.actionMode == Shell.ActionMode.NORMAL && this._draggedWindow && + this._settings.get_boolean('enable-desktop-edge-switch')) { + Main.wm.actionMoveWindow(this._draggedWindow, newWorkspace); + } else if (Main.actionMode == Shell.ActionMode.NONE && Main.overview.visible && + this._settings.get_boolean('enable-overview-edge-switch')) { + newWorkspace.activate(global.get_current_time()); + } + }); + + // Keep a reference to the currently dragged window. + global.display.connect('grab-op-begin', (d, win, op) => { + if (op == Meta.GrabOp.MOVING) { + this._draggedWindow = win; + } + }); + + // Release the reference to the currently dragged window. + global.display.connect('grab-op-end', (d, win, op) => { + if (op == Meta.GrabOp.MOVING) { + this._draggedWindow = null; + } + }); + + + // ----------------------------------------------------------------------------------- + // ------------------- fix perspective of multi-monitor setups ----------------------- + // ----------------------------------------------------------------------------------- + + // Usually, GNOME Shell uses one central perspective for all monitors combined. This + // results in a somewhat sheared appearance of the cube on multi-monitor setups where + // the primary monitor is not in the middle (or cubes are shown on multiple monitors). + // With the code below, we modify the projection and view matrices for each monitor so + // that each monitor uses its own central perspective. This seems to be possible on + // Wayland only. On X11, there's only one set of projection and view matrices for all + // monitors combined, so we tweak them so that the projection center is in the middle + // of the primary monitor. So it will at least only look bad on X11 if the cube is + // shown on all monitors... + const updateMonitorPerspective = () => { + // Disable the perspective fixes first... + this._disablePerspectiveCorrection(); + + // Store this so we do not have to get it too often. + this._enablePerMonitorPerspective = + this._settings.get_boolean('per-monitor-perspective') && + global.display.get_n_monitors() > 1; + + // ... and then enable them if required. + if (this._enablePerMonitorPerspective) { + this._enablePerspectiveCorrection(); + } + }; + + this._settings.connect('changed::per-monitor-perspective', updateMonitorPerspective); + this._monitorsChangedID = + Meta.MonitorManager.get().connect('monitors-changed', updateMonitorPerspective); + + updateMonitorPerspective(); + } + + // This function could be called after the extension is uninstalled, disabled in GNOME + // Tweaks, when you log out or when the screen locks. + disable() { + + // Restore the original behavior. + WorkspacesView.prototype._updateWorkspacesState = this._origUpdateWorkspacesState; + WorkspacesView.prototype._getSpacing = this._origGetSpacing; + WorkspacesView.prototype._updateVisibility = this._origUpdateVisibility; + WorkspaceAnimationController.prototype.animateSwitch = this._origAnimateSwitch; + WorkspaceAnimationController.prototype._prepareWorkspaceSwitch = this._origPrepSwitch; + WorkspaceAnimationController.prototype._finishWorkspaceSwitch = this._origFinalSwitch; + + imports.ui.workspacesView.WORKSPACE_SWITCH_TIME = this._origWorkspaceSwitchTime; + imports.ui.overview.ANIMATION_TIME = this._origToOverviewTime; + imports.ui.overviewControls.SIDE_CONTROLS_ANIMATION_TIME = this._origToAppDrawerTime; + + // Remove all drag-to-rotate gestures. + this._removeDesktopDragGesture(); + this._removePanelDragGesture(); + this._removeOverviewDragGesture(); + + // Clean up skybox. + if (this._skybox) { + this._skybox.destroy(); + this._skybox = null; + } + + // Clean up the edge-workspace-switching. + global.stage.disconnect(this._stageAllocationID); + + this._pressureBarrier.destroy(); + this._leftBarrier.destroy(); + this._rightBarrier.destroy(); + + this._pressureBarrier = null; + this._leftBarrier = null; + this._rightBarrier = null; + + // Clean up perspective correction. + this._disablePerspectiveCorrection(); + Meta.MonitorManager.get().disconnect(this._monitorsChangedID); + + // Make sure that the settings object is freed. + this._settings = null; + } + + // ----------------------------------------------------------------------- private stuff + + // Calls inhibit_culling on the given actor and recursively on all mapped children. + _inhibitCulling(actor) { + if (actor.mapped) { + actor.inhibit_culling(); + actor._culling_inhibited_by_desktop_cube = true; + actor.get_children().forEach(c => this._inhibitCulling(c)); + } + }; + + // Calls uninhibit_culling on the given actor and recursively on all children. It will + // only call uninhibit_culling() on those actors which were inhibited before. + _uninhibitCulling(actor) { + if (actor._culling_inhibited_by_desktop_cube) { + delete actor._culling_inhibited_by_desktop_cube; + actor.uninhibit_culling(); + actor.get_children().forEach(c => this._uninhibitCulling(c)); + } + }; + + // Returns a value between [0...1] blending between overview (0) and app grid mode (1). + _getAppDrawerMode(workspacesView) { + return workspacesView._fitModeAdjustment.value; + } + + // Returns a value between [0...1] blending between desktop / app drawer mode (0) and + // overview mode (1). + _getOverviewMode(workspacesView) { + return workspacesView._overviewAdjustment.value - + 2 * this._getAppDrawerMode(workspacesView); + } + + // Returns a value between [0...1]. If it's 0, the cube should be unfolded, if it's 1, + // the cube should be drawn like, well, a cube :). + _getCubeMode(workspacesView) { + return 1 - this._getAppDrawerMode(workspacesView) + } + + // Returns the angle between consecutive workspaces. + _getFaceAngle(faceCount) { + + // With this setting, our "cube" only covers 180°, if there are only two workspaces, + // it covers 90°. This prevents the affordance that it could be possible to switch + // from the last ot the first workspace. + if (this._settings.get_boolean('last-first-gap')) { + return (faceCount == 2 ? 90 : 180) / (faceCount - 1); + } + + // Else the "cube" covers 360°. + return 360.0 / faceCount; + } + + // Returns the z-distance from the cube faces to the rotation pivot. + _getCenterDist(workspaceWidth, faceAngle) { + let centerDepth = workspaceWidth / 2; + if (faceAngle < 180) { + centerDepth /= Math.tan(faceAngle * 0.5 * Math.PI / 180); + } + return centerDepth; + } + + // This sorts the given list of children actors (which are supposed to be attached to + // the same parent) by increasing absolute rotation-y angle. This is used for + // depth-sorting, as cube faces which are less rotated, are in front of others. + _depthSortCubeFaces(actors) { + // First create a copy of the actors list and sort it by decreasing rotation angle. + const copy = actors.slice(); + copy.sort((a, b) => { + return Math.abs(b.rotation_angle_y) - Math.abs(a.rotation_angle_y); + }); + + // Then sort the children actors accordingly. + const parent = actors[0].get_parent(); + for (let i = 0; i < copy.length; i++) { + parent.set_child_at_index(copy[i], -1); + } + } + + // This sorts the given list of children actors (which are supposed to be attached to + // the same parent) by increasing orthogonal distance to the camera. To do this, the + // camera position is projected onto the plane defined by the actor and the absolute + // distance from the camera to its projected position is computed. This is used for + // depth-sorting a list of parallel actors. + _depthSortWindowActors(actors, monitorIndex) { + + // Sanity check. + if (actors.length <= 1) { + return; + } + + // First, compute distance of virtual camera to the front workspace plane. + const camera = new Graphene.Point3D({ + x: global.stage.width / 2, + y: global.stage.height / 2, + z: global.stage.height / + (2 * Math.tan(global.stage.perspective.fovy / 2 * Math.PI / 180)) + }); + + // All actors are expected to share the same parent. + const parent = actors[0].get_parent(); + + // If the perspective is corrected for multi-monitor setups, the virtual camera is not + // in the middle of the stage but rather in front of each monitor. + if (this._enablePerMonitorPerspective) { + + let monitor; + + if (Meta.is_wayland_compositor()) { + + // On Wayland, each monitor should have its own StageView. Therefore, the virtual + // camera has been positioned in front of each monitor separately. + monitor = global.display.get_monitor_geometry(monitorIndex); + + } else { + + // On X11, there's only one StageView. We move the virtual camera so that it is in + // front of the primary monitor. + monitor = + global.display.get_monitor_geometry(global.display.get_primary_monitor()); + } + + camera.x = monitor.x + monitor.width / 2; + camera.y = monitor.y + monitor.height / 2; + } + + // Create a list of the orthogonal distances to the camera for each actor. + const distances = actors.map((a, i) => { + // A point on the actor plane. + const onActor = a.apply_relative_transform_to_point( + null, new Graphene.Point3D({x: 0, y: 0, z: 0})); + + // A point one unit above the actor plane. + const aboveActor = a.apply_relative_transform_to_point( + null, new Graphene.Point3D({x: 0, y: 0, z: 1000})); + + // The normal vector on the actor plane. + const normal = new Graphene.Point3D({ + x: aboveActor.x - onActor.x, + y: aboveActor.y - onActor.y, + z: aboveActor.z - onActor.z, + }); + + const length = + Math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z); + normal.x /= length; + normal.y /= length; + normal.z /= length; + + onActor.x -= camera.x; + onActor.y -= camera.y; + onActor.z -= camera.z; + + // Return the length of the projected vector. + return { + index: i, + distance: onActor.x * normal.x + onActor.y * normal.y + onActor.z * normal.z + }; + }); + + // Sort by decreasing distance. + distances.sort((a, b) => { + return Math.abs(b.distance) - Math.abs(a.distance); + }); + + // Then use this to create a sorted list of actors. + const copy = distances.map(e => { + return actors[e.index]; + }); + + // Finally, sort the children actors accordingly. + for (let i = 0; i < copy.length; i++) { + parent.set_child_at_index(copy[i], -1); + } + } + + // During rotations, the cube is scaled down and the windows are "exploded". If we + // are directly facing a cube side, the strengths of both effects are approaching + // zero. The strengths of both effects are small during horizontal rotations to make + // workspace-switching not so obtrusive. However, during vertical rotations, the + // effects are stronger. + // This method returns two values: + // result[0]: A translation value by which the cube should be moved backwards. + // result[1]: A translation value by which windows may be moved away from the cube. + _getExplodeFactors(hRotation, vRotation, centerDepth, monitorIndex) { + + // These are zero if we are facing a workspace and one if we look directly at an + // edge between adjacent workspaces or if the cube is rotated vertically + // respectively. + const hFactor = 1.0 - 2.0 * Math.abs(hRotation % 1 - 0.5); + const vFactor = Math.abs(vRotation); + + // For horizontal rotations, we want to scale the cube (or rather move it backwards) + // a tiny bit to reveal a bit of parallax. However, if we have many cube sides, this + // looks weird, so we reduce the effect there. We use the offset which would make + // the cube's corners stay behind the original workspace faces during he rotation. + const monitor = global.display.get_monitor_geometry(monitorIndex); + const cornerDist = + Math.sqrt(Math.pow(centerDepth, 2) + Math.pow(monitor.width / 2, 2)); + const hDepthOffset = + this._settings.get_double('window-parallax') * (cornerDist - centerDepth); + + // The explode factor is set to the hDepthOffset value to make the front-most + // window stay at a constant depth. + const hExplode = hDepthOffset; + + // For vertical rotations, we move the cube backwards to reveal everything. The + // maximum explode width is set to half of the workspace size. + const vExplode = this._settings.get_boolean('do-explode') ? + Math.max(monitor.width, monitor.height) / 2 : + 0; + const diameter = 2 * (vExplode + centerDepth); + const camDist = + monitor.height / (2 * Math.tan(global.stage.perspective.fovy / 2 * Math.PI / 180)); + const vDepthOffset = + (1 + PADDING_V_ROTATION) * diameter * camDist / monitor.width - centerDepth; + + // Use current maximum of both values. + const depthOffset = Math.max(hFactor * hDepthOffset, vFactor * vDepthOffset); + const explode = Math.max(hFactor * hExplode, vFactor * vExplode); + + // Do not explode the cube in app drawer state. The stateAdjustment is... + // ... 0 on the desktop + // ... 1 in the window picker + // ... 2 in the app drawer + const windowPickerFactor = + Math.min(1.0, 2.0 - Main.overview._overview.controls._stateAdjustment.value); + + return [depthOffset * windowPickerFactor, explode * windowPickerFactor]; + } + + // Usually, GNOME Shell uses one central perspective for all monitors combined. This + // results in a somewhat sheared appearance of the cube on multi-monitor setups where + // the primary monitor is not in the middle (or cubes are shown on multiple monitors). + // With the code below, we modify the projection and view matrices for each monitor so + // that each monitor uses its own central perspective. This seems to be possible on + // Wayland only. On X11, there's only one set of projection and view matrices for all + // monitors combined, so we tweak them so that the projection center is in the middle of + // the primary monitor. So it will at least only look bad on X11 if the cube is shown on + // all monitors... + _enablePerspectiveCorrection() { + + this._stageBeforeUpdateID = global.stage.connect('before-update', (stage, view) => { + // Do nothing if neither overview or desktop switcher are shown. + if (!Main.overview.visible && Main.wm._workspaceAnimation._switchData == null) { + return; + } + + // Usually, the virtual camera is positioned centered in front of the stage. We will + // move the virtual camera around. These variables will be the new stage-relative + // coordinates of the virtual camera. + let cameraX, cameraY; + + if (Meta.is_wayland_compositor()) { + + // On Wayland, each monitor has its own StageView. Therefore we can move the + // virtual camera for each monitor separately. + cameraX = view.layout.x + view.layout.width / 2; + cameraY = view.layout.y + view.layout.height / 2; + + } else { + + // On X11, there's only one StageView. We move the virtual camera so that it is in + // front of the primary monitor. + const primaryMonitorRect = + global.display.get_monitor_geometry(global.display.get_primary_monitor()); + + cameraX = primaryMonitorRect.x + primaryMonitorRect.width / 2; + cameraY = primaryMonitorRect.y + primaryMonitorRect.height / 2; + } + + // This is the offset to the original, centered camera position. Y is flipped due to + // some negative scaling at some point in Mutter. + const camOffsetX = stage.width / 2 - cameraX; + const camOffsetY = cameraY - stage.height / 2; + + const z_near = stage.perspective.z_near; + const z_far = stage.perspective.z_far; + + // The code below is copied from Mutter's Clutter. + // https://gitlab.gnome.org/GNOME/mutter/-/blob/main/clutter/clutter/clutter-stage.c#L2255 + const A = 0.57735025882720947265625; + const B = 0.866025388240814208984375; + const C = 0.86162912845611572265625; + const D = 0.00872653536498546600341796875; + + const z_2d = z_near * A * B * C / D + z_near; + + // The code below is copied from Mutter's Clutter as well. + // https://gitlab.gnome.org/GNOME/mutter/-/blob/main/clutter/clutter/clutter-stage.c#L2270 + const top = z_near * Math.tan(stage.perspective.fovy * Math.PI / 360.0); + const left = -top * stage.perspective.aspect; + const right = top * stage.perspective.aspect; + const bottom = -top; + + const left_2d_plane = left / z_near * z_2d; + const right_2d_plane = right / z_near * z_2d; + const bottom_2d_plane = bottom / z_near * z_2d; + const top_2d_plane = top / z_near * z_2d; + + const width_2d_start = right_2d_plane - left_2d_plane; + const height_2d_start = top_2d_plane - bottom_2d_plane; + + const width_scale = width_2d_start / stage.width; + const height_scale = height_2d_start / stage.height; + // End of the copy-paste code. + + // Compute the required offset of the frustum planes at the near plane. This + // basically updates the projection matrix according to our new camera position. + const offsetX = camOffsetX * width_scale / z_2d * z_near; + const offsetY = camOffsetY * height_scale / z_2d * z_near; + + // Set the new frustum. + view.get_framebuffer().frustum(left + offsetX, right + offsetX, bottom + offsetY, + top + offsetY, z_near, z_far); + + // Translate the virtual camera. This basically updates the view matrix according to + // our new camera position. + view.get_framebuffer().push_matrix(); + view.get_framebuffer().translate(camOffsetX * width_scale, + camOffsetY * height_scale, 0); + + // If the perspective of each monitor is computed separately, the culling of GNOME + // Shell does not work anymore as it still uses the original frustum. The only + // workaround is to disable culling altogether. This will be bad performance-wise, + // but I do not see an alternative. + // If the overview is shown, we inhibit culling for the WorkspacesDisplay. If the + // desktop-workspace-switcher is shown, we inhibit culling for all shown monitor + // groups. + if (Main.overview.visible) { + this._inhibitCulling(Main.overview._overview.controls._workspacesDisplay); + } else if (Main.wm._workspaceAnimation._switchData) { + Main.wm._workspaceAnimation._switchData.monitors.forEach(m => { + this._inhibitCulling(m); + }); + } + }); + + // Revert the matrix changes before the update, + this._stageAfterUpdateID = global.stage.connect('after-update', (stage, view) => { + // Nothing to do if neither overview or desktop switcher are shown. + if (!Main.overview.visible && Main.wm._workspaceAnimation._switchData == null) { + return; + } + + view.get_framebuffer().pop_matrix(); + view.get_framebuffer().perspective(stage.perspective.fovy, stage.perspective.aspect, + stage.perspective.z_near, + stage.perspective.z_far); + + // Re-enable culling for all relevant actors. + if (Main.overview.visible) { + this._uninhibitCulling(Main.overview._overview.controls._workspacesDisplay); + } else if (Main.wm._workspaceAnimation._switchData) { + Main.wm._workspaceAnimation._switchData.monitors.forEach(m => { + this._uninhibitCulling(m); + }); + } + }); + } + + // Reverts the changes done with the method above. + _disablePerspectiveCorrection() { + + if (this._stageBeforeUpdateID) { + global.stage.disconnect(this._stageBeforeUpdateID); + this._stageBeforeUpdateID = 0; + } + + if (this._stageAfterUpdateID) { + global.stage.disconnect(this._stageAfterUpdateID); + this._stageAfterUpdateID = 0; + } + } + + // This creates a custom drag gesture and adds it to the given SwipeTracker. The swipe + // tracker will now also respond to horizontal drags. The additional gesture also + // reports vertical drag movements via the "pitch" property. This method returns an + // object containing the gesture, an St.Adjustment which will contain this pitch value, + // and a connection ID which is used by _removeDragGesture() to clean up. When the + // SwipeTracker's gesture ends, the St.Adjustment's value will be eased to zero. + _addDragGesture(actor, tracker, mode) { + const gesture = new DragGesture(actor, mode); + gesture.connect('begin', tracker._beginGesture.bind(tracker)); + gesture.connect('update', tracker._updateGesture.bind(tracker)); + gesture.connect('end', tracker._endTouchGesture.bind(tracker)); + tracker.bind_property('distance', gesture, 'distance', + GObject.BindingFlags.SYNC_CREATE); + + // Update the gesture's sensitivity when the corresponding settings value changes. + this._settings.bind('mouse-rotation-speed', gesture, 'sensitivity', + Gio.SettingsBindFlags.GET); + + // Connect the gesture's pitch property to the pitch adjustment. + gesture.bind_property('pitch', this._pitch, 'value', 0); + + // Ease the pitch adjustment to zero if the SwipeTracker reports an ended gesture. + // This ensures that the cube smoothly rotates back when released. The end-signal + // returns a suitable duration for this, however this depends on the horizontal + // rotation required to move the cube back. Here, we compute a duration required for + // the vertical rotation and use the maximum of both values for the final easing. + const gestureEndID = tracker.connect('end', (g, duration) => { + this._pitch.remove_transition('value'); + this._pitch.ease(0, { + duration: Math.max(500 * Math.abs(this._pitch.value), duration), + mode: Clutter.AnimationMode.EASE_OUT_CUBIC, + }); + }); + + // We return all things which are required to remove the gesture again. This can be + // done with the _removeDragGesture() method below. + return { + actor: actor, + tracker: tracker, + gesture: gesture, + trackerConnection: gestureEndID + }; + } + + // Removes a single-click drag gesture created earlier via _addDragGesture(). The info + // parameter should be the object returned by _addDragGesture(). + _removeDragGesture(info) { + info.gesture.destroy(); + info.tracker.disconnect(info.trackerConnection); + } + + // Calls _addDragGesture() for the SwipeTracker and actor responsible for + // workspace-switching in desktop mode when dragging on the background. + _addDesktopDragGesture() { + // The SwipeTracker for switching workspaces in desktop mode is created here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspaceAnimation.js#L285 + const tracker = Main.wm._workspaceAnimation._swipeTracker; + let actor = Main.layoutManager._backgroundGroup; + const mode = Shell.ActionMode.NORMAL; + + // If not in the overview, you can usually only swipe to adjacent workspaces. This + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/swipeTracker.js#L633 + // allows us to override this behavior. + tracker.allowLongSwipes = true; + + // We have to make the background reactive. Make sure to store the current state so + // that we can reset it later. + this._origBackgroundReactivity = actor.reactive; + actor.reactive = true; + + this._desktopDragGesture = this._addDragGesture(actor, tracker, mode); + } + + // Calls _addDragGesture() for the SwipeTracker and actor responsible for + // workspace-switching in desktop mode when dragging on the panel. + _addPanelDragGesture() { + // The SwipeTracker for switching workspaces in desktop mode is created here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspaceAnimation.js#L285 + const tracker = Main.wm._workspaceAnimation._swipeTracker; + const actor = Main.panel; + const mode = Shell.ActionMode.NORMAL; + + // If not in the overview, you can usually only swipe to adjacent workspaces. This + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/swipeTracker.js#L633 + // allows us to override this behavior. + tracker.allowLongSwipes = true; + + // We have to prevent moving fullscreen windows when dragging. + this._origPanelTryDragWindow = actor._tryDragWindow; + actor._tryDragWindow = () => Clutter.EVENT_PROPAGATE; + + this._panelDragGesture = this._addDragGesture(actor, tracker, mode); + } + + // Calls _addDragGesture() for the SwipeTracker and actor responsible for + // workspace-switching in overview mode. + _addOverviewDragGesture() { + // The SwipeTracker for switching workspaces in overview mode is created here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspacesView.js#L827 + const tracker = Main.overview._overview._controls._workspacesDisplay._swipeTracker; + const actor = Main.layoutManager.overviewGroup; + const mode = Shell.ActionMode.OVERVIEW; + + this._overviewDragGesture = this._addDragGesture(actor, tracker, mode); + } + + // Calls _removeDragGesture() for the SwipeTracker and actor responsible for + // workspace-switching in desktop mode when dragging on the background. + _removeDesktopDragGesture() { + if (this._desktopDragGesture) { + + // Restore original behavior. + this._desktopDragGesture.tracker.allowLongSwipes = false; + + // Make sure to restore the original state. + this._desktopDragGesture.actor.reactive = this._origBackgroundReactivity; + + this._removeDragGesture(this._desktopDragGesture); + + delete this._desktopDragGesture; + } + } + + // Calls _removeDragGesture() for the SwipeTracker and actor responsible for + // workspace-switching in desktop mode when dragging on the panel. + _removePanelDragGesture() { + if (this._panelDragGesture) { + + // Restore original behavior. + this._panelDragGesture.tracker.allowLongSwipes = false; + + // Make sure to restore the original state. + this._panelDragGesture.actor._tryDragWindow = this._origPanelTryDragWindow; + + this._removeDragGesture(this._panelDragGesture); + + delete this._panelDragGesture; + } + } + + // Calls _removeDragGesture() for the SwipeTracker and actor responsible for + // workspace-switching in overview mode. + _removeOverviewDragGesture() { + if (this._overviewDragGesture) { + this._removeDragGesture(this._overviewDragGesture); + + delete this._overviewDragGesture; + } + } +} + +// This function is called once when the extension is loaded, not enabled. +function init() { + return new Extension(); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/ar/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/ar/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..d1ad668a1fafce7ae1889a873116f58ca8d70fae GIT binary patch literal 5544 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/es/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/es/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..11d681fd2b1183bfd0957ea0d260041ea32c5974 GIT binary patch literal 4757 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/gl/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/gl/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..7f872c1ec01d04981b3ae5720fd86b02e5f2c869 GIT binary patch literal 4648 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/it/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/it/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..1a5587d1ff4f37e1aeabc5cf1e6402e4ec28e396 GIT binary patch literal 4395 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 jeYsbXmZ`{t!w1L>0 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/nb_NO/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/nb_NO/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..a75b00da189063b528162d5336defb1bf33b6110 GIT binary patch literal 2827 zcma)-%a0UA9LGz<*MOq^G@rh`F`@wfX_LqUrg4aOy_YL?WcoSs1TOik`f}q%c06qyez^A|qAlIV{a=xE{ zN5Jnu&i8Nd5V)&S#`6xy{pf%-@G1xw;(L(m`6IX&{0(G(e}dd%lwBaDqQ?CDE?g*K z;e-3gi}QFM*UPx@S+Sn(llSC0aE=@|_l)boi}U4L^5R%HzrlI|H+_q;epUQggc zYNK_sX>u=phh&3X;!PIJ=1mea*61rFS2LrXu};jUs+Gu4M>4WuT-ZmYz4S&}<3mry zuPy%iF4m?;wx?+Qf0}2Zru1&M{V3&9<`rTS4Wr>&%w5h>6Om;1(r5{9UbVus46U%7 z4>Q>$zfPoO8aiKO(^eLD>&7N73tJ@SNt4BAgYD-{8jY%O+E{hPXb%JDE%{bQ=~$Zf zDDx%kqWlK`rgYfysz;;Uo!Iu8OMbh7SQ=Dm;D4C|9d==bGGh_AoXKOcLXOZmBO_{u zdFo{^Omh+|q8ArA#eHIQdO*$J58`j?nurrE-lQ-)efcU z0XOad#wtaaqo~$8%1P1=J2~tfdbwe8*$TCEG&&U6$0?i{*|w%zgn%3Et76TD+9~d) z^r}n49u1q~&Jv2d@VV3b(UPmUQ4^lo$=lGb;c0wIfYGOPh zI(gc3DGOr~=aoh=WftO?q~T>r?KZW%ShnU87@UcMb7UQ|sgF%mrR-g>;9?a8=${ML zOkGx%mx2}Q!G+O51K#U$YGP_Cn3xJC56Q`?`r)aA6Ihk^a1er`REW{ox;zQ*S}qzJ zb+$G)7%mM2`vus^apFFf+Hh4J`ioP!JKZH2oqM9N1Do4meU+H4^A1| zb?}xIk8XPEs4Q=%wcIx?Cy!Px1mzePbvj?BBM(<6CxeK36|vMU1@RNS9d5Z4;%%ShO)cTi01f$dXKuzaF>dL*-P06#v_{khObkx;pggl-ACxG)3-+ z4HAdHb5JOjI9tX5g^MupT0@3>86B*}0w&gUdBVEI9cB(q<;2=sn~*waj%|{P9E`TE zM}5JADM7EcJDtzdbX$GS4Lq^#B?-%3*y~rLfgh-+sYoBHmlUcu?gv?Hw<>HPWaF{0 z`f(+1%YRKpsX`%0j{0>5iDQDHhA0SEo>VHL`!)o#WAjSYArD)L6@uKzBi%T~&#HZWNa1s3Qkd|V1 zhxy=rVT`GdZP;~5-foZVF{qx!5ao_64uFF=#$tw$Q6f8+sM{qLcnupJ<$ZljFlDTe Hi5LF@8Pz`d literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/nl/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/nl/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..76ace2264f9c9e39240ea9306f44c8beccb5059b GIT binary patch literal 4859 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/sk/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/sk/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..79cfaca2e77ccee963b21a219d8305bf421c10d2 GIT binary patch literal 4488 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 Pl^|@CS-f#xk^FxH^3sr* literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/tr/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/tr/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..c4d9baf7d05a2115f72cbb8ff408224fab08a2fd GIT binary patch literal 4641 zcmbVOO^h5z6)qeD@q+nDAp9lp41~n7dv?8>SoYc*GHb8bA+dM0yV%6Uhnne{nM!w8 zb*ig(-2(!|0UwZZ03{Nqy#y^>kXJ%E?TMKcQZ7j3fCPdA2yx&9%8>)#>z<$WdQBo) z)ALPFzp8pa-}|cm^3dVe1+J%XKZ-m4fDq?^JBRRv>lY6Q@gd+ZfsX+103Qba7Wi@C zp9b&$2@LT3Z(t2bhlMx+TmrJ)cYr+4kAdfbKLO4Ge+Oi{qaPIF%fPe1Q^1#jUjn`c z{3`HQK%VCv;8Eb;fX9IU0)7$rFeYdFY2YV-D?qku0zV3T70CX75BN0jb>MN}+rWH-V1;8$b_a zyFUOqKMx`aoX@9#Jm1TM=br-c5xe;MB=8*|`}23;H1Iz_j(ZZpeI9rn$aQx>uEURj zj{)BRE&+cH5pj5s>5kG;Y3_OYAqyN7tdjFSuIzIDGNh!4H(G%mqI_ zg!^;2;bxg{q@&~s_X%I@Bd9CBzz>59)GsfjzPvbpoFk5(ug~CSu6_kK$HwvU#eD}l zm3;gfkonFR^O>(F%de}}sNDSQFKvdk+*4ZA#W%#FPl-@+1!MbN@JZ&q?mWs zbQP_p)@0UY;(|0y6^je8Zbl?w89Lc6rwXg7$XjyOORvg*n>_IW)^=UFb*(nur#bvl z@j*j8j)`<=};v~PB3!@4L-Wm92}_ZYm_ z_j^Y#7}&v2ZJmZ3tsziL46p7OyT{S)kR9isL7;yWPS-9V57LENfgoWiqS}s&=Fwl{aH&;36j!^JFM- zMlENP@?ZQgz9!b3G?`{zkk@c;Sov|X>Dx(m^B%i$o;^J~BK7^PMVr7jOOe~Q;<$zOdW-q z5O+XBq5Mb?%A1`eOo;mBU?kc`(#+|p-`p8V7Wh`?N4=VBhq>WM9!p25v#)R;T2rGs zwXF?N&)hYuw#;&L(opp>LP=5^7ah5-Os#2?$xi5WR-<`ET&R+5U{Y*lSS|*Js31X7 zR7l@gURdN#&bWV%4MQ^)PFGShDq-1uNG2C~UjuR$He>;!EmwXA&xgUaYSP)eWP74& zhTuxp)?t8#$bvN}!Nl@Xu%gzHeQSb?D9kKPPfbq;Q)h#z8JeD%J$2^96t0OE(OE&s zB9za%S@e{X5iPl9ZfNPo3-$RI>sRS~!}1@t8$sQqd9IyE9dl-$#RSMO$`!0Bnat8! z?joIa=zPcfG@G5A?AXk!u(qKv(5sqt?a4tcvdIAf1E%<7(>gWj-Q;-6S@Le;%JWwi z#-X38O-)Nz2DKuRA#N%HcZS(lE>c}R*wQ1fTbh)Qw24(2&Zq!7QUw*L z9^wgAfe27}5B7_CZ>zr@#W-12bDpF|UhUmQj?J5NH&%se=os6vHo99A^U(I)O&yVC z0`<1;%_%`kvyy0$riR_!jPppWmZu5Qar7QzMkAQv@vxSn9(zo=m!1{73>DJLg7Pk6 zz^bCod4O|?EbikUYHrA;G6EZz9)ltKLV?kKyUL@*5p9RgVTwi7+e(m^y$;T6ho18| z6zDkAPF#Z&$fCc^d1KCjUj&a^{cW&S%*<1Rn<~-6#z0raYTRp4)r3VJG5ruWg&^|o zW=Zj~x;VJ?wji-i8`Md5VWrc&w^cHIz!~&!e=|`A&5L(XP>J4SS*YQtnqksaL?ZSa z82U z*c~{$cbl^h)hz`@CxkSZm@{7L93D%>D+?>?28va*m=SbCL$YvagVrur%0rSnGlTwu z+04`kM-v5Z3*HV>TXF{0Z@R5_3uFI?I1W6q%alkzLf!B{94s)%DtoL2`H$O~`#IG$-2Y9tiI;Bu%0bhL2}!rs94Z8*G8LTT>p-;k9u Oh8|YsLN9d(BKBXH7Xyv} literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/zh_Hans/LC_MESSAGES/desktop-cube.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/locale/zh_Hans/LC_MESSAGES/desktop-cube.mo new file mode 100644 index 0000000000000000000000000000000000000000..3d5b191bafbea319a51d61d987525b085c38cc49 GIT binary patch literal 4119 zcma)-Yit}>6~`~6v|tF2mPZRMy#>-HBo{G)`RbXTfuLEPr!H-+P)6L zWpC4mfd{cU`S%z|@jVT~74{rR`;~*Ve?#{AI7s&IfMoZZ?EODvxe5=-z62y)UIi)6 zec9_#@KId91LDWt!yoON0>1$M2P9orLp+*a1d`ouknCOqDei{sbrjry>%$<`(Ayx{ z{|O9$e*-ySV-@SP8z1MIooB zCHcc~klz#o4cg<&IH(qKBU{p5z6x?TLDGW;QpG;!o%udIhI8`$^EeQOS0@xB4e}kO z%f3Pv*@4pc2Kh~c;(Y=K^$U$J;UG=Fj)Q81;-x`-_Ye-s)6+Pp-f2)h(^%{M?Utrk z$6l#3Pz1Ev->wTPTP(>IIi|cROo0>rODto2AuYN3@{88Xq!wx$pPRt~9k; zL-3$59ZNHKL|Ar21RcFe@H%O6p<%N|Y3h!&SmnNmAww{RN?e*8qBwdGvpfa8fVN|f zW^w^b4WZ%Q2Hqm0Jcygk8hP%7b(=ToAtB578oQ9~&?3B6IL$(sTnoK{kW6QJc*~y~ zn(cULtkW%=wB ze)##-ZMN(&rRHt}R+TG{-2T<%Xub;fh={b{INutrXM2P#P|cEuM4c8j9NwfEQNi}C zEJ7ZQa7c-QFv->qOVl2=-dI5)M1xM$5`}E9K-o%ZI6AETQmKtP4pKw8vt^^;2-Shg zdxe3l^6k1IaPIA2ObbVC!FTMg+EvN-hJ|4~W3O}z6LkZ@EyYqp=@X`n{ZXo6&B>?N zCTHLx35s=Wq}b+lmTdIy;>2_cS&gNcwoY}y9UboFGQT7?f34Ae{T@4Son<|nFX|7r z&YK`iEfS&DZ$>0b6AWs-m#M3_g*CHY7_uIh@Q&|8sN(ra(vSP=P(q9V~Y8sGR_@y}=SuPoG?r;m6u zs#{najzkU3;t@-}L47FALjEGJmokKWMy;UVmUa}KlzZ#h94U!Nqb00039~RL8;imr zOScR8R>3JzUbUf;45@{@%}^mC&!n?lOVO7U78h(o@#DP~sA-8HGDqxlitvKe z&CNU*)-1db%D-2$J+NuXj@qP7Sb<72C_{K#mGMorx>HbXL{W(W)L5fk#?6R#X_uF5 z=Kg7U@#cc>2mH68r_L*WH2m4Z68r)o(Nw_Jx`XG|F?INQa;`V~LGr(->hPpHJgqJq zNX^Aq=J-ge^GN#US=Dt(4ZOuv-%0mY2m5Pluj(04?Qu1G%k4g?x+dN8M>1zdRo}Eb z*qu&XN&T$bJvp099ET;l+jP7wJ<)Nm>3vqklJ1$sdrfIof5%K~XXgAYb9?&JH_tKO zm(=A!)ptR4%=jkhh1t~n5EfA#?QYMgx;>UmjHn}X_gH&=eW10Po^_}DlCjI~&_e3s zoEn}~XWCW&bn3)pGImuh9!yWXm7X}p)Y-Pw=^MTb?%*wTZ9vVp=JjCi!RzVq1F%R> zv?b>-vt+C*8SB2Q zWFQ(O@m1bfk%}L8&mJN@GV|x$bM0>YXnL{TJ<^#uHbsT;(=jOLcD1V86K-EW662Y+ zcDmh{+>`Ce_$`*6T1X|PlCimB)iIn*EFxjcK6WH%&L3~;@mnhd!yd_auY2_ZY7sl3 zs`3(&Mhg?TPxJE1t#?B)e1p7O0y>T9b+E{(MaIZQx;gddwY~PF?Lp^}AgI zDsc_2df&I~tK{?oR$B3Cf<1OmU5n=}NXu9&x=W2E+%seDTtDV;^o8m=uNDuZO45l$ zy7TSy%t3ePoSHd=3G~rQb#}NTSMJOoU~0V0??&>iV>or?ioc*Qc{0`u|5bnQ@|zj2 Oc~IwQHMe(+()d49?nqDo literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/metadata.json b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/metadata.json new file mode 100644 index 0000000..44b7e32 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/metadata.json @@ -0,0 +1,16 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Indulge in nostalgia with useless 3D effects.", + "gettext-domain": "desktop-cube", + "name": "Desktop Cube", + "settings-schema": "org.gnome.shell.extensions.desktop-cube", + "shell-version": [ + "40", + "41", + "42", + "43" + ], + "url": "https://github.com/Schneegans/Desktop-Cube", + "uuid": "desktop-cube@schneegans.github.com", + "version": 13 +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/prefs.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/prefs.js new file mode 100644 index 0000000..135218e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/prefs.js @@ -0,0 +1,263 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ,-. ,--. ,-. , , ,---. ,-. ;-. ,-. . . ,-. ,--. // +// | \ | ( ` | / | / \ | ) / | | | ) | // +// | | |- `-. |< | | | |-' | | | |-< |- // +// | / | . ) | \ | \ / | \ | | | ) | // +// `-' `--' `-' ' ` ' `-' ' `-' `--` `-' `--' // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {Gio, Gtk, Gdk} = imports.gi; +const ByteArray = imports.byteArray; + +// libadwaita is available starting with GNOME Shell 42. +let Adw = null; +try { + Adw = imports.gi.Adw; +} catch (e) { + // Nothing to do. +} + +const _ = imports.gettext.domain('desktop-cube').gettext; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; +const ImageChooserButton = Me.imports.src.ImageChooserButton; + +////////////////////////////////////////////////////////////////////////////////////////// +// For now, the preferences dialog of this extension is very simple. In the future, if // +// we might consider to improve its layout... // +////////////////////////////////////////////////////////////////////////////////////////// + +var PreferencesDialog = class PreferencesDialog { + // ------------------------------------------------------------ constructor / destructor + + constructor() { + // Load all of our resources. + this._resources = Gio.Resource.load(Me.path + '/resources/desktop-cube.gresource'); + Gio.resources_register(this._resources); + + // Register our custom widgets. + ImageChooserButton.registerWidget(); + + // Load the user interface file. + this._builder = new Gtk.Builder(); + this._builder.add_from_resource(`/ui/settings.ui`); + + // Make sure custom icons are found. + Gtk.IconTheme.get_for_display(Gdk.Display.get_default()).add_resource_path('/img'); + + // This is our top-level widget which we will return later. Starting with GNOME Shell + // 42, the preferences window already has a built-in scrolled window. For older + // versions, we have to add this manually. + if (utils.shellVersionIsAtLeast(42)) { + this._widget = this._builder.get_object('settings-widget'); + } else { + this._widget = new Gtk.ScrolledWindow(); + + const box = this._builder.get_object('settings-widget'); + box.margin_start = 30; + box.margin_end = 30; + box.margin_top = 30; + box.margin_bottom = 30; + this._widget.set_child(box); + } + + // Store a reference to the settings object. + this._settings = ExtensionUtils.getSettings(); + + // Bind all properties. + this._bindAdjustment('workpace-separation'); + this._bindAdjustment('horizontal-stretch'); + this._bindAdjustment('window-parallax'); + this._bindImageChooserButton('background-panorama'); + this._bindSwitch('last-first-gap'); + this._bindSwitch('enable-desktop-dragging'); + this._bindSwitch('enable-panel-dragging'); + this._bindSwitch('enable-desktop-edge-switch'); + this._bindSwitch('enable-overview-edge-switch'); + this._bindSwitch('enable-overview-dragging'); + this._bindSwitch('do-explode'); + this._bindSwitch('per-monitor-perspective'); + this._bindAdjustment('active-workpace-opacity'); + this._bindAdjustment('inactive-workpace-opacity'); + this._bindAdjustment('edge-switch-pressure'); + this._bindAdjustment('mouse-rotation-speed'); + this._bindAdjustment('overview-transition-time'); + this._bindAdjustment('appgrid-transition-time'); + this._bindAdjustment('workspace-transition-time'); + + // Inject the video link. + const label = this._builder.get_object('multi-monitor-hint-label'); + label.label = label.label.replace( + '%s', 'https://youtu.be/dpYyn1BXGjU'); + + // Add a menu to the title bar of the preferences dialog. + this._widget.connect('realize', (widget) => { + const window = widget.get_root(); + + // Show the version number in the title bar. + window.title = `Desktop Cube ${Me.metadata.version}`; + + // Add the menu to the title bar + const menu = this._builder.get_object('menu-button'); + + // Starting with GNOME Shell 42, the settings dialog uses libadwaita (at least + // most of the time - it seems that pop!_OS does not support libadwaita even on + // GNOME 42). So we have to hack our way through the widget tree of the + // Adw.PreferencesWindow... + if (Adw && utils.shellVersionIsAtLeast(42)) { + const header = this._findWidgetByType(window.get_content(), Adw.HeaderBar); + header.pack_end(menu); + } else { + window.get_titlebar().pack_end(menu); + } + + // Populate the actions. + const group = Gio.SimpleActionGroup.new(); + + const addAction = (name, uri) => { + const action = Gio.SimpleAction.new(name, null); + action.connect('activate', () => Gtk.show_uri(null, uri, Gdk.CURRENT_TIME)); + group.add_action(action); + }; + + // clang-format off + addAction('homepage', 'https://github.com/Schneegans/Desktop-Cube'); + addAction('changelog', 'https://github.com/Schneegans/Desktop-Cube/blob/main/docs/changelog.md'); + addAction('translate', 'https://hosted.weblate.org/engage/desktop-cube/'); + addAction('bugs', 'https://github.com/Schneegans/Desktop-Cube/issues'); + addAction('donate-paypal', 'https://www.paypal.com/donate/?hosted_button_id=3F7UFL8KLVPXE'); + addAction('donate-github', 'https://github.com/sponsors/Schneegans'); + // clang-format on + + // Add the about dialog. + const aboutAction = Gio.SimpleAction.new('about', null); + aboutAction.connect('activate', () => { + // The JSON report format from weblate is a bit weird. Here we extract all + // unique names from the translation report. + const translators = new Set(); + this._getJSONResource('/credits/translators.json').forEach(i => { + for (const j of Object.values(i)) { + j.forEach(k => translators.add(k[1])); + } + }); + + const sponsors = this._getJSONResource('/credits/sponsors.json'); + + const dialog = new Gtk.AboutDialog({transient_for: window, modal: true}); + dialog.set_logo_icon_name('desktop-cube-symbolic'); + dialog.set_program_name(`Desktop-Cube ${Me.metadata.version}`); + dialog.set_website('https://github.com/Schneegans/Desktop-Cube'); + dialog.set_authors(['Simon Schneegans']); + dialog.set_copyright('© 2022 Simon Schneegans'); + dialog.set_translator_credits([...translators].join('\n')); + if (sponsors.gold.length > 0) { + dialog.add_credit_section(_('Gold Sponsors'), sponsors.gold); + } + if (sponsors.silver.length > 0) { + dialog.add_credit_section(_('Silver Sponsors'), sponsors.silver); + } + if (sponsors.bronze.length > 0) { + dialog.add_credit_section(_('Bronze Sponsors'), sponsors.bronze); + } + if (sponsors.past.length > 0) { + dialog.add_credit_section(_('Past Sponsors'), sponsors.past); + } + dialog.set_license_type(Gtk.License.GPL_3_0); + + dialog.show(); + }); + group.add_action(aboutAction); + + window.insert_action_group('prefs', group); + }); + + + // As we do not have something like a destructor, we just listen for the destroy + // signal of our main widget. + this._widget.connect('destroy', () => { + // Unregister our resources. + Gio.resources_unregister(this._resources); + }); + } + + // -------------------------------------------------------------------- public interface + + // Returns the widget used for the settings of this extension. + getWidget() { + return this._widget; + } + + // ----------------------------------------------------------------------- private stuff + + // Connects a DesktopCubeImageChooserButton (or anything else which has a 'file' + // property) to a settings key. It also binds the corresponding reset button. + _bindImageChooserButton(settingsKey) { + this._bind(settingsKey, 'file'); + } + + // Connects a Gtk.Adjustment (or anything else which has a 'value' property) to a + // settings key. It also binds the corresponding reset button. + _bindAdjustment(settingsKey) { + this._bind(settingsKey, 'value'); + } + + // Connects a Gtk.Switch (or anything else which has an 'active' property) to a settings + // key. It also binds the corresponding reset button. + _bindSwitch(settingsKey) { + this._bind(settingsKey, 'active'); + } + + // Connects any widget's property to a settings key. The widget must have the same ID as + // the settings key. It also binds the corresponding reset button. + _bind(settingsKey, property) { + this._settings.bind(settingsKey, this._builder.get_object(settingsKey), property, + Gio.SettingsBindFlags.DEFAULT); + + const resetButton = this._builder.get_object('reset-' + settingsKey); + resetButton.connect('clicked', () => { + this._settings.reset(settingsKey); + }); + } + + // Reads the contents of a JSON file contained in the global resources archive. The data + // is parsed and returned as a JavaScript object / array. + _getJSONResource(path) { + const data = Gio.resources_lookup_data(path, 0); + const string = ByteArray.toString(ByteArray.fromGBytes(data)); + return JSON.parse(string); + } + + // This traverses the widget tree below the given parent recursively and returns the + // first widget of the given type. + _findWidgetByType(parent, type) { + for (const child of [...parent]) { + if (child instanceof type) return child; + + const match = this._findWidgetByType(child, type); + if (match) return match; + } + + return null; + } +} + +// This is used for setting up the translations. +function init() { + ExtensionUtils.initTranslations(); +} + +// This function is called when the preferences window is created to build and return a +// Gtk widget. We create a new instance of the PreferencesDialog class each time this +// method is called. This way we can actually open multiple settings windows and interact +// with all of them properly. +function buildPrefsWidget() { + var dialog = new PreferencesDialog(); + return dialog.getWidget(); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/resources/desktop-cube.gresource b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/resources/desktop-cube.gresource new file mode 100644 index 0000000000000000000000000000000000000000..d305b402b6cdd99740734c8a95b36d7fc718fb50 GIT binary patch literal 63704 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 +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {Clutter, GObject, Meta, Shell} = imports.gi; + +const Util = imports.misc.util; +const Main = imports.ui.main; +const ControlsState = imports.ui.overviewControls.ControlsState; +const Workspace = imports.ui.workspace.Workspace; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; + +////////////////////////////////////////////////////////////////////////////////////////// +// In GNOME Shell, SwipeTrackers are used all over the place to capture swipe gestures. // +// There's one for entering the overview, one for switching workspaces in desktop mode, // +// one for switching workspaces in overview mode, one for horizontal scrolling in the // +// app drawer, and many more. The ones used for workspace-switching usually do not // +// respond to single-click dragging but only to multi-touch gestures. We want to be // +// able to rotate the cube with the left mouse button, so we add the gesture defined // +// below to these two SwipeTracker instances (this is done by the _addDragGesture() of // +// the extension class). The gesture is loosely based on the gesture defined here: // +// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/swipeTracker.js#L213 // +// It behaves the same in the regard that it reports update events for horizontal // +// movements. However, it stores vertical movements as well and makes this accessible // +// via the "pitch" property. This is then used for vertical rotations of the cube. // +////////////////////////////////////////////////////////////////////////////////////////// + +const State = { + INACTIVE: 0, // The state will change to PENDING as soon as there is a mouse click. + PENDING: 1, // There was a click, but not enough movement to trigger the gesture. + ACTIVE: 2 // The gesture has been triggered and is in progress. +}; + +// clang-format off +var DragGesture = + GObject.registerClass({ + Properties: { + 'distance': GObject.ParamSpec.double( + 'distance', 'distance', 'distance', GObject.ParamFlags.READWRITE, 0, Infinity, 0), + 'pitch': GObject.ParamSpec.double( + 'pitch', 'pitch', 'pitch', GObject.ParamFlags.READWRITE, 0, 1, 0), + 'sensitivity': GObject.ParamSpec.double( + 'sensitivity', 'sensitivity', 'sensitivity', GObject.ParamFlags.READWRITE, 1, 10, 1), + }, + Signals: { + 'begin': {param_types: [GObject.TYPE_UINT, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE]}, + 'update': {param_types: [GObject.TYPE_UINT, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE]}, + 'end': {param_types: [GObject.TYPE_UINT, GObject.TYPE_DOUBLE]}, + }, + }, + class DragGesture extends GObject.Object { + // clang-format on + _init(actor, mode) { + super._init(); + + this._actor = actor; + this._state = State.INACTIVE; + this._mode = mode; + + // We listen to the 'captured-event' to be able to intercept some other actions. The + // main problem is the long-press action of the desktop background actor. This + // swallows any click events preventing us from dragging the desktop background. + // By connecting to 'captured-event', we have to extra-careful to propagate any event + // we are not interested in. + this._actorConnection1 = actor.connect('captured-event', (a, e) => { + return this._handleEvent(e); + }); + + // Once the input is grabbed, events are delivered directly to the actor, so we have + // also to connect to the normal "event" signal. + this._actorConnection2 = actor.connect('event', (a, e) => { + if (this._lastGrab) { + return this._handleEvent(e); + } + return Clutter.EVENT_PROPAGATE; + }); + } + + // Disconnects from the actor. + destroy() { + this._actor.disconnect(this._actorConnection1); + this._actor.disconnect(this._actorConnection2); + } + + // This is called on every captured event. + _handleEvent(event) { + + // Abort if the gesture is not meant for the current action mode (e.g. either + // Shell.ActionMode.OVERVIEW or Shell.ActionMode.NORMAL). + if (this._mode != Main.actionMode) { + return Clutter.EVENT_PROPAGATE; + } + + // In the overview, we only want to switch workspaces by dragging when in + // window-picker state. + if (Main.actionMode == Shell.ActionMode.OVERVIEW) { + if (Main.overview._overview.controls._stateAdjustment.value != + ControlsState.WINDOW_PICKER) { + return Clutter.EVENT_PROPAGATE; + } + } + + // Ignore touch events on X11. On X11, we get emulated pointer events. + if (!Meta.is_wayland_compositor() && + (event.type() == Clutter.EventType.TOUCH_BEGIN || + event.type() == Clutter.EventType.TOUCH_UPDATE || + event.type() == Clutter.EventType.TOUCH_END)) { + return Clutter.EVENT_PROPAGATE; + } + + // When a mouse button is pressed or a touch event starts, we store the corresponding + // position. The gesture is maybe triggered later, if the pointer was moved a little. + if (event.type() == Clutter.EventType.BUTTON_PRESS || + event.type() == Clutter.EventType.TOUCH_BEGIN) { + + // Here's a minor hack: In the overview, there are some draggable things like window + // previews which "compete" with this gesture. Sometimes, the cube is dragged, + // sometimes the window previews. So we make sure that we do only start the gesture + // for events which originate from the given actor or from a workspace's background. + if (Main.actionMode != Shell.ActionMode.OVERVIEW || + event.get_source() == this._actor || + event.get_source().get_parent() instanceof Workspace) { + this._clickPos = event.get_coords(); + this._state = State.PENDING; + } + + return Clutter.EVENT_PROPAGATE; + } + + // Abort the pending state if the pointer leaves the actor. + if (event.type() == Clutter.EventType.LEAVE && this._state == State.PENDING) { + this._cancel(); + return Clutter.EVENT_PROPAGATE; + } + + // As soon as the pointer is moved a bit, the drag action becomes active. + if (this._eventIsMotion(event)) { + + // If the mouse button is not pressed, we are not interested in the event. + if (this._state != State.INACTIVE && event.type() == Clutter.EventType.MOTION && + (event.get_state() & Clutter.ModifierType.BUTTON1_MASK) == 0) { + + this._cancel(); + return Clutter.EVENT_PROPAGATE; + } + + const currentPos = event.get_coords(); + + // If we are in the pending state, the gesture may be triggered as soon as the + // pointer is moved enough. + if (this._state == State.PENDING) { + + const threshold = Clutter.Settings.get_default().dnd_drag_threshold; + + if (Math.abs(currentPos[0] - this._clickPos[0]) > threshold || + Math.abs(currentPos[1] - this._clickPos[1]) > threshold) { + + + // When starting a drag in desktop mode, we grab the input so that we can move + // the pointer across windows without loosing the input events. + if (Main.actionMode == Shell.ActionMode.NORMAL) { + const sequence = event.type() == Clutter.EventType.TOUCH_UPDATE ? + event.get_event_sequence() : + null; + + if (!this._grab(event.get_device(), sequence)) { + return Clutter.EVENT_PROPAGATE; + } + } + + this._state = State.ACTIVE; + [this._lastX, this._startY] = currentPos; + this.pitch = 0; + this.emit('begin', event.get_time(), currentPos[0], currentPos[1]); + } + + // Even if the gesture started, we propagate the event so that any other + // gestures may wait for long-presses are canceled properly. + return Clutter.EVENT_PROPAGATE; + } + + // In the active state, we report updates on each movement. + if (this._state == State.ACTIVE) { + + // Compute the horizontal movement relative to the last call. + let deltaX = currentPos[0] - this._lastX; + this._lastX = currentPos[0]; + + // Compute the accumulated pitch relative to the screen height. + this.pitch = (this._startY - currentPos[1]) / global.screen_height; + + // Increase sensitivity. + deltaX *= this.sensitivity; + + // Increase horizontal movement if the cube is rotated vertically. + deltaX *= Util.lerp(1.0, global.workspaceManager.get_n_workspaces(), + Math.abs(this.pitch)); + + this.emit('update', event.get_time(), -deltaX, this.distance); + + return Clutter.EVENT_STOP; + } + + return Clutter.EVENT_PROPAGATE; + } + + // As soon as the mouse button is released or the touch event ends, we quit the + // gesture. + if (this._eventIsRelease(event)) { + + // If the gesture was active, report an end event. + if (this._state == State.ACTIVE) { + + this._cancel(); + + this.emit('end', event.get_time(), this.distance); + + return Clutter.EVENT_STOP; + } + + // If the gesture was in pending state, set it to inactive again. + this._cancel(); + + return Clutter.EVENT_PROPAGATE; + } + + return Clutter.EVENT_PROPAGATE; + } + + // This aborts any ongoing grab and resets the current state to inactive. + _cancel() { + if (this._lastGrab) { + this._ungrab(); + } + + this._state = State.INACTIVE; + } + + // Makes sure that all events from the pointing device we received last input from is + // passed to the given actor. This is used to ensure that we do not "loose" the touch + // buttons will dragging them around. + _grab(device, sequence) { + + // On GNOME Shell 42, there's a new API. + if (utils.shellVersionIsAtLeast(42)) { + this._lastGrab = global.stage.grab(this._actor); + return this._lastGrab != null; + } + + // Before, we needed to grab the device and enter modal mode. + if (global.begin_modal(0, 0)) { + if (sequence) { + device.sequence_grab(sequence, this._actor); + this._grabbedSequence = sequence; + } else { + device.grab(this._actor); + } + this._lastGrab = device; + return true; + } + + return false; + } + + // Releases a grab created with the method above. + _ungrab() { + if (utils.shellVersionIsAtLeast(42)) { + this._lastGrab.dismiss(); + } else { + if (this._grabbedSequence) { + this._lastGrab.sequence_ungrab(this._grabbedSequence); + this._grabbedSequence = null; + } else { + this._lastGrab.ungrab(); + } + global.end_modal(0); + } + this._lastGrab = null; + } + + // This is borrowed from here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/dnd.js#L214 + _eventIsRelease(event) { + if (event.type() == Clutter.EventType.BUTTON_RELEASE) { + const buttonMask = Clutter.ModifierType.BUTTON1_MASK | + Clutter.ModifierType.BUTTON2_MASK | Clutter.ModifierType.BUTTON3_MASK; + // We only obey the last button release from the device, other buttons may get + // pressed / released during the drag. + return (event.get_state() & buttonMask) == 0; + } else if (event.type() == Clutter.EventType.TOUCH_END) { + // For touch, we only obey the pointer emulating sequence. + return global.display.is_pointer_emulating_sequence(event.get_event_sequence()); + } + + return false; + } + + // This is borrowed from here: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/dnd.js#L259 + _eventIsMotion(event) { + return event.type() == Clutter.EventType.MOTION || + (event.type() == Clutter.EventType.TOUCH_UPDATE && + global.display.is_pointer_emulating_sequence(event.get_event_sequence())); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/ImageChooserButton.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/ImageChooserButton.js new file mode 100644 index 0000000..19aaec0 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/ImageChooserButton.js @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ,-. ,--. ,-. , , ,---. ,-. ;-. ,-. . . ,-. ,--. // +// | \ | ( ` | / | / \ | ) / | | | ) | // +// | | |- `-. |< | | | |-' | | | |-< |- // +// | / | . ) | \ | \ / | \ | | | ) | // +// `-' `--' `-' ' ` ' `-' ' `-' `--` `-' `--' // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {GObject, Gtk, Gio} = imports.gi; + +const _ = imports.gettext.domain('desktop-cube').gettext; + +////////////////////////////////////////////////////////////////////////////////////////// +// This is based on a similar class from the Fly-Pie extension (MIT License). // +// https://github.com/Schneegans/Fly-Pie/blob/main/src/prefs/ImageChooserButton.js // +// We only need file chooser buttons for images, so the content. // +////////////////////////////////////////////////////////////////////////////////////////// + +function registerWidget() { + + if (GObject.type_from_name('DesktopCubeImageChooserButton') == null) { + GObject.registerClass( + { + GTypeName: 'DesktopCubeImageChooserButton', + Template: `resource:///ui/imageChooserButton.ui`, + InternalChildren: ['button', 'label'], + Properties: { + 'file': GObject.ParamSpec.string('file', 'file', 'file', + GObject.ParamFlags.READWRITE, ''), + }, + }, + class DesktopCubeImageChooserButton extends Gtk.Box { // -------------------------- + _init(params = {}) { + super._init(params); + + this._dialog = new Gtk.Dialog({use_header_bar: true, modal: true, title: ''}); + this._dialog.add_button(_('Select File'), Gtk.ResponseType.OK); + this._dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL); + this._dialog.set_default_response(Gtk.ResponseType.OK); + + const fileFilter = new Gtk.FileFilter(); + fileFilter.add_mime_type('image/*'); + + this._fileChooser = new Gtk.FileChooserWidget({ + action: Gtk.FileChooserAction.OPEN, + hexpand: true, + vexpand: true, + height_request: 500, + filter: fileFilter + }); + + this._dialog.get_content_area().append(this._fileChooser); + + this._dialog.connect('response', (dialog, id) => { + if (id == Gtk.ResponseType.OK) { + this.file = this._fileChooser.get_file().get_path(); + } + dialog.hide(); + }); + + this._button.connect('clicked', (button) => { + this._dialog.set_transient_for(button.get_root()); + + this._dialog.show(); + + if (this._file != null) { + this._fileChooser.set_file(this._file); + } + }); + } + + // Returns the currently selected file. + get file() { + return this._file.get_path(); + } + + // This makes the file chooser dialog preselect the given file. + set file(value) { + this._file = Gio.File.new_for_path(value); + + if (this._file.query_exists(null)) { + this._label.label = this._file.get_basename(); + } else { + this._label.label = _('(None)'); + this._file = null; + } + + this.notify('file'); + } + }); + } +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/Skybox.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/Skybox.js new file mode 100644 index 0000000..2f78619 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/Skybox.js @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ,-. ,--. ,-. , , ,---. ,-. ;-. ,-. . . ,-. ,--. // +// | \ | ( ` | / | / \ | ) / | | | ) | // +// | | |- `-. |< | | | |-' | | | |-< |- // +// | / | . ) | \ | \ / | \ | | | ) | // +// `-' `--' `-' ' ` ' `-' ' `-' `--` `-' `--' // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {Clutter, GObject, GdkPixbuf, Cogl, Shell} = imports.gi; + +const Main = imports.ui.main; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; + +////////////////////////////////////////////////////////////////////////////////////////// +// This file contains two classes, the Skybox (which is an actor) and the SkyboxEffect, // +// which is a Shell.GLSLEffect which is applied to the Skybox actor. // +// // +// SkyboxEffect loads a given texture and interprets it as a 360° panorama in // +// equirectangular projection. It uses the current perspective of the stage to draw a // +// perspectively correct portion of this panorama. It has an additional pitch and yaw // +// parameter controlling the horizontal and vertical rotation of the camera. // +////////////////////////////////////////////////////////////////////////////////////////// + +// clang-format off +var SkyboxEffect = GObject.registerClass({ + Properties: { + 'yaw': GObject.ParamSpec.double('yaw', 'yaw', 'yaw', GObject.ParamFlags.READWRITE, + -2 * Math.PI, 2 * Math.PI, 0), + 'pitch': GObject.ParamSpec.double('pitch', 'pitch', 'pitch', GObject.ParamFlags.READWRITE, + -0.5 * Math.PI, 0.5 * Math.PI, 0), + }, + }, class SkyboxEffect extends Shell.GLSLEffect { + // clang-format on + _init(file) { + super._init(); + + const FORMATS = [ + Cogl.PixelFormat.G_8, + Cogl.PixelFormat.RG_88, + Cogl.PixelFormat.RGB_888, + Cogl.PixelFormat.RGBA_8888, + ]; + + // Attempt to load the texture. + const textureData = GdkPixbuf.Pixbuf.new_from_file(file); + this._texture = new Clutter.Image(); + this._texture.set_data(textureData.get_pixels(), + FORMATS[textureData.get_n_channels() - 1], textureData.width, + textureData.height, textureData.rowstride); + + // Redraw if either the pitch or the yaw changes. + this.connect('notify::yaw', () => {this.queue_repaint()}); + this.connect('notify::pitch', () => {this.queue_repaint()}); + }; + + // This is called once to setup the Cogl.Pipeline. + vfunc_build_pipeline() { + + // In the vertex shader, we compute the view space position of the actor's corners. + this.add_glsl_snippet(Shell.SnippetHook.VERTEX, 'varying vec4 vsPos;', + 'vsPos = cogl_modelview_matrix * cogl_position_in;', false); + + const fragmentDeclares = ` + varying vec4 vsPos; + uniform sampler2D uTexture; + uniform float uPitch; + uniform float uYaw; + + mat3 getPitch() { + float s = sin(uPitch); + float c = cos(uPitch); + return mat3(1.0, 0.0, 0.0, 0.0, c, s, 0.0, -s, c); + } + + mat3 getYaw() { + float s = sin(uYaw); + float c = cos(uYaw); + return mat3(c, 0.0, -s, 0.0, 1.0, 0.0, s, 0.0, c); + } + `; + + // The fragment shader uses the interpolated viewspace position to compute a view + // ray. This ray is rotated according to the pitch and yaw values. + const fragmentCode = ` + // Rotate the view ray. + vec3 view = getYaw() * getPitch() * normalize(vsPos.xyz); + + // Compute equirectangular projection. + const float pi = 3.14159265359; + float x = 0.5 + 0.5 * atan(view.x, -view.z) / pi; + float y = acos(view.y) / pi; + + cogl_color_out = texture2D(uTexture, vec2(x, y)); + `; + + this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, fragmentDeclares, fragmentCode, + false); + } + + // For each draw call, we have to set some uniform values. + vfunc_paint_target(node, paintContext) { + this.get_pipeline().set_layer_texture(0, this._texture.get_texture()); + + this.set_uniform_float(this.get_uniform_location('uTexture'), 1, [0]); + this.set_uniform_float(this.get_uniform_location('uPitch'), 1, [this.pitch]); + this.set_uniform_float(this.get_uniform_location('uYaw'), 1, [this.yaw]); + + super.vfunc_paint_target(node, paintContext); + } +}); + +////////////////////////////////////////////////////////////////////////////////////////// +// The Skybox is a simple actor which applies the above effect to itself. It also has // +// the pitch and yaw properties - these are directly forwarded to the effect. // +////////////////////////////////////////////////////////////////////////////////////////// + +// clang-format off +var Skybox = GObject.registerClass({ + Properties: { + 'yaw': GObject.ParamSpec.double('yaw', 'yaw', 'yaw', GObject.ParamFlags.READWRITE, + -2 * Math.PI, 2 * Math.PI, 0), + 'pitch': GObject.ParamSpec.double('pitch', 'pitch', 'pitch', GObject.ParamFlags.READWRITE, + -0.5 * Math.PI, 0.5 * Math.PI, 0), + } + }, class Skybox extends Clutter.Actor { + // clang-format on + _init(file) { + super._init(); + + // Apply the effect. + this._effect = new SkyboxEffect(file); + this.add_effect(this._effect); + + // Make sure that the overview background is transparent. + Main.uiGroup.add_style_class_name('desktop-cube-panorama-enabled'); + + // Forward the yaw and pitch values. + this.bind_property('yaw', this._effect, 'yaw', GObject.BindingFlags.NONE); + this.bind_property('pitch', this._effect, 'pitch', GObject.BindingFlags.NONE); + + // Revert to the original overview background appearance. + this.connect('destroy', () => { + Main.uiGroup.remove_style_class_name('desktop-cube-panorama-enabled'); + }); + } +}); \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/utils.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/utils.js new file mode 100644 index 0000000..956c1ae --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/src/utils.js @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ,-. ,--. ,-. , , ,---. ,-. ;-. ,-. . . ,-. ,--. // +// | \ | ( ` | / | / \ | ) / | | | ) | // +// | | |- `-. |< | | | |-' | | | |-< |- // +// | / | . ) | \ | \ / | \ | | | ) | // +// `-' `--' `-' ' ` ' `-' ' `-' `--` `-' `--' // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const Config = imports.misc.config; +const [GS_MAJOR] = Config.PACKAGE_VERSION.split('.'); + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); + +// This method can be used to write a message to GNOME Shell's log. This is enhances +// the standard log() functionality by prepending the extension's name and the location +// where the message was logged. As the extensions name is part of the location, you +// can more effectively watch the log output of GNOME Shell: +// journalctl -f -o cat | grep -E 'desktop-cube|' +// This method is based on a similar script from the Fly-Pie GNOME Shell extension which +// os published under the MIT License (https://github.com/Schneegans/Fly-Pie). +function debug(message) { + const stack = new Error().stack.split('\n'); + + // Remove debug() function call from stack. + stack.shift(); + + // Find the index of the extension directory (e.g. desktopcube@schneegans.github.com) + // in the stack entry. We do not want to print the entire absolute file path. + const extensionRoot = stack[0].indexOf(Me.metadata.uuid); + + log('[' + stack[0].slice(extensionRoot) + '] ' + message); +} + +// This method returns true if the current GNOME Shell version matches the given +// argument. +function shellVersionIs(major) { + return GS_MAJOR == major; +} + +// This method returns true if the current GNOME Shell version is at least as high as the +// given argument. +function shellVersionIsAtLeast(major) { + return GS_MAJOR >= major; +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/stylesheet.css b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/stylesheet.css new file mode 100644 index 0000000..82ed00c --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/desktop-cube@schneegans.github.com/stylesheet.css @@ -0,0 +1,20 @@ +/* +SPDX-FileCopyrightText: Simon Schneegans +SPDX-License-Identifier: CC0-1.0 +*/ + +/* +This ensures that the overview background is transparent, so that the background +panorama becomes visible. +*/ +.desktop-cube-panorama-enabled #overviewGroup { + background: transparent; +} + +/* +This ensures that the background during workspace switches becomes transparent, so that +the background panorama becomes visible. +*/ +.desktop-cube-panorama-enabled .workspace-animation { + background-color: transparent; +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/CHANGELOG.md b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/CHANGELOG.md new file mode 100644 index 0000000..d2467b4 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/CHANGELOG.md @@ -0,0 +1,420 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +We go to the next version after each release on [GNOME Shell Extensions website](https://extensions.gnome.org/). + +## [Unreleased] + +## [22.0.0 Millet] - 2022-09-10 + +### Fixed + +- Dash app button visibility height. +- Looking glass error after unlock. + +### Added + +- App menu label visibility. +- GNOME Shell 43 support. +- Quick settings menu visibility. + +### Removed + +- Aggregate menu for GNOME Shell 43 and higher. + +## [21.0.0 Reynolds] - 2022-08-06 + +### Changed + +- Prefs compatibility layer checking to GTK and Adw instead of GNOME Shell version. + +### Fixed + +- Application button visibility in Ubuntu 22.04. +- Prefs window size for scaled displays. +- Prefs window size for small displays in GNOME Shell 42. +- Racy prefs window size. +- Window caption going out of display area when dash is disabled in GNOME Shell 40 and higher. +- Russian translation by [@librusekus35790](https://gitlab.gnome.org/librusekus35790). +- Spanish translation by [@Luci](https://gitlab.gnome.org/Luci). + +### Added + +- Alt Tab window preview icon size. +- Alt Tab window preview size. +- Alt Tab icon size. +- Dash separator visibility. +- Looking glass size by [@AdvendraDeswanta](https://gitlab.gnome.org/AdvendraDeswanta). +- OSD position. +- Take screenshot button in window menu visibility. + +### Removed + +- Gesture API for GNOME Shell 40 and higher. +- List box separators for GNOME Shell 40 and 41 (EOS). +- Prefs intro. + +## [20.0.0 Hayez] - 2022-04-01 + +### Fixed + +- Dynamic workspaces getting disabled by workspace popup. +- Flickering panel after Unlock. +- Notification banner position on GNOME Shell 42. +- Window demands attention focus on GNOME Shell 42. +- French translation by [@GeoffreyCoulaud](https://gitlab.gnome.org/GeoffreyCoulaud). +- Italian translation by [@svityboy](https://gitlab.gnome.org/svityboy). + +### Added + +- Events visibility in clock menu. +- Calendar visibility in clock menu. +- Dutch translation by [@Vistaus](https://gitlab.gnome.org/Vistaus). + +## [19.0.0 Ancher] - 2022-03-02 + +### Fixed + +- Blurry search entry on GNOME Shell themes with box-shadow. +- Prefs file chooser recursion. +- SecondaryMonitorDisplay error on GNOME Shell 42. +- Shell theme override OSD for GNOME Shell 42. +- Shell theme override workspace switcher for GNOME Shell 42. +- Workspace popup visiblity in GNOME Shell 42. + +### Added + +- Libadwaita for GNOME Shell 42 prefs. +- Panel icon size. +- Panel world clock visiblity. +- Weather visiblity. + +## [18.0.0 Roslin] - 2022-02-12 + +### Fixed + +- GNOME 3.x prefs error. + +## [17.0.0 Roslin] - 2022-02-11 + +### Fixed + +- Emitting panel show when panel is visible. +- Looking glass not showing up. +- Looking glass position on startup when panel is hidden. +- Prefs height going off the screen in small displays. +- Prefs lunching url freeze on Wayland. +- Prefs padding in GNOME Shell 42. +- Prefs UI Improvement by [@muqtxdir](https://gitlab.gnome.org/muqtxdir). +- Startup animation for hiding panel when panel is disabled. +- Type to search when text entry content is replaced with another content. +- Window goes under panel after unlock on Wayland. +- Window picker caption visibility issue on Pop Shell. +- Galician translation by [@frandieguez](https://gitlab.gnome.org/frandieguez). + +### Added + +- Bottom to notification banner position. + +### Removed + +- Panel corner size option for GNOME Shell 42. + +## [16.0.0 Rembrandt] - 2021-11-15 + +### Fixed + +- Animation jump when search entry is disabled and entering app grid. +- Clock menu revealing in lockscreen when the position is left or right. +- Startup status for Ubuntu. +- Workspace switcher visiblity in GNOME Shell 41. + +### Removed + +- Hot corner for GNOME Shell 41. +- Hot corner library for all supported Shell versions. + +### Added + +- Double supper to app grid for GNOME Shell 40 and 41. +- Panel corner size when panel is disabled. +- Panel visiblity in overview when panel is disabled. +- Prefs window intro. +- Profile selector to the prefs window. +- Ripple box. + +## [15.0.0 Magnetized] - 2021-09-22 + +### Fixed + +- unlock recursion error. + +### Added + +- Hot corner support for GNOME Shell 41. + +## [14.0.0 Magnetized] - 2021-09-22 + +### Changed + +- Repo folder structure to have better organization. + +### Fixed + +- Bottom panel position for multi monitors [@harshadgavali](https://gitlab.gnome.org/harshadgavali). +- First swipe up in desktop startup status. +- Looking glass position on bottom panel. +- Maximized window gap on Wayland. +- Search entry animation for type to search when search entry is disabled. +- Search entry API to avoid conflicting with other extensions. +- Window picker caption border on disable. +- Window picker disapearing on wayland with shell theme override. +- Galician translation by [@frandieguez](https://gitlab.gnome.org/frandieguez). +- Spanish translation by [@DiegoIvanME](https://gitlab.gnome.org/DiegoIvanME). + +### Removed + +- Donation popover in prefs. +- Hot corner for GNOME Shell 41. + +### Added + +- GNOME Shell 41 support. +- Panel indicator padding size. +- Window picker close button visibility. + +## [13.0.0 Ring] - 2021-08-10 + +### Changed + +- Search button position in prefs window. + +### Fixed + +- Accessing dash in case the original dash has been removed by third party extensions. +- API.monitorGetInfo for "pMonitor is null" error. +- Dropdown align in preferences dialog. +- Startup status blocking shortcut keys. +- Unwanted window demands attention focus. +- Russian translation by [@librusekus35790](https://gitlab.gnome.org/librusekus35790). + +### Removed + +- Settings and Translation library and using ExtensionUtils instead. + +### Added + +- Panel button padding size. +- Panel height. +- Window picker caption visibility. +- Workspace background corner size in overview. +- Workspace wraparound (modified version of WorkspaceSwitcherWrapAround by [@war1025](https://github.com/war1025)). + +## [12.0.0 Queen Red] - 2021-06-29 + +### Changed + +- Lighter background color for switcher list (alt+tab) in override theme. +- Workspace switcher max size now maxed out to 30%. + +### Fixed + +- Combobox scroll issue on GTK4. +- Window demands attention focus notification popup. +- French translation by [@GeoffreyCoulaud](https://gitlab.gnome.org/GeoffreyCoulaud). +- Russian translation by [@librusekus35790](https://gitlab.gnome.org/librusekus35790). + +### Added + +- Always show workspace switcher on dynamic workspaces. +- More descriptions to the preferences dialog. +- Notification banner position. +- Startup status for GNOME Shell 40. +- Workspace animation background color for shell theme override. +- Workspaces visiblity in app grid by [@fmuellner](https://gitlab.gnome.org/fmuellner). +- Chinese (Taiwan) translation by [@r0930514](https://gitlab.com/r0930514). + +## [11.0.0 Whisper] - 2021-05-20 + +### Changed + +- App gesture now only works on GNOME 3.36 and 3.38. +- Donation icon to GTK4 non-compatible icon sets. +- Shell theme override is now disabled by default. +- Workspace switcher size for GNOME Shell 40 is now maxed out to 15%. + +### Fixed + +- Gap when panel posision is at the bottom and shell override theme happens. +- Panel menu margin when panel is in bottom. +- Window picker icon visiblity on drag. +- Workspace switcher size for multi monitor setup. +- Arabic translation by [@AliGalal](https://gitlab.com/AliGalal). +- Chinese translation by [@wsxy162](https://gitlab.com/wsxy162). +- Italian translation by [@l3nn4rt](https://gitlab.com/l3nn4rt). +- Swedish translation by [@MorganAntonsson](https://gitlab.com/MorganAntonsson). + +### Added + +- Activities button icon. +- Dash icon size. +- Window demands attention focus. + +## [10.0.0] - 2021-03-26 + +### Changed + +- Organized prefs UI for icons and behavior. +- Removed quotes and side bar image from prefs UI. + +### Fixed + +- Fake hot corner primary monitor position. +- Horizontal scroll in prefs. +- Primary Monitor Panel Position. +- Arabic translation by [@karem34](https://gitlab.com/karem34). +- Russian translation by [@librusekus35790](https://gitlab.com/librusekus35790). + +### Added + +- Clock menu position. +- Disable animation or change the animation speed. +- Disable applications button in dash. +- Disable app menu icon. +- Disable panel arrow in GNOME 3.36 and 3.38. +- Disable panel notification icon. +- No results found for prefs window. +- Brazilian Portuguese translation by [@Zelling](https://gitlab.com/Zelling). +- Catalan translation by [@juxuanu](https://gitlab.com/juxuanu). +- Galician translation by [@frandieguez](https://gitlab.com/frandieguez). + +## [9.0.0] - 2021-03-06 + +### Changed + +- Prefs interface. + +### Fixed + +- Default value for hot corner on extension disable. +- GNOME Shell 40.beta version. + +### Added + +- Disable power icon. +- Panel position. +- Support to prefs window. + +## [8.0.0] - 2021-02-22 + +### Changed + +- Holding back lonely overview until the final GNOME 40 release. + +### Fixed + +- Dash override theme on GNOME Shell 40 beta. +- Focus for find entry on prefs. +- Search controller for GNOME Shell 40 beta. +- Start search for GNOME Shell 40 beta. +- Workspace switcher enable related to workspace switcher size. +- Nepali translation filename by [@IBA4](https://gitlab.com/IBA4). + +## [7.0.0] - 2021-02-12 + +### Fixed + +- GNOME Shell 40 hidden side by side workspace preview. +- GNOME Shell 40 search padding when panel is disabled. +- Initial prefs window size. + +### Added + +- GNOME Shell 40 window picker icon visibility to the settings. +- GNOME Shell 40 workspace switcher size to the settings. +- Panel corner size to the settings. +- Search feature to the settings. +- Type to Search to the settings. +- Nepali translation by [@IBA4](https://gitlab.com/IBA4). +- Spanish translation by [@oscfdezdz](https://gitlab.com/oscfdezdz). + +## [6.0.0] - 2021-01-29 + +### Fixed + +- GNOME Shell 3.38 extra padding on no workspace switcher. +- GNOME Shell 40 and GTK4 support for prefs. +- GNOME Shell 40 support for search entry. +- GNOME Shell 40 support for workspace switcher. + +## [5.0.0] - 2021-01-05 + +### Added + +- Accessibility Menu visibility to the settings. +- Activities button visibility to the settings. +- App menu visibility to the settings. +- Clock menu visibility to the settings. +- Keyboard Layout visibility to the settings. +- System Menu (Aggregate Menu) visibility to the settings. + +### Changed + +- OSD in settings to "On Screen Display (OSD)". + +### Fixed + +- Hot corner when top panel is visible. +- Padding on no dash. +- Search top padding on no top panel. + +## [4.0.0] 2020-12-25 + +### Added + +- API to decouple all libraries from using GNOME Shell ui directly. +- Automate build process by [@daPhipz](https://gitlab.com/daPhipz). +- CHANGELOG.md file. +- Compatibility layer for API. +- Translation automation script by [@daPhipz](https://gitlab.com/daPhipz). + +### Changed + +- Default settings to enable. +- Displaying error for generate-mo.sh by [@daPhipz](https://gitlab.com/daPhipz). +- German translation by [@M4he](https://gitlab.com/M4he). + +### Fixed + +- Top padding on no search and no top panel. + +## [3.0.0] - 2020-12-21 + +### Added + +- CONTRIBUTING.md file. +- Decoupled library from GNOME Shell ui. +- Extension logo. +- Initial Translations. +- Prefs as extension settings. + +## [2.0.0] - 2020-11-18 + +### Fixed + +- Destroy hot corner on disable. + +## [1.0.0] - 2020-11-15 + +### Added + +- Disable app gesture. +- Disable background menu. +- Hide dash. +- Hide search. +- Hide top panel. +- Hide workspace switcher. +- Hot corner to toggle overview visibility. + +. diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/LICENSE b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/LICENSE new file mode 100644 index 0000000..ce02513 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Just Perfection GNOME Shell Desktop + Copyright (C) 2020-2022 Javad Rahmatzadeh + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Just Perfection GNOME Shell Desktop + Copyright (C) 2020-2022 Javad Rahmatzadeh + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/bin/close-button.svg b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/bin/close-button.svg new file mode 100644 index 0000000..c4a62ba --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/bin/close-button.svg @@ -0,0 +1,50 @@ + +Close Buttonimage/svg+xmlClose ButtonJavad RahmatzadehJavad Rahmatzadeh2022 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/extension.js new file mode 100644 index 0000000..f5eec62 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/extension.js @@ -0,0 +1,121 @@ +/** + * Extension + * + * @author Javad Rahmatzadeh + * @copyright 2020-2022 + * @license GPL-3.0-only + */ + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); + +const {API, Manager} = Me.imports.lib; +const {GObject, GLib, Gio, St, Clutter, Meta} = imports.gi; + +const Util = imports.misc.util; +const Config = imports.misc.config; +const shellVersion = parseFloat(Config.PACKAGE_VERSION); + +const Main = imports.ui.main; +const BackgroundMenu = imports.ui.backgroundMenu; +const OverviewControls = imports.ui.overviewControls; +const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup; +const ViewSelector = (shellVersion < 40) ? imports.ui.viewSelector : null; +const WorkspaceThumbnail = imports.ui.workspaceThumbnail; +const SearchController = (shellVersion >= 40) ? imports.ui.searchController : null; +const Panel = imports.ui.panel; +const WorkspacesView = imports.ui.workspacesView; +const WindowPreview = (shellVersion >= 3.38) ? imports.ui.windowPreview : null; +const Workspace = imports.ui.workspace; +const LookingGlass = imports.ui.lookingGlass; +const MessageTray = imports.ui.messageTray; +const OSDWindow = imports.ui.osdWindow; +const WindowMenu = imports.ui.windowMenu; +const AltTab = imports.ui.altTab; + +let manager; +let api; + +/** + * initiate extension + * + * @returns {void} + */ +function init() +{ +} + +/** + * enable extension + * + * @returns {void} + */ +function enable() +{ + // <3.36 can crash by enabling the extension + // since <3.36 is not supported we simply return + // to avoid bad experience for <3.36 users. + if (shellVersion < 3.36) { + return; + } + + let InterfaceSettings = new Gio.Settings({schema_id: 'org.gnome.desktop.interface'}); + + api = new API.API({ + Main, + BackgroundMenu, + OverviewControls, + WorkspaceSwitcherPopup, + InterfaceSettings, + SearchController, + ViewSelector, + WorkspaceThumbnail, + WorkspacesView, + Panel, + WindowPreview, + Workspace, + LookingGlass, + MessageTray, + OSDWindow, + WindowMenu, + AltTab, + St, + Gio, + GLib, + Clutter, + Util, + Meta, + GObject, + }, shellVersion); + + api.open(); + + let settings = ExtensionUtils.getSettings(); + + manager = new Manager.Manager({ + API: api, + Settings: settings, + }, shellVersion); + + manager.registerSettingsSignals(); + manager.applyAll(); +} + +/** + * disable extension + * + * @returns {void} + */ +function disable() +{ + if (manager) { + manager.revertAll(); + manager = null; + } + + if (api) { + api.close(); + api = null; + } +} + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/API.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/API.js new file mode 100644 index 0000000..61a4639 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/API.js @@ -0,0 +1,3354 @@ +/** + * API Library + * + * @author Javad Rahmatzadeh + * @copyright 2020-2022 + * @license GPL-3.0-only + */ + +const XY_POSITION = { + TOP_START: 0, + TOP_CENTER: 1, + TOP_END: 2, + BOTTOM_START: 3, + BOTTOM_CENTER: 4, + BOTTOM_END: 5, + CENTER_START: 6, + CENTER_CENTER: 7, + CENTER_END: 8, +}; + +const PANEL_POSITION = { + TOP: 0, + BOTTOM: 1, +}; + +const PANEL_BOX_POSITION = { + CENTER: 0, + RIGHT: 1, + LEFT: 2, +}; + +const PANEL_HIDE_MODE = { + ALL: 0, + DESKTOP: 1, +}; + +const SHELL_STATUS = { + NONE: 0, + OVERVIEW: 1, +}; + +const ICON_TYPE = { + NAME: 0, + URI: 1, +}; + +const DASH_ICON_SIZES = [16, 22, 24, 32, 48, 64]; + +/** + * API to avoid calling GNOME Shell directly + * and make all parts compatible with different GNOME Shell versions + */ +var API = class +{ + /** + * Class Constructor + * + * @param {Object} dependencies + * 'Main' reference to ui::main + * 'BackgroundMenu' reference to ui::backgroundMenu + * 'OverviewControls' reference to ui::overviewControls + * 'WorkspaceSwitcherPopup' reference to ui::workspaceSwitcherPopup + * 'InterfaceSettings' reference to Gio::Settings for 'org.gnome.desktop.interface' + * 'SearchController' reference to ui::searchController + * 'ViewSelector' reference to ui::viewSelector + * 'WorkspaceThumbnail' reference to ui::workspaceThumbnail + * 'WorkspacesView' reference to ui::workspacesView + * 'Panel' reference to ui::panel + * 'WindowPreview' reference to ui::windowPreview + * 'Workspace' reference to ui::workspace + * 'LookingGlass' reference to ui::lookingGlass + * 'MessageTray' reference to ui::messageTray + * 'OSDWindow' reference to ui::osdTray + * 'WindowMenu' reference to ui::windowMenu + * 'AltTab' reference to ui::altTab + * 'St' reference to St + * 'Gio' reference to Gio + * 'GLib' reference to GLib + * 'Clutter' reference to Clutter + * 'Util' reference to misc::util + * 'Meta' reference to Meta + * 'GObject' reference to GObject + * @param {number} shellVersion float in major.minor format + */ + constructor(dependencies, shellVersion) + { + this._main = dependencies['Main'] || null; + this._backgroundMenu = dependencies['BackgroundMenu'] || null; + this._overviewControls = dependencies['OverviewControls'] || null; + this._workspaceSwitcherPopup = dependencies['WorkspaceSwitcherPopup'] || null; + this._interfaceSettings = dependencies['InterfaceSettings'] || null; + this._searchController = dependencies['SearchController'] || null; + this._viewSelector = dependencies['ViewSelector'] || null; + this._workspaceThumbnail = dependencies['WorkspaceThumbnail'] || null; + this._workspacesView = dependencies['WorkspacesView'] || null; + this._panel = dependencies['Panel'] || null; + this._windowPreview = dependencies['WindowPreview'] || null; + this._workspace = dependencies['Workspace'] || null; + this._lookingGlass = dependencies['LookingGlass'] || null; + this._messageTray = dependencies['MessageTray'] || null; + this._osdWindow = dependencies['OSDWindow'] || null; + this._windowMenu = dependencies['WindowMenu'] || null; + this._altTab = dependencies['AltTab'] || null; + this._st = dependencies['St'] || null; + this._gio = dependencies['Gio'] || null; + this._glib = dependencies['GLib'] || null; + this._clutter = dependencies['Clutter'] || null; + this._util = dependencies['Util'] || null; + this._meta = dependencies['Meta'] || null; + this._gobject = dependencies['GObject'] || null; + + this._shellVersion = shellVersion; + this._originals = {}; + this._timeoutIds = {}; + + /** + * whether search entry is visible + * + * @member {boolean} + */ + this._searchEntryVisibility = true; + + /** + * last workspace switcher size in float + * + * @member {number} + */ + this._workspaceSwitcherLastSize + = (this._workspaceThumbnail && this._shellVersion >= 40) + ? this._workspaceThumbnail.MAX_THUMBNAIL_SCALE + : 0.0; + } + + /** + * prepare everything needed for API + * + * @returns {void} + */ + open() + { + this.UIStyleClassAdd(this._getAPIClassname('shell-version')); + } + + /** + * remove everything from GNOME Shell been added by this class + * + * @returns {void} + */ + close() + { + this.UIStyleClassRemove(this._getAPIClassname('shell-version')); + this._startSearchSignal(false); + + for (let [name, id] of Object.entries(this._timeoutIds)) { + this._glib.source_remove(id); + delete(this._timeoutIds[name]); + } + } + + /** + * get x and y align for position + * + * @param int pos position + * see XY_POSITION + * + * @returns {array} + * - 0 Clutter.ActorAlign + * - 1 Clutter.ActorAlign + */ + _xyAlignGet(pos) + { + if (XY_POSITION.TOP_START === pos) { + return [this._clutter.ActorAlign.START, this._clutter.ActorAlign.START]; + } + + if (XY_POSITION.TOP_CENTER === pos) { + return [this._clutter.ActorAlign.CENTER, this._clutter.ActorAlign.START]; + } + + if (XY_POSITION.TOP_END === pos) { + return [this._clutter.ActorAlign.END, this._clutter.ActorAlign.START]; + } + + if (XY_POSITION.CENTER_START === pos) { + return [this._clutter.ActorAlign.START, this._clutter.ActorAlign.CENTER]; + } + + if (XY_POSITION.CENTER_CENTER === pos) { + return [this._clutter.ActorAlign.CENTER, this._clutter.ActorAlign.CENTER]; + } + + if (XY_POSITION.CENTER_END === pos) { + return [this._clutter.ActorAlign.END, this._clutter.ActorAlign.CENTER]; + } + + if (XY_POSITION.BOTTOM_START === pos) { + return [this._clutter.ActorAlign.START, this._clutter.ActorAlign.END]; + } + + if (XY_POSITION.BOTTOM_CENTER === pos) { + return [this._clutter.ActorAlign.CENTER, this._clutter.ActorAlign.END]; + } + + if (XY_POSITION.BOTTOM_END === pos) { + return [this._clutter.ActorAlign.END, this._clutter.ActorAlign.END]; + } + } + + /** + * add to animation duration + * + * @param {number} duration in milliseconds + * + * @returns {number} + */ + _addToAnimationDuration(duration) + { + let settings = this._st.Settings.get(); + + return (settings.enable_animations) ? settings.slow_down_factor * duration : 1; + } + + /** + * get signal id of the event + * + * @param {Gtk.Widget} widget to find signal in + * @param {string} signalName signal name + * + * @returns {number} + */ + _getSignalId(widget, signalName) + { + return this._gobject.signal_handler_find(widget, { signalId: signalName }); + } + + /** + * get the css classname for API + * + * @param {string} type possible types + * shell-version + * no-search + * no-workspace + * no-panel + * panel-corner + * no-window-picker-icon + * type-to-search + * no-power-icon + * bottom-panel + * no-panel-arrow + * no-panel-notification-icon + * no-app-menu-icon + * no-app-menu-label + * no-show-apps-button + * activities-button-icon + * activities-button-icon-monochrome + * activities-button-no-label + * dash-icon-size + * panel-button-padding-size + * panel-indicator-padding-size + * no-window-caption + * workspace-background-radius-size + * no-window-close + * refresh-styles + * no-ripple-box + * no-weather + * no-world-clocks + * panel-icon-size + * no-events-button + * osd-position-top + * osd-position-bottom + * osd-position-center + * no-dash-separator + * + * @returns {string} + */ + _getAPIClassname(type) + { + let starter = 'just-perfection-api-'; + + let possibleTypes = [ + 'shell-version', + 'no-search', + 'no-workspace', + 'no-panel', + 'panel-corner', + 'no-window-picker-icon', + 'type-to-search', + 'no-power-icon', + 'bottom-panel', + 'no-panel-arrow', + 'no-panel-notification-icon', + 'no-app-menu-icon', + 'no-app-menu-label', + 'no-show-apps-button', + 'activities-button-icon', + 'activities-button-icon-monochrome', + 'activities-button-no-label', + 'dash-icon-size', + 'panel-button-padding-size', + 'panel-indicator-padding-size', + 'no-window-caption', + 'workspace-background-radius-size', + 'no-window-close', + 'refresh-styles', + 'no-ripple-box', + 'no-weather', + 'no-world-clocks', + 'panel-icon-size', + 'no-events-button', + 'osd-position-top', + 'osd-position-bottom', + 'osd-position-center', + 'no-dash-separator', + ]; + + if (!possibleTypes.includes(type)) { + return ''; + } + + if (type === 'shell-version') { + let shellVerMajor = Math.trunc(this._shellVersion); + return `${starter}gnome${shellVerMajor}`; + } + + return starter + type; + } + + /** + * allow shell theme use its own panel corner + * + * @returns {void} + */ + panelCornerSetDefault() + { + if (this._shellVersion >= 42) { + return; + } + + let classnameStarter = this._getAPIClassname('panel-corner'); + + for (let size = 0; size <= 60; size++) { + this.UIStyleClassRemove(classnameStarter + size); + } + } + + /** + * change panel corner size + * + * @param {number} size 0 to 60 + * + * @returns {void} + */ + panelCornerSetSize(size) + { + if (this._shellVersion >= 42) { + return; + } + + this.panelCornerSetDefault(); + + if (size > 60 || size < 0) { + return; + } + + let classnameStarter = this._getAPIClassname('panel-corner'); + + this.UIStyleClassAdd(classnameStarter + size); + } + + /** + * set panel size to default + * + * @returns {void} + */ + panelSetDefaultSize() + { + if (!this._originals['panelHeight']) { + return; + } + + this.panelSetSize(this._originals['panelHeight'], false); + } + + /** + * change panel size + * + * @param {number} size 0 to 100 + * @param {boolean} fake true means it shouldn't change the last size, + * false otherwise + * + * @returns {void} + */ + panelSetSize(size, fake) + { + if (!this._originals['panelHeight']) { + this._originals['panelHeight'] = this._main.panel.height; + } + + if (size > 100 || size < 0) { + return; + } + + this._main.panel.height = size; + + if (!fake) { + this._panelSize = size; + } + + // to fix panel not getting out of place + this._emitPanelPositionChanged(); + } + + /** + * get the last size of the panel + * + * @returns {number} + */ + panelGetSize() + { + if (this._panelSize !== undefined) { + return this._panelSize; + } + + if (this._originals['panelHeight']) { + return this._originals['panelHeight']; + } + + return this._main.panel.height; + } + + /** + * emit refresh styles + * this is useful when changed style doesn't emit change because doesn't have + * standard styles. for example, style with only `-natural-hpadding` + * won't notify any change. so you need to call this function + * to refresh that + * + * @returns {void} + */ + _emitRefreshStyles() + { + let classname = this._getAPIClassname('refresh-styles'); + + this.UIStyleClassAdd(classname); + this.UIStyleClassRemove(classname); + } + + /** + * emit changed signal for panel position + * + * @param {boolean} calledFromChanger whether it is called from + * position changer. you should never call it with false from + * this.panelSetPosition() since it can cause recursion. + * + * @returns {void} + */ + _emitPanelPositionChanged(calledFromChanger = false) + { + if (this._timeoutIds['emitPanelPositionChanged']) { + this._glib.source_remove(this._timeoutIds['emitPanelPositionChanged']); + delete(this._timeoutIds['emitPanelPositionChanged']); + } + + if (this._timeoutIds['emitPanelPositionChanged2']) { + this._glib.source_remove(this._timeoutIds['emitPanelPositionChanged2']); + delete(this._timeoutIds['emitPanelPositionChanged2']); + } + + if (!calledFromChanger) { + this.panelSetPosition(this.panelGetPosition(), true); + } + + if (!this.isPanelVisible()) { + let mode = this._panelHideMode ? this._panelHideMode : 0; + this.panelHide(mode, 0); + } else { + // resize panel can fix windows going under panel + // we may not need it on X11, but it is needed on Wayland + // we also need delay after animation + // because without delay it many not fix the issue + let panelBox = this._main.layoutManager.panelBox; + let duration = this._addToAnimationDuration(180); + this._timeoutIds['emitPanelPositionChanged'] + = this._glib.timeout_add(this._glib.PRIORITY_IDLE, duration, () => { + delete(this._timeoutIds['emitPanelPositionChanged']); + this._main.panel.height++; + this._timeoutIds['emitPanelPositionChangedIn2'] + = this._glib.timeout_add(this._glib.PRIORITY_IDLE, 20, () => { + this._main.panel.height--; + delete(this._timeoutIds['emitPanelPositionChangedIn2']); + return this._glib.SOURCE_REMOVE; + }); + return this._glib.SOURCE_REMOVE; + }); + } + + this._fixLookingGlassPosition(); + } + + /** + * show panel + * + * @param {number} animationDuration in milliseconds. defaults to 150 + * + * @returns {void} + */ + panelShow(animationDuration = 150) + { + this._panelVisibility = true; + + let classname = this._getAPIClassname('no-panel'); + + if (!this.UIStyleClassContain(classname)) { + return; + } + + let overview = this._main.overview; + let searchEntryParent = overview.searchEntry.get_parent(); + let panelBox = this._main.layoutManager.panelBox; + + this._main.layoutManager.removeChrome(panelBox); + this._main.layoutManager.addChrome(panelBox, { + affectsStruts: true, + trackFullscreen: true, + }); + + panelBox.ease({ + translation_y: 0, + mode: this._clutter.AnimationMode.EASE, + duration: animationDuration, + onComplete: () => { + // hide and show can fix windows going under panel + panelBox.hide(); + panelBox.show(); + this._fixLookingGlassPosition(); + }, + }); + + if (this._overviewShowingSignal) { + overview.disconnect(this._overviewShowingSignal); + delete(this._overviewShowingSignal); + } + + if (this._overviewHidingSignal) { + overview.disconnect(this._overviewHidingSignal); + delete(this._overviewHidingSignal); + } + + if (this._hidePanelWorkareasChangedSignal) { + global.display.disconnect(this._hidePanelWorkareasChangedSignal); + delete(this._hidePanelWorkareasChangedSignal); + } + + searchEntryParent.set_style(`margin-top: 0;`); + + this.UIStyleClassRemove(classname); + } + + /** + * hide panel + * + * @param {mode} hide mode see PANEL_HIDE_MODE. defaults to hide all + * @param {boolean} force apply hide even if it is hidden + * @param {number} animationDuration in milliseconds. defaults to 150 + * + * @returns {void} + */ + panelHide(mode, animationDuration = 150) + { + this._panelVisibility = false; + this._panelHideMode = mode; + + let overview = this._main.overview; + let searchEntryParent = overview.searchEntry.get_parent(); + let panelBox = this._main.layoutManager.panelBox; + let panelHeight = this._main.panel.height; + let direction = (this.panelGetPosition() === PANEL_POSITION.BOTTOM) ? 1 : -1; + + this._main.layoutManager.removeChrome(panelBox); + this._main.layoutManager.addChrome(panelBox, { + affectsStruts: false, + trackFullscreen: true, + }); + + panelBox.ease({ + translation_y: panelHeight * direction, + mode: this._clutter.AnimationMode.EASE, + duration: animationDuration, + onComplete: () => { + // hide and show can fix windows going under panel + panelBox.hide(); + panelBox.show(); + this._fixLookingGlassPosition(); + }, + }); + + searchEntryParent.set_style(`margin-top: 0;`); + + if (this._overviewShowingSignal) { + overview.disconnect(this._overviewShowingSignal); + delete(this._overviewShowingSignal); + } + if (this._overviewHidingSignal) { + overview.disconnect(this._overviewHidingSignal); + delete(this._overviewHidingSignal); + } + + let appMenuOriginalVisibility; + + if (mode === PANEL_HIDE_MODE.DESKTOP) { + if (!this._overviewShowingSignal) { + this._overviewShowingSignal = overview.connect('showing', () => { + appMenuOriginalVisibility = this.isAppMenuVisible(); + this.appMenuHide(); + panelBox.ease({ + translation_y: 0, + mode: this._clutter.AnimationMode.EASE, + duration: 250, + }); + }); + } + if (!this._overviewHidingSignal) { + this._overviewHidingSignal = overview.connect('hiding', () => { + panelBox.ease({ + translation_y: panelHeight * direction, + mode: this._clutter.AnimationMode.EASE, + duration: 250, + onComplete: () => { + if (appMenuOriginalVisibility) { + this.appMenuShow(); + } else { + this.appMenuHide(); + } + }, + }); + }); + } + searchEntryParent.set_style(`margin-top: ${panelHeight}px;`); + } + + if (this._hidePanelWorkareasChangedSignal) { + global.display.disconnect(this._hidePanelWorkareasChangedSignal); + delete(this._hidePanelWorkareasChangedSignal); + } + + this._hidePanelWorkareasChangedSignal + = global.display.connect('workareas-changed', () => { + this.panelHide(this._panelHideMode, 0); + }); + + // when panel is hidden and search entry is visible, + // the search entry gets too close to the top, so we fix it with margin + // on GNOME 3 we need to have top and bottom margin for correct proportion + // but on GNOME 40 we don't need to keep proportion but give it more + // top margin to keep it less close to top + let classname = this._getAPIClassname('no-panel'); + this.UIStyleClassAdd(classname); + } + + /** + * check whether panel is visible + * + * @returns {boolean} + */ + isPanelVisible() + { + if (this._panelVisibility === undefined) { + return true; + } + + return this._panelVisibility; + } + + /** + * check whether dash is visible + * + * @returns {boolean} + */ + isDashVisible() + { + return this._dashVisibility === undefined || this._dashVisibility; + } + + /** + * show dash + * + * @returns {void} + */ + dashShow() + { + if (!this._main.overview.dash || this.isDashVisible()) { + return; + } + + this._dashVisibility = true; + + this._main.overview.dash.show(); + + if (this._shellVersion >= 40) { + this._main.overview.dash.height = -1; + this._main.overview.dash.setMaxSize(-1, -1); + } else { + this._main.overview.dash.width = -1; + this._main.overview.dash._maxHeight = -1; + } + + this._updateWindowPreviewOverlap(); + } + + /** + * hide dash + * + * @returns {void} + */ + dashHide() + { + if (!this._main.overview.dash || !this.isDashVisible()) { + return; + } + + this._dashVisibility = false; + + this._main.overview.dash.hide(); + + if (this._shellVersion >= 40) { + this._main.overview.dash.height = 0; + } else { + this._main.overview.dash.width = 0; + } + + this._updateWindowPreviewOverlap(); + } + + /** + * update window preview overlap + * + * @returns {void} + */ + _updateWindowPreviewOverlap() + { + if (this._shellVersion < 40) { + return; + } + + let wpp = this._windowPreview.WindowPreview.prototype; + + if (this.isDashVisible() && wpp.overlapHeightsOld) { + wpp.overlapHeights = wpp.overlapHeightsOld; + delete(wpp.overlapHeightsOld); + return; + } + + if (!this.isDashVisible()) { + wpp.overlapHeightsOld = wpp.overlapHeights; + wpp.overlapHeights = function () { + let [top, bottom] = this.overlapHeightsOld(); + return [top + 24, bottom + 24]; + }; + } + } + + /** + * enable gesture + * + * @returns {void} + */ + gestureEnable() + { + if (this._shellVersion >= 40) { + return; + } + + global.stage.get_actions().forEach(a => { + a.enabled = true; + }); + } + + /** + * disable gesture + * + * @returns {void} + */ + gestureDisable() + { + if (this._shellVersion >= 40) { + return; + } + + global.stage.get_actions().forEach(a => { + a.enabled = false; + }); + } + + /** + * add class name to the UI group + * + * @param {string} classname class name + * + * @returns {void} + */ + UIStyleClassAdd(classname) + { + this._main.layoutManager.uiGroup.add_style_class_name(classname); + } + + /** + * remove class name from UI group + * + * @param {string} classname class name + * + * @returns {void} + */ + UIStyleClassRemove(classname) + { + this._main.layoutManager.uiGroup.remove_style_class_name(classname); + } + + /** + * check whether UI group has class name + * + * @param {string} classname class name + * + * @returns {boolean} + */ + UIStyleClassContain(classname) + { + return this._main.layoutManager.uiGroup.has_style_class_name(classname); + } + + /** + * enable background menu + * + * @returns {void} + */ + backgroundMenuEnable() + { + if (!this._originals['backgroundMenu']) { + return; + } + + this._backgroundMenu.BackgroundMenu.prototype.open + = this._originals['backgroundMenu']; + } + + /** + * disable background menu + * + * @returns {void} + */ + backgroundMenuDisable() + { + if (!this._originals['backgroundMenu']) { + this._originals['backgroundMenu'] + = this._backgroundMenu.BackgroundMenu.prototype.open; + } + + this._backgroundMenu.BackgroundMenu.prototype.open = () => {}; + } + + /** + * show search + * + * @param {boolean} fake true means it just needs to do the job but + * don't need to change the search visibility status + * + * @returns {void} + */ + searchEntryShow(fake) + { + let classname = this._getAPIClassname('no-search'); + + if (!this.UIStyleClassContain(classname)) { + return; + } + + this.UIStyleClassRemove(classname); + + let searchEntry = this._main.overview.searchEntry; + let searchEntryParent = searchEntry.get_parent(); + + searchEntryParent.ease({ + height: searchEntry.height, + opacity: 255, + mode: this._clutter.AnimationMode.EASE, + duration: 110, + onComplete: () => { + searchEntryParent.height = -1; + searchEntry.ease({ + opacity: 255, + mode: this._clutter.AnimationMode.EASE, + duration: 700, + }); + }, + }); + + if (!fake) { + this._searchEntryVisibility = true; + } + } + + /** + * hide search + * + * @param {boolean} fake true means it just needs to do the job + * but don't need to change the search visibility status + * + * @returns {void} + */ + searchEntryHide(fake) + { + this.UIStyleClassAdd(this._getAPIClassname('no-search')); + + let searchEntry = this._main.overview.searchEntry; + let searchEntryParent = searchEntry.get_parent(); + + searchEntry.ease({ + opacity: 0, + mode: this._clutter.AnimationMode.EASE, + duration: 50, + }); + + searchEntryParent.ease({ + height: 0, + opacity: 0, + mode: this._clutter.AnimationMode.EASE, + duration: 120, + }); + + if (!fake) { + this._searchEntryVisibility = false; + } + } + + /** + * enable start search + * + * @returns {void} + */ + startSearchEnable() + { + this._startSearchSignal(true); + + if (!this._originals['startSearch']) { + return; + } + + let viewSelector + = this._main.overview.viewSelector || this._main.overview._overview.viewSelector; + + if (this._shellVersion >= 40 && this._searchController) { + this._searchController.SearchController.prototype.startSearch + = this._originals['startSearch']; + } else { + viewSelector.startSearch = this._originals['startSearch']; + } + } + + /** + * disable start search + * + * @returns {void} + */ + startSearchDisable() + { + this._startSearchSignal(false); + + let overview = this._main.overview; + let viewSelector = overview.viewSelector || overview.viewSelector; + + if (!this._originals['startSearch']) { + this._originals['startSearch'] + = (this._shellVersion >= 40 && this._searchController) + ? this._searchController.SearchController.prototype.startSearch + : viewSelector.startSearch; + } + + if (this._shellVersion >= 40 && this._searchController) { + this._searchController.SearchController.prototype.startSearch = () => {}; + } else { + viewSelector.startSearch = () => {}; + } + } + + /** + * add search signals that needs to be show search entry when the + * search entry is hidden + * + * @param {boolean} add true means add the signal, false means remove + * the signal + * + * @returns {void} + */ + _startSearchSignal(add) + { + let controller + = this._main.overview.viewSelector || + this._main.overview._overview.viewSelector || + this._main.overview._overview.controls._searchController; + + // remove + if (!add) { + if (this._searchActiveSignal) { + controller.disconnect(this._searchActiveSignal); + this._searchActiveSignal = null; + } + return; + } + + // add + if (this._searchActiveSignal) { + return; + } + + let bySearchController = this._shellVersion >= 40; + + let signalName = (bySearchController) ? 'notify::search-active' : 'page-changed'; + + this._searchActiveSignal = controller.connect(signalName, () => { + if (this._searchEntryVisibility) { + return; + } + + let inSearch + = (bySearchController) + ? controller.searchActive + : (controller.getActivePage() === this._viewSelector.ViewPage.SEARCH); + + if (inSearch) { + this.UIStyleClassAdd(this._getAPIClassname('type-to-search')); + this.searchEntryShow(true); + } else { + this.UIStyleClassRemove(this._getAPIClassname('type-to-search')); + this.searchEntryHide(true); + } + }); + } + + /** + * enable OSD + * + * @returns {void} + */ + OSDEnable() + { + if (!this._originals['osdWindowManagerShow']) { + return; + } + + this._main.osdWindowManager.show = this._originals['osdWindowManagerShow']; + } + + /** + * disable OSD + * + * @returns {void} + */ + OSDDisable() + { + if (!this._originals['osdWindowManagerShow']) { + this._originals['osdWindowManagerShow'] + = this._main.osdWindowManager.show; + } + + this._main.osdWindowManager.show = () => {}; + } + + /** + * enable workspace popup + * + * @returns {void} + */ + workspacePopupEnable() + { + if (this._shellVersion < 42) { + if (!this._originals['workspaceSwitcherPopupShow']) { + return; + } + this._workspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype._show + = this._originals['workspaceSwitcherPopupShow']; + + return; + } + + if (!this._originals['workspaceSwitcherPopupDisplay']) { + return; + } + + this._workspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype.display + = this._originals['workspaceSwitcherPopupDisplay'] + } + + /** + * disable workspace popup + * + * @returns {void} + */ + workspacePopupDisable() + { + if (this._shellVersion < 42) { + if (!this._originals['workspaceSwitcherPopupShow']) { + this._originals['workspaceSwitcherPopupShow'] + = this._workspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype._show; + } + this._workspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype._show = () => { + return false; + }; + + return; + } + + if (!this._originals['workspaceSwitcherPopupDisplay']) { + this._originals['workspaceSwitcherPopupDisplay'] + = this._workspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype.display; + } + + this._workspaceSwitcherPopup.WorkspaceSwitcherPopup.prototype.display = (index) => { + return false; + }; + } + + /** + * show workspace switcher + * + * @returns {void} + */ + workspaceSwitcherShow() + { + if (this._shellVersion < 40) { + + if (!this._originals['getAlwaysZoomOut'] || + !this._originals['getNonExpandedWidth']) + { + return; + } + + let TSProto = this._overviewControls.ThumbnailsSlider.prototype; + + TSProto._getAlwaysZoomOut = this._originals['getAlwaysZoomOut']; + TSProto.getNonExpandedWidth = this._originals['getNonExpandedWidth']; + } + + // it should be before setting the switcher size + // because the size can be changed by removing the api class + this.UIStyleClassRemove(this._getAPIClassname('no-workspace')); + + if (this._workspaceSwitcherLastSize) { + this.workspaceSwitcherSetSize(this._workspaceSwitcherLastSize, false); + } else { + this.workspaceSwitcherSetDefaultSize(); + } + } + + /** + * hide workspace switcher + * + * @returns {void} + */ + workspaceSwitcherHide() + { + if (this._shellVersion < 40) { + + let TSProto = this._overviewControls.ThumbnailsSlider.prototype; + + if (!this._originals['getAlwaysZoomOut']) { + this._originals['getAlwaysZoomOut'] = TSProto._getAlwaysZoomOut; + } + + if (!this._originals['getNonExpandedWidth']) { + this._originals['getNonExpandedWidth'] = TSProto.getNonExpandedWidth; + } + + TSProto._getAlwaysZoomOut = () => { + return false; + }; + TSProto.getNonExpandedWidth = () => { + return 0; + }; + } + + this.workspaceSwitcherSetSize(0.0, true); + + // on GNOME 3.38 + // fix extra space that 3.38 leaves for no workspace with css + // on GNOME 40 + // we can hide the workspace only with css by scale=0 and + // no padding + this.UIStyleClassAdd(this._getAPIClassname('no-workspace')); + } + + /** + * check whether workspace switcher is visible + * + * @returns {boolean} + */ + isWorkspaceSwitcherVisible() + { + return !this.UIStyleClassContain(this._getAPIClassname('no-workspace')); + } + + /** + * get Secondary Monitor Display + * + * @returns {ui.WorkspacesView.SecondaryMonitorDisplay} + */ + _getSecondaryMonitorDisplay() + { + if (this._shellVersion < 40) { + return null; + } + + // for some reason the first time we get the value it returns null in 42 + // but it returns the correct value in second get + this._workspacesView.SecondaryMonitorDisplay; + + return this._workspacesView.SecondaryMonitorDisplay; + } + + /** + * set workspace switcher to its default size + * + * @returns {void} + */ + workspaceSwitcherSetDefaultSize() + { + if (this._shellVersion < 40) { + return; + } + + if (this._originals['MAX_THUMBNAIL_SCALE'] === undefined) { + return; + } + + let size = this._originals['MAX_THUMBNAIL_SCALE']; + + if (this.isWorkspaceSwitcherVisible()) { + this._workspaceThumbnail.MAX_THUMBNAIL_SCALE = size; + } + + if (this._originals['smd_getThumbnailsHeight'] !== undefined) { + let smd = this._getSecondaryMonitorDisplay(); + smd.prototype._getThumbnailsHeight = this._originals['smd_getThumbnailsHeight']; + } + + this._workspaceSwitcherLastSize = size; + } + + /** + * set workspace switcher size + * + * @param {number} size in float + * @param {boolean} fake true means don't change + * this._workspaceSwitcherLastSize, false otherwise + * + * @returns {void} + */ + workspaceSwitcherSetSize(size, fake) + { + if (this._shellVersion < 40) { + return; + } + + if (this._originals['MAX_THUMBNAIL_SCALE'] === undefined) { + this._originals['MAX_THUMBNAIL_SCALE'] + = this._workspaceThumbnail.MAX_THUMBNAIL_SCALE; + } + + if (this.isWorkspaceSwitcherVisible()) { + + this._workspaceThumbnail.MAX_THUMBNAIL_SCALE = size; + + // >> + // we are overriding the _getThumbnailsHeight() here with the same + // function as original but we change the MAX_THUMBNAIL_SCALE to our + // custom size. + // we do this because MAX_THUMBNAIL_SCALE is const and cannot be changed + let smd = this._getSecondaryMonitorDisplay(); + + if (this._originals['smd_getThumbnailsHeight'] === undefined) { + this._originals['smd_getThumbnailsHeight'] = smd.prototype._getThumbnailsHeight; + } + + smd.prototype._getThumbnailsHeight = function(box) { + if (!this._thumbnails.visible) + 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 * size); + } + // << + } + + if (!fake) { + this._workspaceSwitcherLastSize = size; + } + } + + /** + * add element to stage + * + * @param {St.Widget} element widget + * + * @returns {void} + */ + chromeAdd(element) + { + this._main.layoutManager.addChrome(element, { + affectsInputRegion : true, + affectsStruts : false, + trackFullscreen : true, + }); + } + + /** + * remove element from stage + * + * @param {St.Widget} element widget + * + * @returns {void} + */ + chromeRemove(element) + { + this._main.layoutManager.removeChrome(element); + } + + /** + * show activities button + * + * @returns {void} + */ + activitiesButtonShow() + { + if (!this.isLocked()) { + this._main.panel.statusArea['activities'].container.show(); + } + } + + /** + * hide activities button + * + * @returns {void} + */ + activitiesButtonHide() + { + this._main.panel.statusArea['activities'].container.hide(); + } + + /** + * show app menu + * + * @returns {void} + */ + appMenuShow() + { + if (!this.isLocked()) { + this._main.panel.statusArea['appMenu'].container.show(); + } + } + + /** + * hide app menu + * + * @returns {void} + */ + appMenuHide() + { + this._main.panel.statusArea['appMenu'].container.hide(); + } + + /** + * check whether app menu is visible + * + * @returns {boolean} + */ + isAppMenuVisible() + { + return this._main.panel.statusArea['appMenu'].container.visible; + } + + /** + * show date menu + * + * @returns {void} + */ + dateMenuShow() + { + if (!this.isLocked()) { + this._main.panel.statusArea['dateMenu'].container.show(); + } + } + + /** + * hide date menu + * + * @returns {void} + */ + dateMenuHide() + { + this._main.panel.statusArea['dateMenu'].container.hide(); + } + + /** + * show keyboard layout + * + * @returns {void} + */ + keyboardLayoutShow() + { + this._main.panel.statusArea['keyboard'].container.show(); + } + + /** + * hide keyboard layout + * + * @returns {void} + */ + keyboardLayoutHide() + { + this._main.panel.statusArea['keyboard'].container.hide(); + } + + /** + * show accessibility menu + * + * @returns {void} + */ + accessibilityMenuShow() + { + this._main.panel.statusArea['a11y'].container.show(); + } + + /** + * hide accessibility menu + * + * @returns {void} + */ + accessibilityMenuHide() + { + this._main.panel.statusArea['a11y'].container.hide(); + } + + /** + * show quick settings menu + * + * @returns {void} + */ + quickSettingsMenuShow() + { + if (this._shellVersion < 43) { + return; + } + + this._main.panel.statusArea['quickSettings'].container.show(); + } + + /** + * hide quick settings menu + * + * @returns {void} + */ + quickSettingsMenuHide() + { + if (this._shellVersion < 43) { + return; + } + + this._main.panel.statusArea['quickSettings'].container.hide(); + } + + /** + * show aggregate menu + * + * @returns {void} + */ + aggregateMenuShow() + { + if (this._shellVersion >= 43) { + return; + } + + this._main.panel.statusArea['aggregateMenu'].container.show(); + } + + /** + * hide aggregate menu + * + * @returns {void} + */ + aggregateMenuHide() + { + if (this._shellVersion >= 43) { + return; + } + + this._main.panel.statusArea['aggregateMenu'].container.hide(); + } + + /** + * set 'enableHotCorners' original value + * + * @returns {void} + */ + _setEnableHotCornersOriginal() + { + if (this._originals['enableHotCorners'] !== undefined) { + return; + } + + this._originals['enableHotCorners'] + = this._interfaceSettings.get_boolean('enable-hot-corners'); + } + + /** + * enable hot corners + * + * @returns {void} + */ + hotCornersEnable() + { + this._setEnableHotCornersOriginal(); + this._interfaceSettings.set_boolean('enable-hot-corners', true); + } + + /** + * disable hot corners + * + * @returns {void} + */ + hotCornersDisable() + { + this._setEnableHotCornersOriginal(); + this._interfaceSettings.set_boolean('enable-hot-corners', false); + } + + /** + * set the hot corners to default value + * + * @returns {void} + */ + hotCornersDefault() + { + this._setEnableHotCornersOriginal(); + + this._interfaceSettings.set_boolean('enable-hot-corners', + this._originals['enableHotCorners']); + } + + /** + * check whether lock dialog is currently showing + * + * @returns {boolean} + */ + isLocked() + { + return this._main.sessionMode.isLocked; + } + + /** + * enable window picker icon + * + * @returns {void} + */ + windowPickerIconEnable() + { + if (this._shellVersion < 40) { + return; + } + + this.UIStyleClassRemove(this._getAPIClassname('no-window-picker-icon')); + } + + /** + * disable window picker icon + * + * @returns {void} + */ + windowPickerIconDisable() + { + if (this._shellVersion < 40) { + return; + } + + this.UIStyleClassAdd(this._getAPIClassname('no-window-picker-icon')); + } + + /** + * show power icon + * + * @returns {void} + */ + powerIconShow() + { + this.UIStyleClassRemove(this._getAPIClassname('no-power-icon')); + } + + /** + * hide power icon + * + * @returns {void} + */ + powerIconHide() + { + this.UIStyleClassAdd(this._getAPIClassname('no-power-icon')); + } + + /** + * get primary monitor information + * + * @returns {false|Object} false when monitor does not exist | object + * x: int + * y: int + * width: int + * height: int + * geometryScale: float + */ + monitorGetInfo() + { + let pMonitor = this._main.layoutManager.primaryMonitor; + + if (!pMonitor) { + return false; + } + + return { + 'x': pMonitor.x, + 'y': pMonitor.y, + 'width': pMonitor.width, + 'height': pMonitor.height, + 'geometryScale': pMonitor.geometry_scale, + }; + } + + /** + * get panel position + * + * @returns {number} see PANEL_POSITION + */ + panelGetPosition() + { + if (this._panelPosition === undefined) { + return PANEL_POSITION.TOP; + } + + return this._panelPosition; + } + + /** + * move panel position + * + * @param {number} position see PANEL_POSITION + * @param {boolean} force allow to set even when the current position + * is the same + * + * @returns {void} + */ + panelSetPosition(position, force = false) + { + let monitorInfo = this.monitorGetInfo(); + let panelBox = this._main.layoutManager.panelBox; + + if (!force && position === this.panelGetPosition()) { + return; + } + + if (position === PANEL_POSITION.TOP) { + this._panelPosition = PANEL_POSITION.TOP; + if (this._workareasChangedSignal) { + global.display.disconnect(this._workareasChangedSignal); + this._workareasChangedSignal = null; + } + let topX = (monitorInfo) ? monitorInfo.x : 0; + let topY = (monitorInfo) ? monitorInfo.y : 0; + panelBox.set_position(topX, topY); + this.UIStyleClassRemove(this._getAPIClassname('bottom-panel')); + this._emitPanelPositionChanged(true); + return; + } + + this._panelPosition = PANEL_POSITION.BOTTOM; + + // only change it when a monitor detected + // 'workareas-changed' signal will do the job on next monitor detection + if (monitorInfo) { + let BottomX = monitorInfo.x; + let BottomY = monitorInfo.y + monitorInfo.height - this.panelGetSize(); + + panelBox.set_position(BottomX, BottomY); + this.UIStyleClassAdd(this._getAPIClassname('bottom-panel')); + } + + if (!this._workareasChangedSignal) { + this._workareasChangedSignal + = global.display.connect('workareas-changed', () => { + this.panelSetPosition(PANEL_POSITION.BOTTOM, true); + }); + } + + this._emitPanelPositionChanged(true); + } + + /** + * fix looking glass position + * + * @returns {void} + */ + _fixLookingGlassPosition() + { + let lookingGlassProto = this._lookingGlass.LookingGlass.prototype; + + if (this._originals['lookingGlassResize'] === undefined) { + this._originals['lookingGlassResize'] = lookingGlassProto._resize; + } + + if (this.panelGetPosition() === PANEL_POSITION.TOP && this.isPanelVisible()) { + + lookingGlassProto._resize = this._originals['lookingGlassResize']; + delete(lookingGlassProto._oldResize); + delete(this._originals['lookingGlassResize']); + if (this._main.lookingGlass) { + this._main.lookingGlass._resize(); + } + + return; + } + + if (lookingGlassProto._oldResize === undefined) { + lookingGlassProto._oldResize = this._originals['lookingGlassResize']; + + const Main = this._main; + + lookingGlassProto._resize = function () { + let panelHeight = Main.layoutManager.panelBox.height; + this._oldResize(); + this._targetY -= panelHeight; + this._hiddenY -= panelHeight; + }; + } + } + + /** + * enable panel arrow + * + * @returns {void} + */ + panelArrowEnable() + { + if (this._shellVersion >= 40) { + return; + } + + this.UIStyleClassRemove(this._getAPIClassname('no-panel-arrow')); + } + + /** + * disable panel arrow + * + * @returns {void} + */ + panelArrowDisable() + { + if (this._shellVersion >= 40) { + return; + } + + this.UIStyleClassAdd(this._getAPIClassname('no-panel-arrow')); + } + + /** + * enable panel notification icon + * + * @returns {void} + */ + panelNotificationIconEnable() + { + this.UIStyleClassRemove(this._getAPIClassname('no-panel-notification-icon')); + } + + /** + * disable panel notification icon + * + * @returns {void} + */ + panelNotificationIconDisable() + { + this.UIStyleClassAdd(this._getAPIClassname('no-panel-notification-icon')); + } + + /** + * disable app menu icon + * + * @returns {void} + */ + appMenuIconEnable() + { + this.UIStyleClassRemove(this._getAPIClassname('no-app-menu-icon')); + } + + /** + * disable app menu icon + * + * @returns {void} + */ + appMenuIconDisable() + { + this.UIStyleClassAdd(this._getAPIClassname('no-app-menu-icon')); + } + + /** + * disable app menu label + * + * @returns {void} + */ + appMenuLabelEnable() + { + this.UIStyleClassRemove(this._getAPIClassname('no-app-menu-label')); + } + + /** + * disable app menu label + * + * @returns {void} + */ + appMenuLabelDisable() + { + this.UIStyleClassAdd(this._getAPIClassname('no-app-menu-label')); + } + + /** + * set the clock menu position + * + * @param {number} pos see PANEL_BOX_POSITION + * @param {number} offset starts from 0 + * + * @returns {void} + */ + clockMenuPositionSet(pos, offset) + { + let dateMenu = this._main.panel.statusArea['dateMenu']; + + let panelBoxs = [ + this._main.panel._centerBox, + this._main.panel._rightBox, + this._main.panel._leftBox, + ]; + + let fromPos = -1; + let fromIndex = -1; + let toIndex = -1; + let childLength = 0; + for (let i = 0; i <= 2; i++) { + let child = panelBoxs[i].get_children(); + let childIndex = child.indexOf(dateMenu.container); + if (childIndex !== -1) { + fromPos = i; + fromIndex = childIndex; + childLength = panelBoxs[pos].get_children().length; + toIndex = (offset > childLength) ? childLength : offset; + break; + } + } + + // couldn't find the from and to position because it has been removed + if (fromPos === -1 || fromIndex === -1 || toIndex === -1) { + return; + } + + if (pos === fromPos && toIndex === fromIndex) { + return; + } + + panelBoxs[fromPos].remove_actor(dateMenu.container); + panelBoxs[pos].insert_child_at_index(dateMenu.container, toIndex); + + if (this.isLocked()) { + this.dateMenuHide(); + } + } + + /** + * enable show apps button + * + * @returns {void} + */ + showAppsButtonEnable() + { + this.UIStyleClassRemove(this._getAPIClassname('no-show-apps-button')); + } + + /** + * disable show apps button + * + * @returns {void} + */ + showAppsButtonDisable() + { + this.UIStyleClassAdd(this._getAPIClassname('no-show-apps-button')); + } + + /** + * set animation speed as default + * + * @returns {void} + */ + animationSpeedSetDefault() + { + if (this._originals['StSlowDownFactor'] === undefined) { + return; + } + + this._st.Settings.get().slow_down_factor = this._originals['StSlowDownFactor']; + } + + /** + * change animation speed + * + * @param {number} factor in float. bigger number means slower + * + * @returns {void} + */ + animationSpeedSet(factor) + { + if (this._originals['StSlowDownFactor'] === undefined) { + this._originals['StSlowDownFactor'] + = this._st.Settings.get().slow_down_factor; + } + + this._st.Settings.get().slow_down_factor = factor; + } + + /** + * set the enable animation as default + * + * @returns {void} + */ + enableAnimationsSetDefault() + { + if (this._originals['enableAnimations'] === undefined) { + return; + } + + let status = this._originals['enableAnimations']; + + this._interfaceSettings.set_boolean('enable-animations', status); + } + + /** + * set the enable animation status + * + * @param {boolean} status true to enable, false otherwise + * + * @returns {void} + */ + enableAnimationsSet(status) + { + if (this._originals['enableAnimations'] === undefined) { + this._originals['enableAnimations'] + = this._interfaceSettings.get_boolean('enable-animations'); + } + + this._interfaceSettings.set_boolean('enable-animations', status); + } + + /** + * add icon to the activities button + * + * @param {number} type see ICON_TYPE + * @param {string} icon file URI or icon name + * @param {boolean} monochrome to show icon in monochrome + * @param {boolean} holdLabel whether label should be available + * + * @returns {void} + */ + activitiesButtonAddIcon(type, icon, monochrome, holdLabel) + { + let iconSize = this.panelIconGetSize() - this._panel.APP_MENU_ICON_MARGIN; + let activities = this._main.panel.statusArea['activities']; + + this.activitiesButtonRemoveIcon(); + + if (!this._activitiesBtn) { + this._activitiesBtn = {}; + } + + let iconClassname + = (monochrome) + ? this._getAPIClassname('activities-button-icon-monochrome') + : this._getAPIClassname('activities-button-icon'); + + this._activitiesBtn.icon = new this._st.Icon({ + icon_size: iconSize, + style_class: iconClassname, + y_align: this._clutter.ActorAlign.CENTER, + }); + + if (monochrome) { + let effect = new this._clutter.DesaturateEffect(); + this._activitiesBtn.icon.add_effect(effect); + + this._activitiesBtn.icon.connect('style-changed', () => { + let themeNode = this._activitiesBtn.icon.get_theme_node(); + effect.enabled + = themeNode.get_icon_style() == this._st.IconStyle.SYMBOLIC; + }); + } + + switch (type) { + + case ICON_TYPE.NAME: + if (!icon) { + return; + } + this._activitiesBtn.icon.set_icon_name(icon); + break; + + case ICON_TYPE.URI: + let file = this._gio.File.new_for_uri(icon); + let filePathExists = file.query_exists(null); + if (!filePathExists) { + return; + } + let gicon = this._gio.icon_new_for_string(file.get_path()); + this._activitiesBtn.icon.set_gicon(gicon); + break; + + default: + return; + } + + activities.remove_actor(activities.label_actor); + + // add as icon + if (!holdLabel) { + this.UIStyleClassAdd(this._getAPIClassname('activities-button-no-label')); + activities.add_actor(this._activitiesBtn.icon); + return; + } + + // add as container (icon and text) + this._activitiesBtn.container = new this._st.BoxLayout(); + this._activitiesBtn.container.add_actor(this._activitiesBtn.icon); + this._activitiesBtn.container.add_actor(activities.label_actor); + + activities.add_actor(this._activitiesBtn.container); + } + + /** + * remove icon from activities button if it has been added before + * + * @returns {void} + */ + activitiesButtonRemoveIcon() + { + let activities = this._main.panel.statusArea['activities']; + + if (!this._activitiesBtn) { + return; + } + + if (this._activitiesBtn.container) { + this._activitiesBtn.container.remove_actor(this._activitiesBtn.icon); + this._activitiesBtn.container.remove_actor(activities.label_actor); + activities.remove_actor(this._activitiesBtn.container); + this._activitiesBtn.icon = null; + this._activitiesBtn.container = null; + } + + if (this._activitiesBtn.icon && activities.contains(this._activitiesBtn.icon)) { + activities.remove_actor(this._activitiesBtn.icon); + this._activitiesBtn.icon = null; + } + + if (!activities.contains(activities.label_actor)) { + activities.add_actor(activities.label_actor); + } + + this.UIStyleClassRemove(this._getAPIClassname('activities-button-no-label')); + } + + /** + * set activities button icon size + * + * @param {number} size 1-60 + * + * @returns {void} + */ + _activitiesButtonIconSetSize(size) + { + if (size < 1 || size > 60) { + return; + } + + let activities = this._main.panel.statusArea['activities']; + + if (!this._activitiesBtn || !this._activitiesBtn.icon) { + return; + } + + this._activitiesBtn.icon.icon_size = size - this._panel.APP_MENU_ICON_MARGIN; + } + + /** + * enable focus when window demands attention happens + * + * @returns {void} + */ + windowDemandsAttentionFocusEnable() + { + if (this._displayWindowDemandsAttentionSignal) { + return; + } + + let display = global.display; + + this._displayWindowDemandsAttentionSignal + = display.connect('window-demands-attention', (display, window) => { + if (!window || window.has_focus() || window.is_skip_taskbar()) { + return; + } + this._main.activateWindow(window); + }); + + // since removing '_windowDemandsAttentionId' doesn't have any effect + // we remove the original signal and re-connect it on disable + let signalId + = (this._shellVersion < 42) + ? this._main.windowAttentionHandler._windowDemandsAttentionId + : this._getSignalId(global.display, 'window-demands-attention'); + + display.disconnect(signalId); + } + + /** + * disable focus when window demands attention happens + * + * @returns {void} + */ + windowDemandsAttentionFocusDisable() + { + if (!this._displayWindowDemandsAttentionSignal) { + return; + } + + let display = global.display; + + display.disconnect(this._displayWindowDemandsAttentionSignal); + this._displayWindowDemandsAttentionSignal = null; + + let wah = this._main.windowAttentionHandler; + wah._windowDemandsAttentionId = display.connect('window-demands-attention', + wah._onWindowDemandsAttention.bind(wah)); + } + + /** + * set startup status + * + * @param {number} status see SHELL_STATUS for available status + * + * @returns {void} + */ + startupStatusSet(status) + { + if (this._shellVersion < 40) { + return; + } + + if (!this._main.layoutManager._startingUp) { + return; + } + + if (this._originals['sessionModeHasOverview'] === undefined) { + this._originals['sessionModeHasOverview'] + = this._main.sessionMode.hasOverview; + } + + let ControlsState = this._overviewControls.ControlsState; + let Controls = this._main.overview._overview.controls; + + switch (status) { + + case SHELL_STATUS.NONE: + this._main.sessionMode.hasOverview = false; + this._main.layoutManager.startInOverview = false; + Controls._stateAdjustment.value = ControlsState.HIDDEN; + break; + + case SHELL_STATUS.OVERVIEW: + this._main.sessionMode.hasOverview = true; + this._main.layoutManager.startInOverview = true; + break; + } + + if (!this._startupCompleteSignal) { + this._startupCompleteSignal + = this._main.layoutManager.connect('startup-complete', () => { + this._main.sessionMode.hasOverview + = this._originals['sessionModeHasOverview']; + }); + } + } + + /** + * set startup status to default + * + * @returns {void} + */ + startupStatusSetDefault() + { + if (this._originals['sessionModeHasOverview'] === undefined) { + return; + } + + if (this._startupCompleteSignal) { + this._main.layoutManager.disconnect(this._startupCompleteSignal); + } + } + + /** + * set dash icon size to default + * + * @returns {void} + */ + dashIconSizeSetDefault() + { + let classnameStarter = this._getAPIClassname('dash-icon-size'); + + DASH_ICON_SIZES.forEach(size => { + this.UIStyleClassRemove(classnameStarter + size); + }); + } + + /** + * set dash icon size + * + * @param {number} size in pixels + * see DASH_ICON_SIZES for available sizes + * + * @returns {void} + */ + dashIconSizeSet(size) + { + this.dashIconSizeSetDefault(); + + if (!DASH_ICON_SIZES.includes(size)) { + return; + } + + let classnameStarter = this._getAPIClassname('dash-icon-size'); + + this.UIStyleClassAdd(classnameStarter + size); + } + + /** + * disable workspaces in app grid + * + * @returns {void} + */ + workspacesInAppGridDisable() + { + if (this._shellVersion < 40) { + return; + } + + if (!this._originals['computeWorkspacesBoxForState']) { + let ControlsManagerLayout = this._overviewControls.ControlsManagerLayout; + this._originals['computeWorkspacesBoxForState'] + = ControlsManagerLayout.prototype._computeWorkspacesBoxForState; + } + + let controlsLayout = this._main.overview._overview._controls.layout_manager; + + controlsLayout._computeWorkspacesBoxForState = (state, ...args) => { + + let box = this._originals['computeWorkspacesBoxForState'].call( + controlsLayout, state, ...args); + + if (state === this._overviewControls.ControlsState.APP_GRID) { + box.set_size(box.get_width(), 0); + } + + return box; + }; + } + + /** + * enable workspaces in app grid + * + * @returns {void} + */ + workspacesInAppGridEnable() + { + if (!this._originals['computeWorkspacesBoxForState']) { + return; + } + + let controlsLayout = this._main.overview._overview._controls.layout_manager; + + controlsLayout._computeWorkspacesBoxForState + = this._originals['computeWorkspacesBoxForState']; + } + + /** + * change notification banner position + * + * @param {number} pos + * see XY_POSITION for available positions + * + * @returns {void} + */ + notificationBannerPositionSet(pos) + { + let messageTray = this._main.messageTray; + let bannerBin = messageTray._bannerBin; + + if (this._originals['bannerAlignmentX'] === undefined) { + this._originals['bannerAlignmentX'] = messageTray.bannerAlignment; + } + + if (this._originals['bannerAlignmentY'] === undefined) { + this._originals['bannerAlignmentY'] = bannerBin.get_y_align(); + } + + if (this._originals['hideNotification'] === undefined) { + this._originals['hideNotification'] = messageTray._hideNotification; + } + + // TOP + messageTray._hideNotification = this._originals['hideNotification']; + + bannerBin.set_y_align(this._clutter.ActorAlign.START); + + if (pos === XY_POSITION.TOP_START) { + messageTray.bannerAlignment = this._clutter.ActorAlign.START; + return; + } + + if (pos === XY_POSITION.TOP_END) { + messageTray.bannerAlignment = this._clutter.ActorAlign.END; + return; + } + + if (pos === XY_POSITION.TOP_CENTER) { + messageTray.bannerAlignment = this._clutter.ActorAlign.CENTER; + return; + } + + // BOTTOM + + // >> + // This block is going to fix the animation when the notification is + // in bottom area + // this is the same function from (ui.messageTray.messageTray._hideNotification) + // with clutter animation mode set to EASE. + // because the EASE_OUT_BACK (original code) causes glitch when + // the tray is on bottom + const State = this._messageTray.State; + const ANIMATION_TIME = this._messageTray.ANIMATION_TIME; + const Clutter = this._clutter; + const SHELL_VERSION = this._shellVersion; + + messageTray._hideNotification = function (animate) { + this._notificationFocusGrabber.ungrabFocus(); + + if (SHELL_VERSION >= 42) { + this._banner.disconnectObject(this); + } else { + if (this._bannerClickedId) { + this._banner.disconnect(this._bannerClickedId); + this._bannerClickedId = 0; + } + if (this._bannerUnfocusedId) { + this._banner.disconnect(this._bannerUnfocusedId); + this._bannerUnfocusedId = 0; + } + } + + this._resetNotificationLeftTimeout(); + this._bannerBin.remove_all_transitions(); + + if (animate) { + this._notificationState = State.HIDING; + this._bannerBin.ease({ + opacity: 0, + duration: ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE, + }); + this._bannerBin.ease({ + opacity: 0, + y: this._bannerBin.height, + duration: ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE, + onComplete: () => { + this._notificationState = State.HIDDEN; + this._hideNotificationCompleted(); + this._updateState(); + }, + }); + } else { + this._bannerBin.y = this._bannerBin.height; + this._bannerBin.opacity = 0; + this._notificationState = State.HIDDEN; + this._hideNotificationCompleted(); + } + } + // << + + bannerBin.set_y_align(this._clutter.ActorAlign.END); + + if (pos === XY_POSITION.BOTTOM_START) { + messageTray.bannerAlignment = this._clutter.ActorAlign.START; + return; + } + + if (pos === XY_POSITION.BOTTOM_END) { + messageTray.bannerAlignment = this._clutter.ActorAlign.END; + return; + } + + if (pos === XY_POSITION.BOTTOM_CENTER) { + messageTray.bannerAlignment = this._clutter.ActorAlign.CENTER; + return; + } + } + + /** + * set notification banner position to default position + * + * @returns {void} + */ + notificationBannerPositionSetDefault() + { + if (this._originals['bannerAlignmentX'] === undefined || + this._originals['bannerAlignmentY'] === undefined || + this._originals['hideNotification'] === undefined + ) { + return; + } + + let messageTray = this._main.messageTray; + let bannerBin = messageTray._bannerBin; + + messageTray.bannerAlignment = this._originals['bannerAlignmentX']; + bannerBin.set_y_align(this._originals['bannerAlignmentY']); + messageTray._hideNotification = this._originals['hideNotification']; + } + + /** + * set the workspace switcher to always/never show + * + * @param {boolean} show true for always show, false for never show + * + * @returns {void} + */ + workspaceSwitcherShouldShow(shouldShow = true) + { + if (this._shellVersion < 40) { + return; + } + + let ThumbnailsBoxProto = this._workspaceThumbnail.ThumbnailsBox.prototype; + + if (!this._originals['updateShouldShow']) { + this._originals['updateShouldShow'] = ThumbnailsBoxProto._updateShouldShow; + } + + ThumbnailsBoxProto._updateShouldShow = function () { + if (this._shouldShow === shouldShow) { + return; + } + this._shouldShow = shouldShow; + this.notify('should-show'); + }; + } + + /** + * set the always show workspace switcher status to default + * + * @returns {void} + */ + workspaceSwitcherShouldShowSetDefault() + { + if (!this._originals['updateShouldShow']) { + return; + } + + let ThumbnailsBoxProto = this._workspaceThumbnail.ThumbnailsBox.prototype; + ThumbnailsBoxProto._updateShouldShow = this._originals['updateShouldShow']; + } + + /** + * set panel button hpadding to default + * + * @returns {void} + */ + panelButtonHpaddingSetDefault() + { + if (this._panelButtonHpaddingSize === undefined) { + return; + } + + let classnameStarter = this._getAPIClassname('panel-button-padding-size'); + this.UIStyleClassRemove(classnameStarter + this._panelButtonHpaddingSize); + this._emitRefreshStyles(); + + delete this._panelButtonHpaddingSize; + } + + /** + * set panel button hpadding size + * + * @param {number} size in pixels (0 - 60) + * + * @returns {void} + */ + panelButtonHpaddingSizeSet(size) + { + this.panelButtonHpaddingSetDefault(); + + if (size < 0 || size > 60) { + return; + } + + this._panelButtonHpaddingSize = size; + + let classnameStarter = this._getAPIClassname('panel-button-padding-size'); + this.UIStyleClassAdd(classnameStarter + size); + this._emitRefreshStyles(); + } + + /** + * set panel indicator padding to default + * + * @returns {void} + */ + panelIndicatorPaddingSetDefault() + { + if (this._panelIndicatorPaddingSize === undefined) { + return; + } + + let classnameStarter = this._getAPIClassname('panel-indicator-padding-size'); + this.UIStyleClassRemove(classnameStarter + this._panelIndicatorPaddingSize); + this._emitRefreshStyles(); + + delete this._panelIndicatorPaddingSize; + } + + /** + * set panel indicator padding size + * + * @param {number} size in pixels (0 - 60) + * + * @returns {void} + */ + panelIndicatorPaddingSizeSet(size) + { + this.panelIndicatorPaddingSetDefault(); + + if (size < 0 || size > 60) { + return; + } + + this._panelIndicatorPaddingSize = size; + + let classnameStarter = this._getAPIClassname('panel-indicator-padding-size'); + this.UIStyleClassAdd(classnameStarter + size); + this._emitRefreshStyles(); + } + + /** + * get window preview prototype + * + * @returns {Object} + */ + _windowPreviewGetPrototype() + { + if (this._shellVersion <= 3.36) { + return this._workspace.WindowOverlay.prototype; + } + + return this._windowPreview.WindowPreview.prototype; + } + + /** + * enable window preview caption + * + * @returns {void} + */ + windowPreviewCaptionEnable() + { + if (!this._originals['windowPreviewGetCaption']) { + return; + } + + let windowPreviewProto = this._windowPreviewGetPrototype(); + windowPreviewProto._getCaption = this._originals['windowPreviewGetCaption']; + + this.UIStyleClassRemove(this._getAPIClassname('no-window-caption')); + } + + /** + * disable window preview caption + * + * @returns {void} + */ + windowPreviewCaptionDisable() + { + let windowPreviewProto = this._windowPreviewGetPrototype(); + + if (!this._originals['windowPreviewGetCaption']) { + this._originals['windowPreviewGetCaption'] = windowPreviewProto._getCaption; + } + + windowPreviewProto._getCaption = () => { + return ''; + }; + + this.UIStyleClassAdd(this._getAPIClassname('no-window-caption')); + } + + /** + * set workspace background border radius to default size + * + * @returns {void} + */ + workspaceBackgroundRadiusSetDefault() + { + if (this._workspaceBackgroundRadiusSize === undefined) { + return; + } + + let workspaceBackgroundProto = this._workspace.WorkspaceBackground.prototype; + + workspaceBackgroundProto._updateBorderRadius + = this._originals['workspaceBackgroundUpdateBorderRadius']; + + let classnameStarter = this._getAPIClassname('workspace-background-radius-size'); + this.UIStyleClassRemove(classnameStarter + this._workspaceBackgroundRadiusSize); + + delete this._workspaceBackgroundRadiusSize; + } + + /** + * set workspace background border radius size + * + * @param {number} size in pixels (0 - 60) + * + * @returns {void} + */ + workspaceBackgroundRadiusSet(size) + { + if (this._shellVersion < 40) { + return; + } + + if (size < 0 || size > 60) { + return; + } + + this.workspaceBackgroundRadiusSetDefault(); + + let workspaceBackgroundProto = this._workspace.WorkspaceBackground.prototype; + + if (!this._originals['workspaceBackgroundUpdateBorderRadius']) { + this._originals['workspaceBackgroundUpdateBorderRadius'] + = workspaceBackgroundProto._updateBorderRadius; + } + + const Util = this._util; + const St = this._st; + + workspaceBackgroundProto._updateBorderRadius = function () { + const {scaleFactor} = St.ThemeContext.get_for_stage(global.stage); + const cornerRadius = scaleFactor * size; + + const backgroundContent = this._bgManager.backgroundActor.content; + backgroundContent.rounded_clip_radius = + Util.lerp(0, cornerRadius, this._stateAdjustment.value); + } + + this._workspaceBackgroundRadiusSize = size; + + let classnameStarter = this._getAPIClassname('workspace-background-radius-size'); + this.UIStyleClassAdd(classnameStarter + size); + } + + /** + * enable workspace wraparound + * + * @returns {void} + */ + workspaceWraparoundEnable() + { + let metaWorkspaceProto = this._meta.Workspace.prototype; + + if (!this._originals['metaWorkspaceGetNeighbor']) { + this._originals['metaWorkspaceGetNeighbor'] + = metaWorkspaceProto.get_neighbor; + } + + const Meta = this._meta; + + metaWorkspaceProto.get_neighbor = function (dir) { + + let index = this.index(); + let lastIndex = global.workspace_manager.n_workspaces - 1; + let neighborIndex; + + if (dir === Meta.MotionDirection.UP || dir === Meta.MotionDirection.LEFT) { + // prev + neighborIndex = (index > 0) ? index - 1 : lastIndex; + } else { + // next + neighborIndex = (index < lastIndex) ? index + 1 : 0; + } + + return global.workspace_manager.get_workspace_by_index(neighborIndex); + }; + } + + /** + * disable workspace wraparound + * + * @returns {void} + */ + workspaceWraparoundDisable() + { + if (!this._originals['metaWorkspaceGetNeighbor']) { + return; + } + + let metaWorkspaceProto = this._meta.Workspace.prototype; + metaWorkspaceProto.get_neighbor = this._originals['metaWorkspaceGetNeighbor']; + } + + /** + * enable window preview close button + * + * @returns {void} + */ + windowPreviewCloseButtonEnable() + { + this.UIStyleClassRemove(this._getAPIClassname('no-window-close')); + } + + /** + * disable window preview close button + * + * @returns {void} + */ + windowPreviewCloseButtonDisable() + { + this.UIStyleClassAdd(this._getAPIClassname('no-window-close')); + } + + /** + * enable ripple box + * + * @returns {void} + */ + rippleBoxEnable() + { + this.UIStyleClassRemove(this._getAPIClassname('no-ripple-box')); + } + + /** + * disable ripple box + * + * @returns {void} + */ + rippleBoxDisable() + { + this.UIStyleClassAdd(this._getAPIClassname('no-ripple-box')); + } + + /** + * enable double super press to toggle app grid + * + * @returns {void} + */ + doubleSuperToAppGridEnable() + { + if (this._shellVersion < 40 || this._isDoubleSuperToAppGrid === true) { + return; + } + + if (!this._overlayKeyNewSignalId) { + return; + } + + global.display.disconnect(this._overlayKeyNewSignalId); + + this._gobject.signal_handler_unblock( + global.display, + this._overlayKeyOldSignalId + ); + + delete(this._overlayKeyNewSignalId); + delete(this._overlayKeyOldSignalId); + + this._isDoubleSuperToAppGrid = true; + } + + /** + * disable double super press to toggle app grid + * + * @returns {void} + */ + doubleSuperToAppGridDisable() + { + if (this._shellVersion < 40 || this._isDoubleSuperToAppGrid === false) { + return; + } + + this._overlayKeyOldSignalId = this._getSignalId(global.display, 'overlay-key'); + + if (!this._overlayKeyOldSignalId) { + return; + } + + this._gobject.signal_handler_block(global.display, this._overlayKeyOldSignalId); + + this._overlayKeyNewSignalId = global.display.connect('overlay-key', () => { + this._main.overview.toggle(); + }); + + this._isDoubleSuperToAppGrid = false; + } + + /** + * set default OSD position + * + * @returns {void} + */ + osdPositionSetDefault() + { + if (this._shellVersion < 42) { + return; + } + + if (!this._originals['osdWindowShow']) { + return; + } + + let osdWindowProto = this._osdWindow.OsdWindow.prototype; + + osdWindowProto.show = this._originals['osdWindowShow']; + + delete(osdWindowProto._oldShow); + delete(this._originals['osdWindowShow']); + + if ( + this._originals['osdWindowXAlign'] !== undefined && + this._originals['osdWindowYAlign'] !== undefined + ) { + let osdWindows = this._main.osdWindowManager._osdWindows; + osdWindows.forEach(osdWindow => { + osdWindow.x_align = this._originals['osdWindowXAlign']; + osdWindow.y_align = this._originals['osdWindowYAlign']; + }); + delete(this._originals['osdWindowXAlign']); + delete(this._originals['osdWindowYAlign']); + } + + this.UIStyleClassRemove(this._getAPIClassname('osd-position-top')); + this.UIStyleClassRemove(this._getAPIClassname('osd-position-bottom')); + this.UIStyleClassRemove(this._getAPIClassname('osd-position-center')); + } + + /** + * set OSD position + * + * @param int pos position XY_POSITION + * + * @returns {void} + */ + osdPositionSet(pos) + { + if (this._shellVersion < 42) { + return; + } + + let osdWindowProto = this._osdWindow.OsdWindow.prototype; + + if (!this._originals['osdWindowShow']) { + this._originals['osdWindowShow'] = osdWindowProto.show; + } + + if ( + this._originals['osdWindowXAlign'] === undefined || + this._originals['osdWindowYAlign'] === undefined + ) { + let osdWindows = this._main.osdWindowManager._osdWindows; + this._originals['osdWindowXAlign'] = osdWindows[0].x_align; + this._originals['osdWindowYAlign'] = osdWindows[0].y_align; + } + + if (osdWindowProto._oldShow === undefined) { + osdWindowProto._oldShow = this._originals['osdWindowShow']; + } + + let [xAlign, yAlign] = this._xyAlignGet(pos); + osdWindowProto.show = function () { + this.x_align = xAlign; + this.y_align = yAlign; + this._oldShow(); + }; + + if ( + pos === XY_POSITION.TOP_START || + pos === XY_POSITION.TOP_CENTER || + pos === XY_POSITION.TOP_END + ) { + this.UIStyleClassAdd(this._getAPIClassname('osd-position-top')); + } + + if ( + pos === XY_POSITION.BOTTOM_START || + pos === XY_POSITION.BOTTOM_CENTER || + pos === XY_POSITION.BOTTOM_END + ) { + this.UIStyleClassAdd(this._getAPIClassname('osd-position-bottom')); + } + + if ( + pos === XY_POSITION.CENTER_START || + pos === XY_POSITION.CENTER_CENTER || + pos === XY_POSITION.CENTER_END + ) { + this.UIStyleClassAdd(this._getAPIClassname('osd-position-center')); + } + } + + /** + * show weather in date menu + * + * @returns {void} + */ + weatherShow() + { + this.UIStyleClassRemove(this._getAPIClassname('no-weather')); + } + + /** + * hide weather in date menu + * + * @returns {void} + */ + weatherHide() + { + this.UIStyleClassAdd(this._getAPIClassname('no-weather')); + } + + /** + * show world clocks in date menu + * + * @returns {void} + */ + worldClocksShow() + { + this.UIStyleClassRemove(this._getAPIClassname('no-world-clocks')); + } + + /** + * hide world clocks in date menu + * + * @returns {void} + */ + worldClocksHide() + { + this.UIStyleClassAdd(this._getAPIClassname('no-world-clocks')); + } + + /** + * show events button in date menu + * + * @returns {void} + */ + eventsButtonShow() + { + this.UIStyleClassRemove(this._getAPIClassname('no-events-button')); + } + + /** + * hide events button in date menu + * + * @returns {void} + */ + eventsButtonHide() + { + this.UIStyleClassAdd(this._getAPIClassname('no-events-button')); + } + + /** + * show calendar in date menu + * + * @returns {void} + */ + calendarShow() + { + this._main.panel.statusArea.dateMenu._calendar.show(); + } + + /** + * hide calendar in date menu + * + * @returns {void} + */ + calendarHide() + { + this._main.panel.statusArea.dateMenu._calendar.hide(); + } + + /** + * set default panel icon size + * + * @returns {void} + */ + panelIconSetDefaultSize() + { + if (this._panelIconSize === undefined || !this._originals['panelIconSize']) { + return; + } + + let classnameStarter = this._getAPIClassname('panel-icon-size'); + this.UIStyleClassRemove(classnameStarter + this._panelIconSize); + this._emitRefreshStyles(); + + let defaultSize = this._originals['panelIconSize']; + this._panel.PANEL_ICON_SIZE = defaultSize; + this._main.panel.statusArea['dateMenu']._indicator.set_icon_size(defaultSize); + this._main.panel.statusArea['appMenu']._onIconThemeChanged(); + this._activitiesButtonIconSetSize(defaultSize); + + delete(this._panelIconSize); + } + + /** + * set panel icon size + * + * @param {number} size 1-60 + * + * @returns {void} + */ + panelIconSetSize(size) + { + if (size < 1 || size > 60) { + return; + } + + if (!this._originals['panelIconSize']) { + this._originals['panelIconSize'] = this._panel.PANEL_ICON_SIZE; + } + + let classnameStarter = this._getAPIClassname('panel-icon-size'); + this.UIStyleClassRemove(classnameStarter + this.panelIconGetSize()); + this.UIStyleClassAdd(classnameStarter + size); + this._emitRefreshStyles(); + + this._panel.PANEL_ICON_SIZE = size; + this._main.panel.statusArea['dateMenu']._indicator.set_icon_size(size); + this._main.panel.statusArea['appMenu']._onIconThemeChanged(); + this._activitiesButtonIconSetSize(size); + + this._panelIconSize = size; + } + + /** + * get panel icon size + * + * @returns {void} + */ + panelIconGetSize() + { + if (this._panelIconSize !== undefined) { + return this._panelIconSize; + } + + return this._panel.PANEL_ICON_SIZE; + } + + /** + * show dash separator + * + * @returns {void} + */ + dashSeparatorShow() + { + if (this._shellVersion < 40) { + return; + } + + this.UIStyleClassRemove(this._getAPIClassname('no-dash-separator')); + } + + /** + * hide dash separator + * + * @returns {void} + */ + dashSeparatorHide() + { + if (this._shellVersion < 40) { + return; + } + + this.UIStyleClassAdd(this._getAPIClassname('no-dash-separator')); + } + + /** + * get looking glass size + * + * @returns {array} + * width: int + * height: int + */ + _lookingGlassGetSize() + { + let lookingGlass = this._main.createLookingGlass(); + + return [lookingGlass.width, lookingGlass.height]; + } + + /** + * set default looking glass size + * + * @returns {void} + */ + lookingGlassSetDefaultSize() + { + if (!this._lookingGlassShowSignal) { + return; + } + + this._main.lookingGlass.disconnect(this._lookingGlassShowSignal); + this._main.lookingGlass._resize(); + + delete(this._lookingGlassShowSignal); + delete(this._lookingGlassOriginalSize); + delete(this._monitorsChangedSignal); + } + + /** + * set looking glass size + * + * @param {number} width in float + * @param {number} height in float + * + * @returns {void} + */ + lookingGlassSetSize(width, height) + { + let lookingGlass = this._main.createLookingGlass(); + + if (!this._lookingGlassOriginalSize) { + this._lookingGlassOriginalSize = this._lookingGlassGetSize(); + } + + if (this._lookingGlassShowSignal) { + lookingGlass.disconnect(this._lookingGlassShowSignal); + delete(this._lookingGlassShowSignal); + } + + this._lookingGlassShowSignal = lookingGlass.connect('show', () => { + let [, currentHeight] = this._lookingGlassGetSize(); + let [originalWidth, originalHeight] = this._lookingGlassOriginalSize; + + let monitorInfo = this.monitorGetInfo(); + + let dialogWidth + = (width !== null) + ? monitorInfo.width * width + : originalWidth; + + let x = monitorInfo.x + (monitorInfo.width - dialogWidth) / 2; + lookingGlass.set_x(x); + + let keyboardHeight = this._main.layoutManager.keyboardBox.height; + let availableHeight = monitorInfo.height - keyboardHeight; + let dialogHeight + = (height !== null) + ? Math.min(monitorInfo.height * height, availableHeight * 0.9) + : originalHeight; + + let hiddenY = lookingGlass._hiddenY + currentHeight - dialogHeight; + lookingGlass.set_y(hiddenY); + lookingGlass._hiddenY = hiddenY; + + lookingGlass.set_size(dialogWidth, dialogHeight); + }); + + if (!this._monitorsChangedSignal) { + this._monitorsChangedSignal = this._main.layoutManager.connect('monitors-changed', + () => { + this.lookingGlassSetSize(width, height); + }); + } + } + + /** + * show screenshot in window menu + * + * @returns {void} + */ + screenshotInWindowMenuShow() + { + if (this._shellVersion < 42) { + return; + } + + let windowMenuProto = this._windowMenu.WindowMenu.prototype; + + if (windowMenuProto._oldBuildMenu === undefined) { + return; + } + + windowMenuProto._buildMenu = this._originals['WindowMenubuildMenu']; + + delete(windowMenuProto._oldBuildMenu); + } + + /** + * hide screenshot in window menu + * + * @returns {void} + */ + screenshotInWindowMenuHide() + { + if (this._shellVersion < 42) { + return; + } + + let windowMenuProto = this._windowMenu.WindowMenu.prototype; + + if (!this._originals['WindowMenubuildMenu']) { + this._originals['WindowMenubuildMenu'] = windowMenuProto._buildMenu; + } + + if (windowMenuProto._oldBuildMenu === undefined) { + windowMenuProto._oldBuildMenu = this._originals['WindowMenubuildMenu']; + } + + windowMenuProto._buildMenu = function (window) { + this._oldBuildMenu(window); + this.firstMenuItem.hide(); + }; + } + + /** + * set default alt tab window preview size + * + * @returns {void} + */ + altTabWindowPreviewSetDefaultSize() + { + if (!this._originals['altTabWindowPreviewSize']) { + return; + } + + this._altTab.WINDOW_PREVIEW_SIZE = this._originals['altTabWindowPreviewSize']; + } + + /** + * set alt tab window preview size + * + * @param {number} size 1-512 + * + * @returns {void} + */ + altTabWindowPreviewSetSize(size) + { + if (size < 1 || size > 512) { + return; + } + + if (!this._originals['altTabWindowPreviewSize']) { + this._originals['altTabWindowPreviewSize'] = this._altTab.WINDOW_PREVIEW_SIZE; + } + + this._altTab.WINDOW_PREVIEW_SIZE = size; + } + + /** + * set default alt tab small icon size + * + * @returns {void} + */ + altTabSmallIconSetDefaultSize() + { + if (!this._originals['altTabAppIconSizeSmall']) { + return; + } + + this._altTab.APP_ICON_SIZE_SMALL = this._originals['altTabAppIconSizeSmall']; + } + + /** + * set alt tab small icon size + * + * @param {number} size 1-512 + * + * @returns {void} + */ + altTabSmallIconSetSize(size) + { + if (size < 1 || size > 512) { + return; + } + + if (!this._originals['altTabAppIconSizeSmall']) { + this._originals['altTabAppIconSizeSmall'] = this._altTab.APP_ICON_SIZE_SMALL; + } + + this._altTab.APP_ICON_SIZE_SMALL = size; + } + + /** + * set default alt tab icon size + * + * @returns {void} + */ + altTabIconSetDefaultSize() + { + if (!this._originals['altTabAppIconSize']) { + return; + } + + this._altTab.APP_ICON_SIZE = this._originals['altTabAppIconSize']; + } + + /** + * set alt tab icon size + * + * @param {number} size 1-512 + * + * @returns {void} + */ + altTabIconSetSize(size) + { + if (size < 1 || size > 512) { + return; + } + + if (!this._originals['altTabAppIconSize']) { + this._originals['altTabAppIconSize'] = this._altTab.APP_ICON_SIZE; + } + + this._altTab.APP_ICON_SIZE = size; + } +} + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Manager.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Manager.js new file mode 100644 index 0000000..68d1cc0 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Manager.js @@ -0,0 +1,1463 @@ +/** + * Manager Library + * + * @author Javad Rahmatzadeh + * @copyright 2020-2022 + * @license GPL-3.0-only + */ + +/** + * Apply settings to the GNOME Shell + */ +var Manager = class +{ + /** + * Class Constructor + * + * @param {Object} dependencies + * 'API' instance of lib::API + * 'Settings' instance of Gio::Settings + * @param {number} shellVersion float in major.minor format + */ + constructor(dependencies, shellVersion) + { + this._api = dependencies['API'] || null; + this._settings = dependencies['Settings'] || null; + + this._shellVersion = shellVersion; + } + + /** + * register all signals for settings + * + * @returns {void} + */ + registerSettingsSignals() + { + this._settings.connect('changed::panel', () => { + this._applyPanel(false); + }); + + this._settings.connect('changed::panel-in-overview', () => { + this._applyPanel(false); + }); + + this._settings.connect('changed::search', () => { + this._applySearch(false); + }); + + this._settings.connect('changed::dash', () => { + this._applyDash(false); + }); + + this._settings.connect('changed::osd', () => { + this._applyOSD(false); + }); + + this._settings.connect('changed::workspace-popup', () => { + this._applyWorkspacePopup(false); + }); + + this._settings.connect('changed::workspace', () => { + this._applyWorkspace(false); + }); + + this._settings.connect('changed::background-menu', () => { + this._applyBackgroundMenu(false); + }); + + this._settings.connect('changed::gesture', () => { + this._applyGesture(false); + }); + + this._settings.connect('changed::hot-corner', () => { + this._applyHotCorner(false); + }); + + this._settings.connect('changed::theme', () => { + this._applyTheme(false); + }); + + this._settings.connect('changed::activities-button', () => { + this._applyActivitiesButton(false); + }); + + this._settings.connect('changed::app-menu', () => { + this._applyAppMenu(false); + }); + + this._settings.connect('changed::clock-menu', () => { + this._applyClockMenu(false); + }); + + this._settings.connect('changed::keyboard-layout', () => { + this._applyKeyboardLayout(false); + }); + + this._settings.connect('changed::accessibility-menu', () => { + this._applyAccessibilityMenu(false); + }); + + this._settings.connect('changed::aggregate-menu', () => { + this._applyAggregateMenu(false); + }); + + this._settings.connect('changed::quick-settings', () => { + this._applyQuickSettings(false); + }); + + this._settings.connect('changed::panel-corner-size', () => { + this._applyPanelCornerSize(false); + }); + + this._settings.connect('changed::window-picker-icon', () => { + this._applyWindowPickerIcon(false); + }); + + this._settings.connect('changed::type-to-search', () => { + this._applyTypeToSearch(false); + }); + + this._settings.connect('changed::workspace-switcher-size', () => { + this._applyWorkspaceSwitcherSize(false); + }); + + this._settings.connect('changed::power-icon', () => { + this._applyPowerIcon(false); + }); + + this._settings.connect('changed::top-panel-position', () => { + this._applyTopPanelPosition(false); + }); + + this._settings.connect('changed::panel-arrow', () => { + this._applyPanelArrow(false); + }); + + this._settings.connect('changed::panel-notification-icon', () => { + this._applyPanelNotificationIcon(false); + }); + + this._settings.connect('changed::app-menu-icon', () => { + this._applyAppMenuIcon(false); + }); + + this._settings.connect('changed::app-menu-label', () => { + this._applyAppMenuLabel(false); + }); + + this._settings.connect('changed::clock-menu-position', () => { + this._applyClockMenuPosition(false); + }); + + this._settings.connect('changed::clock-menu-position-offset', () => { + this._applyClockMenuPosition(false); + }); + + this._settings.connect('changed::show-apps-button', () => { + this._applyShowAppsButton(false); + }); + + this._settings.connect('changed::animation', () => { + this._applyAnimation(false); + }); + + this._settings.connect('changed::activities-button-icon-path', () => { + this._applyActivitiesButtonIcon(false); + }); + + this._settings.connect('changed::activities-button-icon-monochrome', () => { + this._applyActivitiesButtonIcon(false); + }); + + this._settings.connect('changed::activities-button-label', () => { + this._applyActivitiesButtonIcon(false); + }); + + this._settings.connect('changed::window-demands-attention-focus', () => { + this._applyWindowDemandsAttentionFocus(false); + }); + + this._settings.connect('changed::dash-icon-size', () => { + this._applyDashIconSize(false); + }); + + this._settings.connect('changed::startup-status', () => { + this._applyStartupStatus(false); + }); + + this._settings.connect('changed::workspaces-in-app-grid', () => { + this._applyWorkspacesInAppGrid(false); + }); + + this._settings.connect('changed::notification-banner-position', () => { + this._applyNotificationBannerPosition(false); + }); + + this._settings.connect('changed::workspace-switcher-should-show', () => { + this._applyWorkspaceSwitcherShouldShow(false); + }); + + this._settings.connect('changed::panel-size', () => { + this._applyPanelSize(false); + }); + + this._settings.connect('changed::panel-button-padding-size', () => { + this._applyPanelButtonPaddingSize(false); + }); + + this._settings.connect('changed::panel-indicator-padding-size', () => { + this._applyPanelIndicatorPaddingSize(false); + }); + + this._settings.connect('changed::window-preview-caption', () => { + this._applyWindowPreviewCaption(false); + }); + + this._settings.connect('changed::window-preview-close-button', () => { + this._applyWindowPreviewCloseButton(false); + }); + + this._settings.connect('changed::workspace-background-corner-size', () => { + this._applyWorkspaceBackgroundCornerSize(false); + }); + + this._settings.connect('changed::workspace-wrap-around', () => { + this._applyWorkspaceWrapAround(false); + }); + + this._settings.connect('changed::ripple-box', () => { + this._applyRippleBox(false); + }); + + this._settings.connect('changed::double-super-to-appgrid', () => { + this._applyDoubleSuperToAppgrid(false); + }); + + this._settings.connect('changed::world-clock', () => { + this._applyWorldClock(false); + }); + + this._settings.connect('changed::weather', () => { + this._applyWeather(false); + }); + + this._settings.connect('changed::calendar', () => { + this._applyCalendar(false); + }); + + this._settings.connect('changed::events-button', () => { + this._applyEventsButton(false); + }); + + this._settings.connect('changed::panel-icon-size', () => { + this._applyPanelIconSize(false); + }); + + this._settings.connect('changed::dash-separator', () => { + this._applyDashSeparator(false); + }); + + this._settings.connect('changed::looking-glass-width', () => { + this._applyLookingGlassSize(false); + }); + + this._settings.connect('changed::looking-glass-height', () => { + this._applyLookingGlassSize(false); + }); + + this._settings.connect('changed::osd-position', () => { + this._applyOSDPosition(false); + }); + + this._settings.connect('changed::window-menu-take-screenshot-button', () => { + this._applyWindowMenuTakeScreenshotButton(false); + }); + + this._settings.connect('changed::alt-tab-window-preview-size', () => { + this._applyAltTabWindowPreviewSize(false); + }); + + this._settings.connect('changed::alt-tab-small-icon-size', () => { + this._applyAltTabSmallIconSize(false); + }); + + this._settings.connect('changed::alt-tab-icon-size', () => { + this._applyAltTabIconSize(false); + }); + } + + /** + * apply everything to the GNOME Shell + * + * @returns {void} + */ + applyAll() + { + this._applyTheme(false); + this._applyPanel(false); + this._applySearch(false); + this._applyDash(false); + this._applyOSD(false); + this._applyWorkspacePopup(false); + this._applyWorkspace(false); + this._applyBackgroundMenu(false); + this._applyGesture(false); + this._applyHotCorner(false); + this._applyActivitiesButton(false); + this._applyAppMenu(false); + this._applyClockMenu(false); + this._applyKeyboardLayout(false); + this._applyAccessibilityMenu(false); + this._applyAggregateMenu(false); + this._applyQuickSettings(false); + this._applyPanelCornerSize(false); + this._applyWindowPickerIcon(false); + this._applyTypeToSearch(false); + this._applyWorkspaceSwitcherSize(false); + this._applyPowerIcon(false); + this._applyTopPanelPosition(false); + this._applyPanelArrow(false); + this._applyPanelNotificationIcon(false); + this._applyAppMenuIcon(false); + this._applyAppMenuLabel(false); + this._applyClockMenuPosition(false); + this._applyShowAppsButton(false); + this._applyAnimation(false); + this._applyActivitiesButtonIcon(false); + this._applyWindowDemandsAttentionFocus(false); + this._applyDashIconSize(false); + this._applyStartupStatus(false); + this._applyWorkspacesInAppGrid(false); + this._applyNotificationBannerPosition(false); + this._applyWorkspaceSwitcherShouldShow(false); + this._applyPanelSize(false); + this._applyPanelButtonPaddingSize(false); + this._applyPanelIndicatorPaddingSize(false); + this._applyWindowPreviewCaption(false); + this._applyWindowPreviewCloseButton(false); + this._applyWorkspaceBackgroundCornerSize(false); + this._applyWorkspaceWrapAround(false); + this._applyRippleBox(false); + this._applyDoubleSuperToAppgrid(false); + this._applyWorldClock(false); + this._applyWeather(false); + this._applyPanelIconSize(false); + this._applyEventsButton(false); + this._applyCalendar(false); + this._applyDashSeparator(false); + this._applyLookingGlassSize(false); + this._applyOSDPosition(false); + this._applyWindowMenuTakeScreenshotButton(false); + this._applyAltTabWindowPreviewSize(false); + this._applyAltTabSmallIconSize(false); + this._applyAltTabIconSize(false); + } + + /** + * revert everything done by this class to the GNOME Shell + * + * @returns {void} + */ + revertAll() + { + this._applyTheme(true); + this._applyPanel(true); + this._applySearch(true); + this._applyDash(true); + this._applyOSD(true); + this._applyWorkspace(true); + this._applyWorkspacePopup(true); + this._applyBackgroundMenu(true); + this._applyGesture(true); + this._applyHotCorner(true); + this._applyActivitiesButton(true); + this._applyAppMenu(true); + this._applyClockMenu(true); + this._applyKeyboardLayout(true); + this._applyAccessibilityMenu(true); + this._applyAggregateMenu(true); + this._applyQuickSettings(true); + this._applyPanelCornerSize(true); + this._applyWindowPickerIcon(true); + this._applyTypeToSearch(true); + this._applyWorkspaceSwitcherSize(true); + this._applyPowerIcon(true); + this._applyTopPanelPosition(true); + this._applyPanelArrow(true); + this._applyPanelNotificationIcon(true); + this._applyAppMenuIcon(true); + this._applyAppMenuLabel(true); + this._applyClockMenuPosition(true); + this._applyShowAppsButton(true); + this._applyAnimation(true); + this._applyActivitiesButtonIcon(true); + this._applyWindowDemandsAttentionFocus(true); + this._applyDashIconSize(true); + this._applyStartupStatus(true); + this._applyWorkspacesInAppGrid(true); + this._applyNotificationBannerPosition(true); + this._applyWorkspaceSwitcherShouldShow(true); + this._applyPanelSize(true); + this._applyPanelButtonPaddingSize(true); + this._applyPanelIndicatorPaddingSize(true); + this._applyWindowPreviewCaption(true); + this._applyWindowPreviewCloseButton(true); + this._applyWorkspaceBackgroundCornerSize(true); + this._applyWorkspaceWrapAround(true); + this._applyRippleBox(true); + this._applyDoubleSuperToAppgrid(true); + this._applyWorldClock(true); + this._applyWeather(true); + this._applyPanelIconSize(true); + this._applyEventsButton(true); + this._applyCalendar(true); + this._applyDashSeparator(true); + this._applyLookingGlassSize(true); + this._applyOSDPosition(true); + this._applyWindowMenuTakeScreenshotButton(true); + this._applyAltTabWindowPreviewSize(true); + this._applyAltTabSmallIconSize(true); + this._applyAltTabIconSize(true); + } + + /** + * apply panel settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanel(forceOriginal) + { + let panel = this._settings.get_boolean('panel'); + let panelInOverview = this._settings.get_boolean('panel-in-overview'); + + if (forceOriginal || panel) { + this._api.panelShow(); + } else { + let mode = (panelInOverview) ? 1 : 0; + this._api.panelHide(mode, 0); + } + } + + /** + * apply search settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applySearch(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('search')) { + this._api.searchEntryShow(false); + } else { + this._api.searchEntryHide(false); + } + } + + /** + * apply type to search settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyTypeToSearch(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('type-to-search')) { + this._api.startSearchEnable(); + } else { + this._api.startSearchDisable(); + } + } + + /** + * apply dash settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyDash(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('dash')) { + this._api.dashShow(); + } else { + this._api.dashHide(); + } + } + + /** + * apply osd settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyOSD(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('osd')) { + this._api.OSDEnable(); + } else { + this._api.OSDDisable(); + } + } + + /** + * apply workspace popup settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspacePopup(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('workspace-popup')) { + this._api.workspacePopupEnable(); + } else { + this._api.workspacePopupDisable(); + } + } + + /** + * apply workspace settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspace(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('workspace')) { + this._api.workspaceSwitcherShow(); + } else { + this._api.workspaceSwitcherHide(); + } + } + + /** + * apply background menu settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyBackgroundMenu(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('background-menu')) { + this._api.backgroundMenuEnable(); + } else { + this._api.backgroundMenuDisable(); + } + } + + /** + * apply gesture settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyGesture(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('gesture')) { + this._api.gestureEnable(); + } else { + this._api.gestureDisable(); + } + } + + /** + * apply hot corner settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyHotCorner(forceOriginal) + { + if (this._shellVersion >= 41) { + return; + } + + if (forceOriginal) { + this._api.hotCornersDefault(); + } else if (!this._settings.get_boolean('hot-corner')) { + this._api.hotCornersDisable(); + } else { + this._api.hotCornersEnable(); + } + } + + /** + * apply theme settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyTheme(forceOriginal) + { + let className = 'just-perfection'; + let fallbackClassName = 'just-perfection-gnome3'; + let fourtySecondGenClassName = 'just-perfection-gnome4x-2nd-gen'; + + if (forceOriginal || !this._settings.get_boolean('theme')) { + this._api.UIStyleClassRemove(className); + this._api.UIStyleClassRemove(fallbackClassName); + this._api.UIStyleClassRemove(fourtySecondGenClassName); + } else { + this._api.UIStyleClassAdd(className); + if (this._shellVersion < 40) { + this._api.UIStyleClassAdd(fallbackClassName); + } + if (this._shellVersion >= 42) { + this._api.UIStyleClassAdd(fourtySecondGenClassName); + } + } + } + + /** + * apply activites button settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyActivitiesButton(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('activities-button')) { + this._api.activitiesButtonShow(); + } else { + this._api.activitiesButtonHide(); + } + } + + /** + * apply app menu settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAppMenu(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('app-menu')) { + this._api.appMenuShow(); + } else { + this._api.appMenuHide(); + } + } + + /** + * apply clock menu (aka date menu) settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyClockMenu(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('clock-menu')) { + this._api.dateMenuShow(); + } else { + this._api.dateMenuHide(); + } + } + + /** + * apply keyboard layout settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyKeyboardLayout(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('keyboard-layout')) { + this._api.keyboardLayoutShow(); + } else { + this._api.keyboardLayoutHide(); + } + } + + /** + * apply accessibility menu settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAccessibilityMenu(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('accessibility-menu')) { + this._api.accessibilityMenuShow(); + } else { + this._api.accessibilityMenuHide(); + } + } + + /** + * apply aggregate menu settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAggregateMenu(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('aggregate-menu')) { + this._api.aggregateMenuShow(); + } else { + this._api.aggregateMenuHide(); + } + } + + /** + * apply quick settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyQuickSettings(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('quick-settings')) { + this._api.quickSettingsMenuShow(); + } else { + this._api.quickSettingsMenuHide(); + } + } + + /** + * apply panel corner size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelCornerSize(forceOriginal) + { + let size = this._settings.get_int('panel-corner-size'); + + if (forceOriginal || size === 0) { + this._api.panelCornerSetDefault(); + } else { + this._api.panelCornerSetSize(size - 1); + } + } + + /** + * apply window picker icon settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWindowPickerIcon(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('window-picker-icon')) { + this._api.windowPickerIconEnable(); + } else { + this._api.windowPickerIconDisable(); + } + } + + /** + * apply workspace switcher size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspaceSwitcherSize(forceOriginal) + { + let size = this._settings.get_int('workspace-switcher-size'); + + if (forceOriginal || size === 0) { + this._api.workspaceSwitcherSetDefaultSize(); + } else { + this._api.workspaceSwitcherSetSize(size / 100, false); + } + } + + /** + * apply power icon settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPowerIcon(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('power-icon')) { + this._api.powerIconShow(); + } else { + this._api.powerIconHide(); + } + } + + /** + * apply top panel position settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyTopPanelPosition(forceOriginal) + { + if (forceOriginal || this._settings.get_int('top-panel-position') === 0) { + this._api.panelSetPosition(0); + } else { + this._api.panelSetPosition(1); + } + } + + /** + * apply panel arrow settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelArrow(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('panel-arrow')) { + this._api.panelArrowEnable(); + } else { + this._api.panelArrowDisable(); + } + } + + /** + * apply panel notification icon settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelNotificationIcon(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('panel-notification-icon')) { + this._api.panelNotificationIconEnable(); + } else { + this._api.panelNotificationIconDisable(); + } + } + + /** + * apply app menu icon settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAppMenuIcon(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('app-menu-icon')) { + this._api.appMenuIconEnable(); + } else { + this._api.appMenuIconDisable(); + } + } + + /** + * apply app menu label settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAppMenuLabel(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('app-menu-label')) { + this._api.appMenuLabelEnable(); + } else { + this._api.appMenuLabelDisable(); + } + } + + /** + * apply clock menu position settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyClockMenuPosition(forceOriginal) + { + if (forceOriginal) { + this._api.clockMenuPositionSet(0, 0); + } else { + let pos = this._settings.get_int('clock-menu-position'); + let offset = this._settings.get_int('clock-menu-position-offset'); + this._api.clockMenuPositionSet(pos, offset); + } + } + + /** + * apply show apps button settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyShowAppsButton(forceOriginal) + { + if (forceOriginal || this._settings.get_boolean('show-apps-button')) { + this._api.showAppsButtonEnable(); + } else { + this._api.showAppsButtonDisable(); + } + } + + /** + * apply animation settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAnimation(forceOriginal) + { + let animation = this._settings.get_int('animation'); + + let factors = [ + 0.4, // fastest + 0.6, // faster + 0.8, // fast + 1.3, // slow + 1.6, // slower + 2.8, // slowest + ]; + + if (forceOriginal) { + this._api.animationSpeedSetDefault(); + this._api.enableAnimationsSetDefault(); + } else if (animation === 0) { + // disabled + this._api.animationSpeedSetDefault(); + this._api.enableAnimationsSet(false); + } else if (animation === 1) { + // default speed + this._api.animationSpeedSetDefault(); + this._api.enableAnimationsSet(true); + } else if (factors[animation - 2] !== undefined) { + // custom speed + this._api.animationSpeedSet(factors[animation - 2]); + this._api.enableAnimationsSet(true); + } + } + + /** + * apply show apps button settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyActivitiesButtonIcon(forceOriginal) + { + let iconPath = this._settings.get_string('activities-button-icon-path'); + let monochrome = this._settings.get_boolean('activities-button-icon-monochrome'); + let label = this._settings.get_boolean('activities-button-label'); + + if (forceOriginal) { + this._api.activitiesButtonRemoveIcon(); + } else { + this._api.activitiesButtonAddIcon(1, iconPath, monochrome, label); + } + } + + /** + * apply window demands attention focus settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWindowDemandsAttentionFocus(forceOriginal) + { + let focus = this._settings.get_boolean('window-demands-attention-focus'); + + if (forceOriginal || !focus) { + this._api.windowDemandsAttentionFocusDisable(); + } else { + this._api.windowDemandsAttentionFocusEnable(); + } + } + + /** + * apply dash icon size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyDashIconSize(forceOriginal) + { + let size = this._settings.get_int('dash-icon-size'); + + if (forceOriginal || size === 0) { + this._api.dashIconSizeSetDefault(); + } else { + this._api.dashIconSizeSet(size); + } + } + + /** + * apply startup status settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyStartupStatus(forceOriginal) + { + let status = this._settings.get_int('startup-status'); + + if (forceOriginal) { + this._api.startupStatusSetDefault(); + } else { + this._api.startupStatusSet(status); + } + } + + /** + * apply workspaces in app grid status settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspacesInAppGrid(forceOriginal) + { + let status = this._settings.get_boolean('workspaces-in-app-grid'); + + if (forceOriginal || status) { + this._api.workspacesInAppGridEnable(); + } else { + this._api.workspacesInAppGridDisable(); + } + } + + /** + * apply notification banner position settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyNotificationBannerPosition(forceOriginal) + { + let pos = this._settings.get_int('notification-banner-position'); + + if (forceOriginal) { + this._api.notificationBannerPositionSetDefault(); + } else { + this._api.notificationBannerPositionSet(pos); + } + } + + /** + * apply workspace switcher should show settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspaceSwitcherShouldShow(forceOriginal) + { + let shouldShow = this._settings.get_boolean('workspace-switcher-should-show'); + + if (forceOriginal || !shouldShow) { + this._api.workspaceSwitcherShouldShowSetDefault(); + } else { + this._api.workspaceSwitcherShouldShow(true); + } + } + + /** + * apply panel size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelSize(forceOriginal) + { + let size = this._settings.get_int('panel-size'); + + if (forceOriginal || size === 0) { + this._api.panelSetDefaultSize(); + } else { + this._api.panelSetSize(size, false); + } + } + + /** + * apply panel button padding size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelButtonPaddingSize(forceOriginal) + { + let size = this._settings.get_int('panel-button-padding-size'); + + if (forceOriginal || size === 0) { + this._api.panelButtonHpaddingSetDefault(); + } else { + this._api.panelButtonHpaddingSizeSet(size - 1); + } + } + + /** + * apply panel indicator padding size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelIndicatorPaddingSize(forceOriginal) + { + let size = this._settings.get_int('panel-indicator-padding-size'); + + if (forceOriginal || size === 0) { + this._api.panelIndicatorPaddingSetDefault(); + } else { + this._api.panelIndicatorPaddingSizeSet(size - 1); + } + } + + /** + * apply window preview caption settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWindowPreviewCaption(forceOriginal) + { + let status = this._settings.get_boolean('window-preview-caption'); + + if (forceOriginal || status) { + this._api.windowPreviewCaptionEnable(); + } else { + this._api.windowPreviewCaptionDisable(); + } + } + + /** + * apply window preview close button settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWindowPreviewCloseButton(forceOriginal) + { + let status = this._settings.get_boolean('window-preview-close-button'); + + if (forceOriginal || status) { + this._api.windowPreviewCloseButtonEnable(); + } else { + this._api.windowPreviewCloseButtonDisable(); + } + } + + /** + * apply workspace background corner size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspaceBackgroundCornerSize(forceOriginal) + { + let size = this._settings.get_int('workspace-background-corner-size'); + + if (forceOriginal || size === 0) { + this._api.workspaceBackgroundRadiusSetDefault(); + } else { + this._api.workspaceBackgroundRadiusSet(size - 1); + } + } + + /** + * apply workspace wrap around settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorkspaceWrapAround(forceOriginal) + { + let status = this._settings.get_boolean('workspace-wrap-around'); + + if (forceOriginal || !status) { + this._api.workspaceWraparoundDisable(); + } else { + this._api.workspaceWraparoundEnable(); + } + } + + /** + * apply ripple box settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyRippleBox(forceOriginal) + { + let status = this._settings.get_boolean('ripple-box'); + + if (forceOriginal || status) { + this._api.rippleBoxEnable(); + } else { + this._api.rippleBoxDisable(); + } + } + + /** + * apply double super to appgrid settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyDoubleSuperToAppgrid(forceOriginal) + { + let status = this._settings.get_boolean('double-super-to-appgrid'); + + if (forceOriginal || status) { + this._api.doubleSuperToAppGridEnable(); + } else { + this._api.doubleSuperToAppGridDisable(); + } + } + + /** + * apply world clock settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWorldClock(forceOriginal) + { + let status = this._settings.get_boolean('world-clock'); + + if (forceOriginal || status) { + this._api.worldClocksShow(); + } else { + this._api.worldClocksHide(); + } + } + + /** + * apply weather settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWeather(forceOriginal) + { + let status = this._settings.get_boolean('weather'); + + if (forceOriginal || status) { + this._api.weatherShow(); + } else { + this._api.weatherHide(); + } + } + + /** + * apply calendar settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyCalendar(forceOriginal) + { + let status = this._settings.get_boolean('calendar'); + + if (forceOriginal || status) { + this._api.calendarShow(); + } else { + this._api.calendarHide(); + } + } + + /** + * apply events button settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyEventsButton(forceOriginal) + { + let status = this._settings.get_boolean('events-button'); + + if (forceOriginal || status) { + this._api.eventsButtonShow(); + } else { + this._api.eventsButtonHide(); + } + } + + /** + * apply panel icon size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyPanelIconSize(forceOriginal) + { + let size = this._settings.get_int('panel-icon-size'); + + if (forceOriginal || size === 0) { + this._api.panelIconSetDefaultSize(); + } else { + this._api.panelIconSetSize(size); + } + } + + /** + * apply dash separator settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyDashSeparator(forceOriginal) + { + let status = this._settings.get_boolean('dash-separator'); + + if (forceOriginal || status) { + this._api.dashSeparatorShow(); + } else { + this._api.dashSeparatorHide(); + } + } + + /** + * apply looking glass size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyLookingGlassSize(forceOriginal) + { + let widthSize = this._settings.get_int('looking-glass-width'); + let heightSize = this._settings.get_int('looking-glass-height'); + + if (forceOriginal) { + this._api.lookingGlassSetDefaultSize(); + } else { + let width = (widthSize !== 0) ? widthSize / 10 : null; + let height = (heightSize !== 0) ? heightSize / 10 : null; + this._api.lookingGlassSetSize(width, height); + } + } + + /** + * apply osd position settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyOSDPosition(forceOriginal) + { + let pos = this._settings.get_int('osd-position'); + + if (forceOriginal || pos === 0) { + this._api.osdPositionSetDefault(); + } else { + this._api.osdPositionSet(pos - 1); + } + } + + /** + * apply window menu take screenshot button settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyWindowMenuTakeScreenshotButton(forceOriginal) + { + let status = this._settings.get_boolean('window-menu-take-screenshot-button'); + + if (forceOriginal || status) { + this._api.screenshotInWindowMenuShow(); + } else { + this._api.screenshotInWindowMenuHide(); + } + } + + /** + * apply alt tab window preview size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAltTabWindowPreviewSize(forceOriginal) + { + let size = this._settings.get_int('alt-tab-window-preview-size'); + + if (forceOriginal || size === 0) { + this._api.altTabWindowPreviewSetDefaultSize(); + } else { + this._api.altTabWindowPreviewSetSize(size); + } + } + + /** + * apply alt tab small icon size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAltTabSmallIconSize(forceOriginal) + { + let size = this._settings.get_int('alt-tab-small-icon-size'); + + if (forceOriginal || size === 0) { + this._api.altTabSmallIconSetDefaultSize(); + } else { + this._api.altTabSmallIconSetSize(size); + } + } + + /** + * apply alt tab icon size settings + * + * @param {boolean} forceOriginal force original shell setting + * + * @returns {void} + */ + _applyAltTabIconSize(forceOriginal) + { + let size = this._settings.get_int('alt-tab-icon-size'); + + if (forceOriginal || size === 0) { + this._api.altTabIconSetDefaultSize(); + } else { + this._api.altTabIconSetSize(size); + } + } +} + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/Prefs.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/Prefs.js new file mode 100644 index 0000000..24eede5 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/Prefs.js @@ -0,0 +1,805 @@ +/** + * Prefs Library + * + * @author Javad Rahmatzadeh + * @copyright 2020-2022 + * @license GPL-3.0-only + */ + +/** + * prefs widget for showing prefs window + */ +var Prefs = class +{ + /** + * class constructor + * + * @param {Object} dependencies + * 'Builder' instance of Gtk::Builder + * 'Settings' instance of Gio::Settings + * 'GObjectBindingFlags' instance of GObject::BindingFlags + * 'Gtk' reference to Gtk + * 'Gdk' reference to Gdk + * 'Gio' reference to Gio + * 'GLib' reference to GLib + * @param {PrefsKeys.PrefsKeys} prefsKeys instance of PrefsKeys + * @param {number} shellVersion float in major.minor format + */ + constructor(dependencies, prefsKeys, shellVersion) + { + this._settings = dependencies['Settings'] || null; + this._builder = dependencies['Builder'] || null; + this._gobjectBindingFlags = dependencies['GObjectBindingFlags'] || null; + this._gtk = dependencies['Gtk'] || null; + this._gdk = dependencies['Gdk'] || null; + this._gio = dependencies['Gio'] || null; + this._glib = dependencies['GLib'] || null; + + this._prefsKeys = prefsKeys; + this._shellVersion = shellVersion; + this._gtkVersion = (this._gtk) ? this._gtk.get_major_version() : 3; + + /** + * whether it is called for adwaita window + * + * @member {boolean} + */ + this._isAdw = false; + + /** + * holds Gtk.DropDown items that are + * created inside this._convertComboBoxTextToDropDown() + * object key is widget id + * + * @member {Object} + */ + this._dropdowns = {}; + + /** + * initial window size + * + * @member {number} + */ + this._windowWidth = 600; + this._windowHeight = 750; + + /** + * initial window size for adw + * + * @member {number} + */ + this._windowWidthAdw = 600; + this._windowHeightAdw = 650; + + /** + * holds all profile names + * + * @member {string} + */ + this._profiles = [ + 'default', + 'minimal', + 'superminimal', + ]; + + /** + * holds all required urls + * + * @member {Object} + */ + this._url = { + bug_report: 'https://gitlab.gnome.org/jrahmatzadeh/just-perfection/-/issues', + patreon: 'https://www.patreon.com/justperfection', + }; + } + + /** + * fill prefs window + * + * @param {string} UIFolderPath folder path to ui folder + * @param {string} binFolderPath bin folder path + * @param {string} gettextDomain gettext domain + * + * @returns {void} + */ + fillPrefsWindow(window, UIFolderPath, binFolderPath, gettextDomain) + { + this._isAdw = true; + + // changing the order here can change the elements order in ui + let uiFilenames = [ + 'profile', + 'visibility', + 'icons', + 'behavior', + 'customize', + ]; + + this._builder.set_translation_domain(gettextDomain); + for (let uiFilename of uiFilenames) { + this._builder.add_from_file(`${UIFolderPath}/adw/${uiFilename}.ui`); + } + + for (let uiFilename of uiFilenames) { + let page = this._builder.get_object(uiFilename); + window.add(page); + } + + this._setValues(); + this._guessProfile(); + this._onlyShowSupportedRows(); + this._registerAllSignals(window); + + this._setWindowSize(window); + + window.search_enabled = true; + } + + /** + * get prefs widget + * + * @param {string} UIFolderPath folder path to ui folder + * @param {string} binFolderPath bin folder path + * @param {string} gettextDomain gettext domain + * + * @returns {Object} + */ + getPrefsWidget(UIFolderPath, binFolderPath, gettextDomain) + { + this._isAdw = false; + + // changing the order here can change the elements order in ui + let uiFilenames = [ + 'main', + 'no-results-found', + 'profile', + 'override', + 'visibility', + 'icons', + 'behavior', + 'customize', + ]; + + // profile is not supported on GNOME Shell 3.x + if (this._shellVersion < 40) { + uiFilenames.splice(uiFilenames.indexOf('profile'), 1); + } + + this._builder.set_translation_domain(gettextDomain); + for (let uiFilename of uiFilenames) { + this._builder.add_from_file(`${UIFolderPath}/${uiFilename}.ui`); + } + + let obj = this._builder.get_object('main_prefs'); + let prefsBox = this._builder.get_object('main_prefs_in_box'); + + for (let uiFilename of uiFilenames) { + if (uiFilename === 'main') { + continue; + } + let elementId = uiFilename.replace(/-/g, '_'); + let elm = this._builder.get_object(elementId); + if (this._gtkVersion === 3) { + prefsBox.add(elm); + } else { + prefsBox.append(elm); + } + } + + this._convertComboBoxTextToDropDown(); + this._fixIconObjects(); + this._setValues(); + this._guessProfile(); + + this._onlyShowSupportedRows(); + + obj.connect('realize', () => { + + let window = (this._gtkVersion === 3) ? obj.get_toplevel() : obj.get_root(); + + this._setWindowSize(window); + + // csd + let headerBar = this._builder.get_object('header_bar'); + let csdMenu = this._builder.get_object('csd_menu'); + window.set_titlebar(headerBar); + if (this._gtkVersion === 3) { + headerBar.set_title('Just Perfection'); + headerBar.set_show_close_button(true); + } + headerBar.pack_end(csdMenu); + + this._registerAllSignals(window); + }); + + return obj; + } + + /** + * set window size + * + * @param {Gtk.Window|Adw.PreferencesWindow} window prefs window + * + * @returns {void} + */ + _setWindowSize(window) + { + let [pmWidth, pmHeight, pmScale] = this._getPrimaryMonitorInfo(); + let sizeTolerance = 50; + let width = (this._isAdw) ? this._windowWidthAdw : this._windowWidth; + let height = (this._isAdw) ? this._windowHeightAdw : this._windowHeight; + + if ( + (pmWidth/pmScale) - sizeTolerance >= width && + (pmHeight/pmScale) - sizeTolerance >= height + ) { + if (!this._isAdw) { + window.default_width = width; + } + window.set_default_size(width, height); + if (this._gtkVersion === 3) { + window.resize(width, height); + } + } + } + + /** + * get primary monitor info + * + * @returns {Array} [width, height, scale] + */ + _getPrimaryMonitorInfo() + { + let display = this._gdk.Display.get_default(); + + let pm + = (this._gtkVersion === 3) + ? display.get_monitor(0) + : display.get_monitors().get_item(0); + + if (!pm) { + return [700, 500, 1]; + } + + let geo = pm.get_geometry(); + let scale = pm.get_scale_factor(); + + return [geo.width, geo.height, scale]; + } + + /** + * fix images that holding icons for GTK4 + * + * @returns {void} + */ + _fixIconObjects() + { + if (this._gtkVersion === 3 || this._isAdw) { + return; + } + + let icons = [ + 'menu_icon', + 'search_icon', + ]; + + icons.forEach(id => { + let elm = this._builder.get_object(id); + let parent = elm.get_parent(); + let iconName = elm.get_icon_name(); + let iconSize = elm.get_icon_size(); + + parent.icon_name = iconName; + parent.icon_size = iconSize; + }); + } + + /** + * convert all comboboxes to drop down and hold them inside this._dropdowns + * + * @returns {void} + */ + _convertComboBoxTextToDropDown() + { + if (this._gtkVersion === 3 || this._isAdw) { + return; + } + + for (let [, key] of Object.entries(this._prefsKeys.keys)) { + if (key.widgetType === 'GtkComboBoxText') { + let widget = this._builder.get_object(key.widgetId); + let parent = widget.get_parent(); + + let items = []; + widget.set_active(0); + let selectedIndex = 0; + while (widget.get_active_text() !== null) { + items.push(widget.get_active_text()); + selectedIndex++; + widget.set_active(selectedIndex); + } + + let dropdown = this._gtk.DropDown.new_from_strings(items); + + this._prefsKeys.deleteKey(key.id); + + let newKey = this._prefsKeys.setKey( + key.category, + key.name, + 'GtkDropDown', + key.supported, + key.profiles, + key.maps + ); + + this._dropdowns[newKey.widgetId] = dropdown; + + dropdown.set_valign(this._gtk.Align.CENTER); + + widget.hide(); + parent.append(dropdown); + } + } + } + + /** + * register all signals + * + * @param {Gtk.Window} window prefs dialog + * + * @returns {void} + */ + _registerAllSignals(window) + { + this._registerKeySignals(); + this._registerSearchSignals(window); + this._registerFileChooserSignals(window); + this._registerProfileSignals(); + this._registerActionSignals(window); + } + + /** + * register signals of all prefs keys + * + * @returns {void} + */ + _registerKeySignals() + { + // all available keys + for (let [, key] of Object.entries(this._prefsKeys.keys)) { + + switch (key.widgetType) { + + case 'GtkSwitch': + this._builder.get_object(key.widgetId).connect('state-set', (w) => { + this._settings.set_boolean(key.name, w.get_active()); + this._guessProfile(); + }); + break; + + case 'GtkComboBoxText': + this._builder.get_object(key.widgetId).connect('changed', (w) => { + let index = w.get_active(); + let value = (index in key.maps) ? key.maps[index] : index; + this._settings.set_int(key.name, value); + this._guessProfile(); + }); + break; + + case 'GtkDropDown': + this._dropdowns[key.widgetId].connect('notify::selected-item', (w) => { + let index = w.get_selected(); + let value = (index in key.maps) ? key.maps[index] : index; + this._settings.set_int(key.name, value); + this._guessProfile(); + }); + break; + + case 'AdwActionRow': + this._builder.get_object(key.widgetId).connect('notify::selected-item', (w) => { + let index = w.get_selected(); + let value = (index in key.maps) ? key.maps[index] : index; + this._settings.set_int(key.name, value); + this._guessProfile(); + }); + break; + + case 'GtkEntry': + this._builder.get_object(key.widgetId).connect('changed', (w) => { + this._settings.set_string(key.name, w.text); + this._guessProfile(); + }); + break; + } + } + } + + /** + * register search signals + * + * @param {Gtk.Window} window prefs dialog + * + * @returns {void} + */ + _registerSearchSignals(window) + { + if (this._isAdw) { + return; + } + + let searchEntry = this._builder.get_object('search_entry'); + searchEntry.connect('changed', (w) => { + this._search(w.get_text()); + }); + + let searchBar = this._builder.get_object('searchbar'); + if (this._gtkVersion === 3) { + window.connect('key-press-event', (w, e) => { + return searchBar.handle_event(e); + }); + } else { + searchBar.set_key_capture_widget(window); + } + + let searchBtn = this._builder.get_object('search_togglebutton'); + searchBtn.bind_property('active', searchBar, 'search-mode-enabled', + this._gobjectBindingFlags.BIDIRECTIONAL); + + searchBar.connect_entry(searchEntry); + } + + /** + * register file chooser signals + * + * @param {Gtk.Window} window prefs dialog + * + * @returns {void} + */ + _registerFileChooserSignals(window) + { + let fileChooser = this._builder.get_object('file_chooser'); + let activitiesButtonIconPath = { + button: this._builder.get_object('activities_button_icon_path_button'), + entry: this._builder.get_object('activities_button_icon_path_entry'), + empty: this._builder.get_object('activities_button_icon_path_empty_button'), + }; + + activitiesButtonIconPath['entry'].connect('changed', (w) => { + this._setFileChooserValue('activities_button_icon_path', w.text, true); + }); + + activitiesButtonIconPath['empty'].connect('clicked', () => { + this._setFileChooserValue('activities_button_icon_path', ''); + }); + + activitiesButtonIconPath['button'].connect('clicked', (w) => { + this.currentFileChooserEntry = activitiesButtonIconPath['entry']; + + let uri = activitiesButtonIconPath['entry'].text; + let file = this._gio.File.new_for_uri(uri); + let fileExists = file.query_exists(null); + if (fileExists) { + let fileParent = file.get_parent(); + fileChooser.set_current_folder( + (this._gtkVersion === 3) ? fileParent.get_path() : fileParent + ); + } + + fileChooser.set_transient_for(window); + fileChooser.show(); + }); + + fileChooser.connect('response', (w, response) => { + if (response !== this._gtk.ResponseType.ACCEPT) { + return; + } + let fileURI = w.get_file().get_uri(); + this.currentFileChooserEntry.text = fileURI; + }); + } + + /** + * register profile signals + * + * @returns {void} + */ + _registerProfileSignals() + { + for (let profile of this._profiles) { + let profileElm = this._builder.get_object(`profile_${profile}`); + if (!profileElm) { + break; + } + profileElm.connect('clicked', (w) => { + this._setValues(profile); + }); + } + } + + /** + * register action signals + * + * @param {Gtk.Window} window prefs dialog + * + * @returns {void} + */ + _registerActionSignals(window) + { + if (this._isAdw) { + return + } + + let actionGroup = new this._gio.SimpleActionGroup(); + + let action1 = new this._gio.SimpleAction({name: 'show-bug-report'}); + action1.connect('activate', () => { + this._openURI(window, this._url.bug_report); + }); + actionGroup.add_action(action1); + + let action2 = new this._gio.SimpleAction({name: 'show-patreon'}); + action2.connect('activate', () => { + this._openURI(window, this._url.patreon); + }); + actionGroup.add_action(action2); + + window.insert_action_group('prefs', actionGroup); + } + + /** + * open uri + * + * @param {string} uri uri to open + * @param {Gtk.Window} window prefs dialog + * + * @returns {void} + */ + _openURI(window, uri) + { + if (this._gtkVersion === 3) { + this._gtk.show_uri_on_window(window, uri, this._gdk.CURRENT_TIME); + return; + } + + this._gtk.show_uri(window, uri, this._gdk.CURRENT_TIME); + } + + /** + * can check all current values and guess the profile based on the values + * + * @returns {void} + */ + _guessProfile() + { + let totalCount = 0; + let matchCount = {}; + + for (let profile of this._profiles) { + matchCount[profile] = 0; + } + + for (let [, key] of Object.entries(this._prefsKeys.keys)) { + + if (!key.supported) { + continue; + } + + let value; + + switch (key.widgetType) { + case 'GtkSwitch': + case 'GtkComboBoxText': + value = this._builder.get_object(key.widgetId).get_active(); + break; + case 'AdwActionRow': + value = this._builder.get_object(key.widgetId).get_selected(); + break; + case 'GtkDropDown': + value = this._dropdowns[key.widgetId].get_selected(); + break; + case 'GtkEntry': + value = this._builder.get_object(key.widgetId).text; + break; + default: + value = ''; + continue; + } + + for (let profile of this._profiles) { + if (key.profiles[profile] === value) { + matchCount[profile]++; + } + } + + totalCount++; + } + + let currentProfile = 'custom'; + for (let profile of this._profiles) { + if (matchCount[profile] === totalCount) { + currentProfile = profile; + break; + } + } + + let profileElm = this._builder.get_object(`profile_${currentProfile}`); + if (profileElm) { + profileElm.set_active(true); + } + } + + /** + * set file chooser button value + * + * @param {string} id element starter id + * @param {string} uri file address + * @param {bool} entrySetBefore whether file chooser entry value has been set before + * + * @returns {void} + */ + _setFileChooserValue(id, uri, entrySetBefore = false) + { + let preview = this._builder.get_object(`${id}_preview`); + let emptyButton = this._builder.get_object(`${id}_empty_button`); + let entry = this._builder.get_object(`${id}_entry`); + + if (!entry) { + return; + } + + let file = this._gio.File.new_for_uri(uri); + let fileExists = file.query_exists(null); + let uriPrepared = (fileExists) ? uri : ''; + + let visible = uriPrepared !== ''; + + if (!entrySetBefore) { + entry.text = uriPrepared; + } + emptyButton.visible = visible; + + preview.clear(); + + if (fileExists) { + let gicon = this._gio.icon_new_for_string(file.get_path()); + if (this._gtkVersion === 3) { + preview.set_from_gicon(gicon, 1); + } else { + preview.set_from_gicon(gicon); + } + } else { + preview.icon_name = 'document-open-symbolic'; + } + } + + /** + * set values for all elements + * + * @param {string} profile profile name or null for get it from gsettings + * + * @returns {void} + */ + _setValues(profile) + { + for (let [, key] of Object.entries(this._prefsKeys.keys)) { + + let elm + = (key.widgetType === 'GtkDropDown') + ? this._dropdowns[key.widgetId] + : this._builder.get_object(key.widgetId); + + switch (key.widgetType) { + + case 'GtkSwitch': + let value + = (profile) + ? key.profiles[profile] + : this._settings.get_boolean(key.name); + + elm.set_active(value); + break; + + case 'GtkComboBoxText': + case 'GtkDropDown': + case 'AdwActionRow': + let index + = (profile) + ? key.profiles[profile] + : this._settings.get_int(key.name); + + for (let k in key.maps) { + if (key.maps[k] === index) { + index = k; + break; + } + } + if (key.widgetType === 'GtkDropDown' || key.widgetType === 'AdwActionRow') { + elm.set_selected(index); + } else { + elm.set_active(index); + } + break; + + case 'GtkEntry': + let text + = (profile) + ? key.profiles[profile] + : this._settings.get_string(key.name); + + elm.text = text; + this._setFileChooserValue(key.id, elm.text); + break; + } + } + } + + /** + * apply all supported keys to the elements + * + * @returns {void} + */ + _onlyShowSupportedRows() + { + if (!this._isAdw) { + this._search(''); + return; + } + + for (let [, key] of Object.entries(this._prefsKeys.keys)) { + let row = this._builder.get_object(`${key.id}_row`); + let visible = key.supported; + row.visible = visible; + } + } + + /** + * search the query + * + * @param {string} q query + * + * @returns {void} + */ + _search(q) + { + let categories = {}; + let noResultsFoundVisibility = true; + + let profile = this._builder.get_object('profile'); + if (profile) { + profile.visible = (q === '') ? true : false; + } + + for (let [, key] of Object.entries(this._prefsKeys.keys)) { + + if (categories[key.category] === undefined) { + categories[key.category] = 0; + } + + let text = this._builder.get_object(`${key.id}_txt`).get_text(); + let row = this._builder.get_object(`${key.id}_row`); + + let visible = key.supported && text.toLowerCase().includes(q); + + row.visible = visible; + + if (visible) { + categories[key.category]++; + noResultsFoundVisibility = false; + } + } + + // hide the category when nothing is visible in it + for (var category in categories) { + let titleElm = this._builder.get_object(`${category}_title`); + let frameElm = this._builder.get_object(`${category}_frame`); + let visible = categories[category] > 0; + + titleElm.visible = visible; + frameElm.visible = visible; + } + + let notFound = this._builder.get_object('no_results_found'); + notFound.visible = noResultsFoundVisibility; + } +}; + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/PrefsKeys.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/PrefsKeys.js new file mode 100644 index 0000000..0150ca8 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/lib/Prefs/PrefsKeys.js @@ -0,0 +1,888 @@ +/** + * PrefsKeys Library + * + * @author Javad Rahmatzadeh + * @copyright 2020-2022 + * @license GPL-3.0-only + */ + +/** + * prefs keys + */ +var PrefsKeys = class +{ + /** + * class constructor + * + * @param {number} shellVersion float in major.minor format + * @param {boolean} isAdw whether the current prefs is using libadwaita + */ + constructor(shellVersion, isAdw) + { + this._shellVersion = shellVersion; + this._isAdw = isAdw; + + /** + * holds all keys generated by this.setKey() + * + * @member {Object} + */ + this.keys = {}; + + this._setDefaults(); + } + + /** + * set all default keys + * + * @returns {void} + */ + _setDefaults() + { + this.setKey( + 'visibility', + 'panel', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'panel-in-overview', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'activities-button', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'app-menu', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'app-menu-label', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'clock-menu', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'keyboard-layout', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'accessibility-menu', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'aggregate-menu', + 'GtkSwitch', + this._shellVersion < 43, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'quick-settings', + 'GtkSwitch', + this._shellVersion >= 43, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'search', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'dash', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'dash-separator', + 'GtkSwitch', + this._shellVersion >= 40, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'osd', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'workspace-popup', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'workspace', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'background-menu', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'show-apps-button', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'workspaces-in-app-grid', + 'GtkSwitch', + this._shellVersion >= 40, + { + default: true, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'window-preview-caption', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'window-preview-close-button', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'ripple-box', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'visibility', + 'world-clock', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'weather', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'calendar', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'events-button', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'visibility', + 'window-menu-take-screenshot-button', + 'GtkSwitch', + this._shellVersion >= 42, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'icons', + 'app-menu-icon', + 'GtkSwitch', + true, + { + default: true, + minimal: false, + superminimal: true, + } + ); + + this.setKey( + 'icons', + 'panel-notification-icon', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'icons', + 'power-icon', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'icons', + 'window-picker-icon', + 'GtkSwitch', + this._shellVersion >= 40, + { + default: true, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'icons', + 'panel-arrow', + 'GtkSwitch', + this._shellVersion < 40, + { + default: true, + minimal: false, + superminimal: true, + } + ); + + this.setKey( + 'icons', + 'activities-button-icon-path', + 'GtkEntry', + true, + { + default: '', + minimal: '', + superminimal: '', + } + ); + + this.setKey( + 'icons', + 'activities-button-icon-monochrome', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'icons', + 'activities-button-label', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'behavior', + 'type-to-search', + 'GtkSwitch', + true, + { + default: true, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'behavior', + 'hot-corner', + 'GtkSwitch', + this._shellVersion < 41, + { + default: false, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'behavior', + 'gesture', + 'GtkSwitch', + this._shellVersion < 40, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'behavior', + 'window-demands-attention-focus', + 'GtkSwitch', + true, + { + default: false, + minimal: true, + superminimal: true, + } + ); + + this.setKey( + 'behavior', + 'workspace-switcher-should-show', + 'GtkSwitch', + this._shellVersion >= 40, + { + default: false, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'behavior', + 'startup-status', + 'GtkComboBoxText', + this._shellVersion >= 40, + { + default: 1, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'behavior', + 'workspace-wrap-around', + 'GtkSwitch', + true, + { + default: false, + minimal: false, + superminimal: false, + } + ); + + this.setKey( + 'behavior', + 'double-super-to-appgrid', + 'GtkSwitch', + this._shellVersion >= 40, + { + default: true, + minimal: true, + superminimal: false, + } + ); + + this.setKey( + 'customize', + 'workspace-background-corner-size', + 'GtkComboBoxText', + this._shellVersion >= 40, + { + default: 0, + minimal: 0, + superminimal: 15, + } + ); + + this.setKey( + 'customize', + 'top-panel-position', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'panel-corner-size', + 'GtkComboBoxText', + this._shellVersion < 42, + { + default: 0, + minimal: 1, + superminimal: 1, + } + ); + + this.setKey( + 'customize', + 'clock-menu-position', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'clock-menu-position-offset', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'workspace-switcher-size', + 'GtkComboBoxText', + this._shellVersion >= 40, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'animation', + 'GtkComboBoxText', + true, + { + default: 1, + minimal: 1, + superminimal: 1, + } + ); + + this.setKey( + 'customize', + 'dash-icon-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 1, + superminimal: 0, + }, + { + '1': 32, + '2': 48, + '3': 64, + } + ); + + this.setKey( + 'customize', + 'notification-banner-position', + 'GtkComboBoxText', + true, + { + default: 1, + minimal: 1, + superminimal: 1, + } + ); + + this.setKey( + 'customize', + 'panel-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'panel-button-padding-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'panel-indicator-padding-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'panel-icon-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'osd-position', + 'GtkComboBoxText', + this._shellVersion >= 42, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'looking-glass-width', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'looking-glass-height', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + } + ); + + this.setKey( + 'customize', + 'alt-tab-window-preview-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + }, + { + '0': 0, + '1': 32, + '2': 64, + '3': 128, + '4': 256, + '5': 512, + } + ); + + this.setKey( + 'customize', + 'alt-tab-small-icon-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + }, + { + '0': 0, + '1': 32, + '2': 64, + '3': 128, + '4': 256, + '5': 512, + } + ); + + this.setKey( + 'customize', + 'alt-tab-icon-size', + 'GtkComboBoxText', + true, + { + default: 0, + minimal: 0, + superminimal: 0, + }, + { + '0': 0, + '1': 32, + '2': 64, + '3': 128, + '4': 256, + '5': 512, + } + ); + + this.setKey( + 'override', + 'theme', + 'GtkSwitch', + true, + { + default: false, + minimal: true, + superminimal: true, + } + ); + } + + /** + * set key + * + * @param {string} category possible values: + * - visibility + * - icons + * - behavior + * - customize + * - override + * @param {string} name should be the same as gsettings key name + * @param {string} widgetType gtk widget type like 'GtkSwitch'. + * @param {boolean} supported whether supported in the current shell + * @param {Object} profiles values for each profile. for example: + * {default: true, minimal: false} + * @param {Object} [maps] for example for combobox you can specify + * if the index is 1 go use 32 as value: + * {1 : 32} + * + * @returns {Object} key object that has been set + */ + setKey(category, name, widgetType, supported, profiles, maps) + { + if (this._isAdw && widgetType === 'GtkComboBoxText') { + widgetType = 'AdwActionRow'; + } + + let id = name.replace(/-/g, '_'); + let widgetName = widgetType.toLowerCase().replace('gtk', ''); + let widgetId = (widgetType === 'AdwActionRow') ? `${id}_row` : `${id}_${widgetName}`; + + if (maps === undefined) { + maps = {}; + } + + this.keys[id] = { + category, + widgetType, + name, + id, + widgetId, + supported, + profiles, + maps, + } + + return this.keys[id]; + } + + /** + * delete key + * + * @param {string} id key id + * + * @returns {void} + */ + deleteKey(id) + { + delete(this.keys[id]); + } +}; + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/af/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/af/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..706de7d00a331c2afb977bfb52b9f085fdace7bb GIT binary patch literal 10741 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/be/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/be/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..506632b4d66bd06ebc7c1eae21edc9431ce03204 GIT binary patch literal 14608 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 Vh;XNzRCp;s`6M%2p^$>3{|B$u#P|RJ literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/bg/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/bg/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..e9cd8c952c906015498216154b79e3fc2f57e140 GIT binary patch literal 15371 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/gl/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/gl/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..22cd72aac749c97446ee01bdec5a088947545139 GIT binary patch literal 12036 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/it/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/it/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..fb49dcf7aa2dcf5fe0ac68bd0a2cc484ec57afbf GIT binary patch literal 11713 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 MxR2}hVScCie>lrZOaK4? literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/ne/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/ne/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..af5bafe886cc44f67bcf21024bdcd785b26df99f GIT binary patch literal 16446 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 B5HkP( literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/pt_BR/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/pt_BR/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..2bec88d0a16852fb115ac7ae4941635be5f2f6c8 GIT binary patch literal 11686 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/sv/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/sv/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..a0a168afb3346e9eedcf35beadaed6424d3edb72 GIT binary patch literal 10722 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/zh_CN/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/zh_CN/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..c50ff2b1692c198e21dafc85b0502d753a3a230c GIT binary patch literal 10340 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 b3dK<@MUfh!vy7&}c{h4REm2sjveEwsf3ix7 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/zh_TW/LC_MESSAGES/just-perfection.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/locale/zh_TW/LC_MESSAGES/just-perfection.mo new file mode 100644 index 0000000000000000000000000000000000000000..293bfb3f9c9bfa54b19563b1f55e4ff2b6c20f29 GIT binary patch literal 10325 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 tCbFFff!Kt9@Mxy(3hEJOGR;R}O5Da$39t? + * @copyright 2020-2022 + * @license GPL-3.0-only + */ + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); + +const {Prefs, PrefsKeys} = Me.imports.lib.Prefs; +const {Gtk, Gdk, Gio, GLib, GObject} = imports.gi; + +const Config = imports.misc.config; +const shellVersion = parseFloat(Config.PACKAGE_VERSION); + +const gettextDomain = Me.metadata['gettext-domain']; +const UIFolderPath = Me.dir.get_child('ui').get_path(); +const binFolderPath = Me.dir.get_child('bin').get_path(); + +/** + * prefs widget + * + * @param {boolean} isAdw whether it is calling for adw ui + * + * @returns {Prefs.Prefs} + */ +function getPrefs(isAdw) +{ + let builder = new Gtk.Builder(); + let settings = ExtensionUtils.getSettings(); + let prefsKeys = new PrefsKeys.PrefsKeys(shellVersion, isAdw); + + return new Prefs.Prefs( + { + Builder: builder, + Settings: settings, + GObjectBindingFlags: GObject.BindingFlags, + Gtk, + Gdk, + Gio, + GLib, + }, + prefsKeys, + shellVersion + ); +} + +/** + * prefs initiation + * + * @returns {void} + */ +function init() +{ + ExtensionUtils.initTranslations(); +} + +/** + * fill prefs window + * + * @returns {Adw.PreferencesWindow} + */ +function fillPreferencesWindow(window) +{ + getPrefs(true).fillPrefsWindow(window, UIFolderPath, binFolderPath, gettextDomain); +} + +/** + * prefs widget + * + * @returns {Gtk.Widget} + */ +function buildPrefsWidget() +{ + return getPrefs(false).getPrefsWidget(UIFolderPath, binFolderPath, gettextDomain); +} + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/schemas/gschemas.compiled b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..a010d9890ef48a3fd202e03fe35533209596ce4a GIT binary patch literal 4309 zcma)9Yitx%7@ev>1yLwPiag{Yx3OFiQJvN-5EPOGtSI*Tc1DB zST!KTkN|3;QHVdpC`2V1vC#k#AE~K`(Wpd&)(1*Vj1Yr(&YhXv?ShF-4(D+8KEM0j zJNMprn+$B}Mn>}21YQyA%xS3!9yZ=EPT(*8ZK*DEC;TmkmSk9rdbZJS^nza=VHkB_ zFUYs#U9X^8LQ6SLi|US)8`_>5w%lC|BjKx{Lzxi_6gG^^wVL98*!LL;hJovWQK!IJ z@QBgC*aQt=qOl4XzL8=AbPCRQA}}ezWbhPVIxrKM1zZSllEiG_Vqi`J0d4_W6I=qG zpI`y_vILid7gpg4Xkro223!Mh{=|-B{S#T2aU5%O8GYcd0Bh>UZ_uZ%hd&5D47~8! z%2()9pADbEngslqUAvV&^*Qk8f)@bmTJPFKpLz`ZcJMM_`_|Fgr=9@c0VX}{sH>bjKfawJHUdivwomY%{cdi_XB&j?>R`HnsGP? zJ_I-`t$XNGkAr`dJkl_hZ0;RJpZaw8P2efOiSG6h^r^YN8L$A>I3sVTPkk2r#o#-D zTc6y!i$3)T_!hVTxPRZYjy^TV-wS>Lxc+tf2z_dne-->X(D%TDqqw)Jhr#ay|IXj` zO&i1V)bx*nj{{#H88|_on)9v4#+(UUdfmp!^r`931up>1e-_Az#D*T4&Hp2KJ_&CJHZ3M^3{8vp-{>gI<*Cm^`Fb2IGlAmfeJ|3d<~l9}-vTr~^y8=Wsabv% zSOMcUKV{LU*5e011-$>|f#LM2xi6jrZvh6!Kio~9n)BKT9so|P`}KMH)Lh3S;6H)B ztGm9VPtCa1$%`}Vh=vphBP;VAex@Yt~5 zo~BRD@sBwhXDX0>W2mvqjXB`VIfn6R+lXITo_aFMw}VZft*_%}`qb0m_kz~|PYmCn z^N^b5Uj=^%?D>4{qbyI&^JEZw`WVCbe$z)beQL(P2|NXOeEa2kA5l+)zYu&2u>QdF z8(5xtJbVjW09Ltj1$}D0@4#z-&D+1!=MOdK`y6-+(Dd83PL`+Uc>2J*fv+0wn?#>_ zIQ)L_e!!Qma)jvxt_nnG->XoDe?d(8J7Q$)Oi#wPo12@Z?~8(Ri~83(Ba>~;$ABUlEAd<~1&+D|^yvRE;427laycJ(Z(s|+7tR9!|mC!J!0bBQ*&NMYsALDUy!gM^d zQatZy zn9?s_W@_T$dw$Wc)H_9-EU$>MGP1gT^q*~(CymdMS>=@5DbKrX$K$fRC`l6(MLRc_*d)U&R8I{&oJOTR_*-`zTbt3}ocRwc`2Z^MT6CNTsEdemYf8){{X_II_np z>g2BKAF1Vasemb@JI+?}PE_r||G)1|Q-z_OwH-U^Nk^jl!*UeTLqq46YZqj^n04qn zojAg!x0LtW_}#@f72i?VgvLC8Im7P&-#*O%-(U^EG+;O|4&d9V5jYp%`wZ7j{aym; zx7c(r-&7X^e77-g=Kz-iivhkL=K~i2mjG7-6MzGBg?9dyn)jXUdB#r@<{T<3AYb3M}v@H}Sm>V4won71A}khvVc zjO7!GB`f_fcGdkPyClux + + + + + + true +

Panel + Panel Visibility Status + + + + false + Panel in Overview + Panel in Overview Visibility Status + + + + true + Background Menu + Background Menu Status + + + + true + Search Box + Search Box Visibility Status + + + + true + Workspace Switcher + Workspace Switcher Visibility Status + + + + true + Dash + Dash Visibility Status + + + + true + OSD + OSD Visibility Status + + + + true + Workspace Popup + Workspace Popup Visibility Status + + + + true + Gesture + Gesture Status + + + + false + Hot Corner + Hot Corner Status + + + + false + Theme + Theme Status + + + + true + Activities Button + Activities Button Visibility Status + + + + true + App Menu + App Menu Visibility Status + + + + true + App Menu Icon + App Menu Icon Visibility Status + + + + true + App Menu Label + App Menu Label Visibility Status + + + + true + Clock Menu + Clock Menu Visibility Status + + + + true + Panel Notification Icon + Panel Notification Icon Visibility Status + + + + true + Keyboard Layout + Keyboard Layout Visibility Status + + + + true + Accessibility Menu + Accessibility Menu Visibility Status + + + + true + Aggregate Menu + Aggregate Menu Visibility Status + + + + true + Quick Settings Menu + Quick Settings Visibility Status + + + + true + Power Icon + Power Icon Visibility Status + + + + true + Panel Arrow + Panel Arrow Visibility Status + + + + true + Window Picker Icon + Window Picker Icon Visiblity + + + + true + Type to Search + Type to Search Behavior + + + + 0 + + 0 means use Shell theme, 1 means no border, 2 - 61 means border size + Panel Corner Size + + + + 0 + + Workspace Switcher Size in percent, 0 means use default size + Workspace Switcher Size + + + + 0 + + Top Panel Position + Top Panel Position Status + + + + 0 + + 0 means center, 1 means right, 2 means left + Clock Menu Position Status + + + + 0 + + 0 means start of the position + Clock Menu Position Offset + + + + true + Show Apps Button Visiblity + Show Apps Button Visiblity Status + + + + 1 + + 0 means disabled, 1 means default speed, animation speed otherwise + Animation Status + + + + '' + Activities Button Icon Path + Activities Button Icon Path + + + + true + Activities Button Monochrome Icon Style + Activities Button Monochrome Icon Style Status + + + + true + Activities Button Label Visiblity + Activities Button Label Visiblity Status + + + + false + Window Demands Attention Focus + Window Demands Attention Focus Status + + + + 0 + + 0 means default, 16, 22, 24, 32, 48, 64 + Dash Icon Size + + + + 1 + + 0 means desktop, 1 means overview + Startup Status + + + + true + Workspaces Visiblity in App Grid + Workspaces Visiblity in App Grid Status + + + + 1 + + 0: top start, 1: top center, 2: top end, 3: bottom start, 4: bottom center, 5: bottom end + Notification Banner Position + + + + false + Always Show Workspaces Switcher + Always Show Workspace Switcher Status + + + + 0 + + 0 means use Shell theme, 1 - 61 means size in pixels + Panel Size + + + + 0 + + 0 means use Shell theme, 1 means no padding, 2 - 61 means padding size + Panel Button Padding Size + + + + 0 + + 0 means use Shell theme, 1 means no padding, 2 - 61 means padding size + Panel Indicator Padding Size + + + + true + Window Preview Caption + Window Preview Caption Status + + + + true + Window Preview Close Button + Window Preview Close Button Status + + + + 0 + + 0 means use default shell size, 1 means no radius, 2 - 61 means radius size + Workspace Background Corner Size + + + + false + Workspace Wrap Around + Workspace Wrap Around Status + + + + true + Ripple Box + Ripple Box Status + + + + true + Double Supper To App Grid + Double Supper To App Grid Status + + + + true + World Clock Visibility in Clock Menu + World Clock Visibility Status + + + + true + Weather Visibility in Clock Menu + Weather Visibility Status + + + + true + Events Button Visibility in Clock Menu + Events Button Visibility Status + + + + true + Calendar Visibility in Clock Menu + Calendar Visibility Status + + + + 0 + + 0 means use Shell theme, 1 - 60 means panel icon size + Panel Icon Size + + + + true + Dash Separator Visibility + Dash Separator Visibility Status + + + + 0 + + Width Size in percent, 0 means use default size + Looking Glass Width size + + + + 0 + + Height Size in percent, 0 means use default size + Looking Glass Height size + + + + 0 + + OSD Position + OSD Position Status + + + + true + Window Menu Take Screenshot Button Visibility + Window Menu Take Screenshot Button Visibility Status + + + + 0 + + 0 means default size + Alt Tab Window Preview Size + + + + 0 + + 0 means default size + Alt Tab Small Icon Size (Window Preview Icon Size) + + + + 0 + + 0 means default size + Alt Tab Icon Size + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/stylesheet.css b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/stylesheet.css new file mode 100644 index 0000000..cce8de7 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/stylesheet.css @@ -0,0 +1,809 @@ +.just-perfection +{ + font-size: small; +} + +.just-perfection .workspace-animation +{ + background-color: black; +} + +.just-perfection .window-clone-border +{ + border: 5px solid #004AC7; + border-radius: 16px; + box-shadow: inset 0 0 0 0 #004AC7; +} + +.just-perfection .window-caption +{ + color: #ffffff; + background-color: #004AC7; + font-size: small; + font-weight: normal; +} + +.just-perfection .window-close +{ + background-image: url("bin/close-button.svg"); + background-size: 24px; + height: 24px; + width: 24px; + background-color: transparent; + color: transparent; + border-radius: 24px; + border: 0 solid #1b6acb; +} + +.just-perfection .switcher-popup +{ + padding: 8px; + spacing: 24px; + font-size: small; +} + +.just-perfection .switcher-list +{ + color: #eeeeec; + background-color: rgba(0, 0, 0, .99); + border: 0 solid rgba(255, 255, 255, .16); + border-radius: 15px; + padding: 12px; + box-shadow: none; +} + +.just-perfection .switcher-list .item-box +{ + padding: 8px; + border-radius: 14px; + border: 1px solid transparent; +} + +.just-perfection .switcher-list .item-box:outlined +{ + border: 0; + background-color: rgba(255, 255, 255, .1); + box-shadow: inset 0 2px 2px 0 rgba(0, 0, 0, .4); +} + +.just-perfection .switcher-list .item-box:selected +{ + background-color: #404040; + color: #eeeeec; +} + +.just-perfection .switcher-list .thumbnail-box +{ + padding: 2px; + spacing: 6px; +} + +.just-perfection .switcher-list .thumbnail +{ + width: 256px; +} + +.just-perfection .switcher-list .separator +{ + width: 1px; + background: #272727; +} + +.just-perfection .switcher-list .switcher-list-item-container +{ + spacing: 12px; +} + +.just-perfection .workspace-switcher-container +{ + background-color: rgba(0, 0, 0, .7); + box-shadow: none; + padding: 3px; + border: 0; + border-radius: 3px; +} + +.just-perfection .workspace-switcher +{ + background: transparent; + border: none; + border-radius: 0; + padding: 0; + spacing: 4px; +} + +.just-perfection.just-perfection-gnome4x-2nd-gen .workspace-switcher +{ + background: rgba(0, 0, 0, .7); + box-shadow: none; + border: none; + border-radius: 5px; + padding: 0; + spacing: 4px; +} + +.just-perfection .ws-switcher-indicator, +.just-perfection .ws-switcher-indicator:active +{ + background: transparent; + background-color: rgba(255, 255, 255, .02); + height: 8px; + width: 20px; + border: 0; + border-radius: 2px; + padding: 2px; + margin: 5px; +} + +.just-perfection .ws-switcher-indicator:active +{ + background-color: rgba(255, 255, 255, .8); +} + +.just-perfection .ws-switcher-box +{ + background: transparent; + background-color: rgba(255, 255, 255, .02); + height: 10px; + background-size: 0; + border: 0; + border-radius: 1px; +} + +.just-perfection .ws-switcher-active-up, +.just-perfection .ws-switcher-active-down, +.just-perfection .ws-switcher-active-left, +.just-perfection .ws-switcher-active-right +{ + height: 10px; + background-color: rgba(255, 255, 255, .8); + border: 0; + border-radius: 1px; +} + +.just-perfection .osd-window +{ + background-color: rgba(0, 0, 0, 1); + border: 0; + border-radius: 8px; + padding: 10px; + box-shadow: none; +} + +.just-perfection.just-perfection-gnome4x-2nd-gen .osd-window StIcon +{ + width: 22px; + height: 22px; +} + +.just-perfection .search-entry +{ + caret-color: white; + selection-background-color: #008bff; + selected-color: white; + padding: 10px; + color: white; + background-color: rgba(0, 0, 0, .5); + border: 0; + border-radius: 10px; + box-shadow: none; +} + +.just-perfection .search-entry:focus +{ + background-color: rgba(0, 0, 0, .6); +} + +.just-perfection .search-entry .search-entry-icon +{ + icon-size: 18px; + padding: 0 0; + color: rgba(255, 255, 255, .5); +} + +.just-perfection .search-section .search-section-separator +{ + height: 1px; + background-color: rgba(255, 255, 255, .1); +} + +.just-perfection .search-section-content +{ + spacing: 0; + border-radius: 0; + border: 0; + box-shadow: none; + background: none; + text-shadow: none; + color: rgba(255, 255, 255, .98); +} + +.just-perfection.just-perfection-gnome3 #dash +{ + background-color: rgba(0, 0, 0, .4); + padding: 5px 0; + border: 0; + border-radius: 0 15px 15px 0; +} + +.just-perfection.just-perfection-gnome3 #dash:rtl +{ + padding: 5px 0; + border-radius: 15px 0 0 15px; +} + +.just-perfection.just-perfection-gnome3 .workspace-thumbnails +{ + spacing: 20px; + padding: 20px; + padding-right: 0; + margin: 0; + border-radius: 15px 0 0 15px; + border: 0; + color: rgba(255, 255, 255, .85); + background-color: rgba(0, 0, 0, .5); +} + +.just-perfection.just-perfection-gnome3 .workspace-thumbnail-indicator +{ + border: 0; + border-bottom: 2px solid transparent; + border-color: #0860f2; + padding: 0; + padding-bottom: 2px; + border-radius: 0; +} + +.just-perfection .tile-preview +{ + background-color: rgba(255, 255, 255, 0.15); + border: 1px solid rgba(255, 255, 255, 0.6); + border-radius: 0; +} + +.just-perfection-api-no-search #overview +{ + spacing: 0; +} + +.just-perfection-api-no-search .overview-controls +{ + padding-top: 36px; + padding-bottom: 36px; +} + +.just-perfection-api-gnome3.just-perfection-api-no-workspace .window-picker +{ + /* 100% won't work but when the px is more than the maximum width it will be 100%*/ + width: 100000px; +} + +.just-perfection-api-gnome40.just-perfection-api-no-workspace .workspace-thumbnails, +.just-perfection-api-gnome41.just-perfection-api-no-workspace .workspace-thumbnails, +.just-perfection-api-gnome42.just-perfection-api-no-workspace .workspace-thumbnails, +.just-perfection-api-gnome43.just-perfection-api-no-workspace .workspace-thumbnails, +.just-perfection-api-gnome40.just-perfection-api-no-workspace .workspace-thumbnail-indicator, +.just-perfection-api-gnome41.just-perfection-api-no-workspace .workspace-thumbnail-indicator, +.just-perfection-api-gnome42.just-perfection-api-no-workspace .workspace-thumbnail-indicator, +.just-perfection-api-gnome43.just-perfection-api-no-workspace .workspace-thumbnail-indicator +{ + /* we use scale=0 which is giving us the same width and height as 0 */ + /* spacing: 0; */ + /* width: 0; */ + /* height: 0; */ + padding: 0; + margin: 0; + border: 0; +} + +.just-perfection-api-gnome3.just-perfection-api-no-panel .search-entry +{ + margin-top: 10px; + margin-bottom: 10px; +} + +.just-perfection-api-gnome40.just-perfection-api-no-panel .search-entry, +.just-perfection-api-gnome41.just-perfection-api-no-panel .search-entry, +.just-perfection-api-gnome42.just-perfection-api-no-panel .search-entry, +.just-perfection-api-gnome43.just-perfection-api-no-panel .search-entry +{ + margin-top: 30px; +} + +/* commented because the icon will be shown when the window is getting dragged */ +/* icon-dropshadow isn't specific to the window picker icon but that's a quick fix for now */ +/* .just-perfection-api-no-window-picker-icon .workspaces-view StIcon */ +.just-perfection-api-no-window-picker-icon .icon-dropshadow +{ + width: 0; + height: 0; + padding: 0; +} + +.just-perfection-api-no-power-icon .power-status StIcon +{ + width: 0; + height: 0; + padding: 0; +} + +.just-perfection-api-gnome3.just-perfection-api-type-to-search #overview +{ + margin-top: 23px; +} + +.just-perfection-api-gnome3.just-perfection-api-type-to-search #overview .search-entry +{ + margin-bottom: 23px; +} + +.just-perfection-api-bottom-panel #overview +{ + margin-bottom: 24px; +} + +.just-perfection-api-bottom-panel .popup-menu.panel-menu +{ + margin-bottom: 0; +} + +.just-perfection-api-bottom-panel.just-perfection-api-no-panel #overview +{ + margin-bottom: 0; +} + +.just-perfection-api-no-panel-arrow .panel-button .popup-menu-arrow +{ + width: 0; + height: 0; +} + +/** + * we shouldn't mess with GNOME Shell theme + * so styling with css for each size is more proper + */ +.just-perfection-api-panel-corner0 #panel .panel-corner { -panel-corner-radius: 0px; } +.just-perfection-api-panel-corner1 #panel .panel-corner { -panel-corner-radius: 1px; } +.just-perfection-api-panel-corner2 #panel .panel-corner { -panel-corner-radius: 2px; } +.just-perfection-api-panel-corner3 #panel .panel-corner { -panel-corner-radius: 3px; } +.just-perfection-api-panel-corner4 #panel .panel-corner { -panel-corner-radius: 4px; } +.just-perfection-api-panel-corner5 #panel .panel-corner { -panel-corner-radius: 5px; } +.just-perfection-api-panel-corner6 #panel .panel-corner { -panel-corner-radius: 6px; } +.just-perfection-api-panel-corner7 #panel .panel-corner { -panel-corner-radius: 7px; } +.just-perfection-api-panel-corner8 #panel .panel-corner { -panel-corner-radius: 8px; } +.just-perfection-api-panel-corner9 #panel .panel-corner { -panel-corner-radius: 9px; } +.just-perfection-api-panel-corner10 #panel .panel-corner { -panel-corner-radius: 10px; } +.just-perfection-api-panel-corner11 #panel .panel-corner { -panel-corner-radius: 11px; } +.just-perfection-api-panel-corner12 #panel .panel-corner { -panel-corner-radius: 12px; } +.just-perfection-api-panel-corner13 #panel .panel-corner { -panel-corner-radius: 13px; } +.just-perfection-api-panel-corner14 #panel .panel-corner { -panel-corner-radius: 14px; } +.just-perfection-api-panel-corner15 #panel .panel-corner { -panel-corner-radius: 15px; } +.just-perfection-api-panel-corner16 #panel .panel-corner { -panel-corner-radius: 16px; } +.just-perfection-api-panel-corner17 #panel .panel-corner { -panel-corner-radius: 17px; } +.just-perfection-api-panel-corner18 #panel .panel-corner { -panel-corner-radius: 18px; } +.just-perfection-api-panel-corner19 #panel .panel-corner { -panel-corner-radius: 19px; } +.just-perfection-api-panel-corner20 #panel .panel-corner { -panel-corner-radius: 20px; } +.just-perfection-api-panel-corner21 #panel .panel-corner { -panel-corner-radius: 21px; } +.just-perfection-api-panel-corner22 #panel .panel-corner { -panel-corner-radius: 22px; } +.just-perfection-api-panel-corner23 #panel .panel-corner { -panel-corner-radius: 23px; } +.just-perfection-api-panel-corner24 #panel .panel-corner { -panel-corner-radius: 24px; } +.just-perfection-api-panel-corner25 #panel .panel-corner { -panel-corner-radius: 25px; } +.just-perfection-api-panel-corner26 #panel .panel-corner { -panel-corner-radius: 26px; } +.just-perfection-api-panel-corner27 #panel .panel-corner { -panel-corner-radius: 27px; } +.just-perfection-api-panel-corner28 #panel .panel-corner { -panel-corner-radius: 28px; } +.just-perfection-api-panel-corner29 #panel .panel-corner { -panel-corner-radius: 29px; } +.just-perfection-api-panel-corner30 #panel .panel-corner { -panel-corner-radius: 30px; } +.just-perfection-api-panel-corner31 #panel .panel-corner { -panel-corner-radius: 31px; } +.just-perfection-api-panel-corner32 #panel .panel-corner { -panel-corner-radius: 32px; } +.just-perfection-api-panel-corner33 #panel .panel-corner { -panel-corner-radius: 33px; } +.just-perfection-api-panel-corner34 #panel .panel-corner { -panel-corner-radius: 34px; } +.just-perfection-api-panel-corner35 #panel .panel-corner { -panel-corner-radius: 35px; } +.just-perfection-api-panel-corner36 #panel .panel-corner { -panel-corner-radius: 36px; } +.just-perfection-api-panel-corner37 #panel .panel-corner { -panel-corner-radius: 37px; } +.just-perfection-api-panel-corner38 #panel .panel-corner { -panel-corner-radius: 38px; } +.just-perfection-api-panel-corner39 #panel .panel-corner { -panel-corner-radius: 39px; } +.just-perfection-api-panel-corner40 #panel .panel-corner { -panel-corner-radius: 40px; } +.just-perfection-api-panel-corner41 #panel .panel-corner { -panel-corner-radius: 41px; } +.just-perfection-api-panel-corner42 #panel .panel-corner { -panel-corner-radius: 42px; } +.just-perfection-api-panel-corner43 #panel .panel-corner { -panel-corner-radius: 43px; } +.just-perfection-api-panel-corner44 #panel .panel-corner { -panel-corner-radius: 44px; } +.just-perfection-api-panel-corner45 #panel .panel-corner { -panel-corner-radius: 45px; } +.just-perfection-api-panel-corner46 #panel .panel-corner { -panel-corner-radius: 46px; } +.just-perfection-api-panel-corner47 #panel .panel-corner { -panel-corner-radius: 47px; } +.just-perfection-api-panel-corner48 #panel .panel-corner { -panel-corner-radius: 48px; } +.just-perfection-api-panel-corner49 #panel .panel-corner { -panel-corner-radius: 49px; } +.just-perfection-api-panel-corner50 #panel .panel-corner { -panel-corner-radius: 50px; } +.just-perfection-api-panel-corner51 #panel .panel-corner { -panel-corner-radius: 51px; } +.just-perfection-api-panel-corner52 #panel .panel-corner { -panel-corner-radius: 52px; } +.just-perfection-api-panel-corner53 #panel .panel-corner { -panel-corner-radius: 53px; } +.just-perfection-api-panel-corner54 #panel .panel-corner { -panel-corner-radius: 54px; } +.just-perfection-api-panel-corner55 #panel .panel-corner { -panel-corner-radius: 55px; } +.just-perfection-api-panel-corner56 #panel .panel-corner { -panel-corner-radius: 56px; } +.just-perfection-api-panel-corner57 #panel .panel-corner { -panel-corner-radius: 57px; } +.just-perfection-api-panel-corner58 #panel .panel-corner { -panel-corner-radius: 58px; } +.just-perfection-api-panel-corner59 #panel .panel-corner { -panel-corner-radius: 59px; } +.just-perfection-api-panel-corner60 #panel .panel-corner { -panel-corner-radius: 60px; } + +.just-perfection-api-no-panel-notification-icon .clock-display StIcon +{ + width: 0; + height: 0; + padding: 0; +} + +.just-perfection-api-no-panel-notification-icon .clock-display-box +{ + padding: 0; + spacing: 0; +} + +.just-perfection-api-no-app-menu-icon .app-menu-icon +{ + width: 0; + height: 0; + margin: 0; +} + +.just-perfection-api-no-show-apps-button .show-apps, +.just-perfection-api-no-show-apps-button .show-apps StIcon +{ + width: 0; + margin: 0; + spacing: 0; +} + +.just-perfection-gnome3.just-perfection-api-no-show-apps-button .show-apps, +.just-perfection-gnome3.just-perfection-api-no-show-apps-button .show-apps StIcon +{ + height: 0; +} + +.just-perfection-api-activities-button-icon, +.just-perfection-api-activities-button-icon-monochrome +{ + /* commented because padding would be enough since we are only using */ + /* one element inside the box */ + /* -natural-hpadding: 6px; */ + /* -minimum-hpadding: 6px; */ + padding-right: 6px; + padding-left: 0; +} + +.just-perfection-api-activities-button-icon-monochrome +{ + -st-icon-style: symbolic; +} + +.just-perfection-api-activities-button-no-label .just-perfection-api-activities-button-icon, +.just-perfection-api-activities-button-no-label .just-perfection-api-activities-button-icon-monochrome +{ + -natural-hpadding: 0; + -minimum-hpadding: 0; + padding-right: 0; + padding-left: 0; +} + +.just-perfection-api-dash-icon-size16 #dash StIcon { height: 16px; width: 16px; } +.just-perfection-api-dash-icon-size22 #dash StIcon { height: 22px; width: 22px; } +.just-perfection-api-dash-icon-size24 #dash StIcon { height: 24px; width: 24px; } +.just-perfection-api-dash-icon-size32 #dash StIcon { height: 32px; width: 32px; } +.just-perfection-api-dash-icon-size48 #dash StIcon { height: 48px; width: 48px; } +.just-perfection-api-dash-icon-size64 #dash StIcon { height: 64px; width: 64px; } + + +.just-perfection-api-panel-button-padding-size0 .panel-button { -natural-hpadding: 0px; -minimum-hpadding: 0px; } +.just-perfection-api-panel-button-padding-size1 .panel-button { -natural-hpadding: 1px; -minimum-hpadding: 1px; } +.just-perfection-api-panel-button-padding-size2 .panel-button { -natural-hpadding: 2px; -minimum-hpadding: 2px; } +.just-perfection-api-panel-button-padding-size3 .panel-button { -natural-hpadding: 3px; -minimum-hpadding: 3px; } +.just-perfection-api-panel-button-padding-size4 .panel-button { -natural-hpadding: 4px; -minimum-hpadding: 4px; } +.just-perfection-api-panel-button-padding-size5 .panel-button { -natural-hpadding: 5px; -minimum-hpadding: 5px; } +.just-perfection-api-panel-button-padding-size6 .panel-button { -natural-hpadding: 6px; -minimum-hpadding: 6px; } +.just-perfection-api-panel-button-padding-size7 .panel-button { -natural-hpadding: 7px; -minimum-hpadding: 7px; } +.just-perfection-api-panel-button-padding-size8 .panel-button { -natural-hpadding: 8px; -minimum-hpadding: 8px; } +.just-perfection-api-panel-button-padding-size9 .panel-button { -natural-hpadding: 9px; -minimum-hpadding: 9px; } +.just-perfection-api-panel-button-padding-size10 .panel-button { -natural-hpadding: 10px; -minimum-hpadding: 10px; } +.just-perfection-api-panel-button-padding-size11 .panel-button { -natural-hpadding: 11px; -minimum-hpadding: 11px; } +.just-perfection-api-panel-button-padding-size12 .panel-button { -natural-hpadding: 12px; -minimum-hpadding: 12px; } +.just-perfection-api-panel-button-padding-size13 .panel-button { -natural-hpadding: 13px; -minimum-hpadding: 13px; } +.just-perfection-api-panel-button-padding-size14 .panel-button { -natural-hpadding: 14px; -minimum-hpadding: 14px; } +.just-perfection-api-panel-button-padding-size15 .panel-button { -natural-hpadding: 15px; -minimum-hpadding: 15px; } +.just-perfection-api-panel-button-padding-size16 .panel-button { -natural-hpadding: 16px; -minimum-hpadding: 16px; } +.just-perfection-api-panel-button-padding-size17 .panel-button { -natural-hpadding: 17px; -minimum-hpadding: 17px; } +.just-perfection-api-panel-button-padding-size18 .panel-button { -natural-hpadding: 18px; -minimum-hpadding: 18px; } +.just-perfection-api-panel-button-padding-size19 .panel-button { -natural-hpadding: 19px; -minimum-hpadding: 19px; } +.just-perfection-api-panel-button-padding-size20 .panel-button { -natural-hpadding: 20px; -minimum-hpadding: 20px; } +.just-perfection-api-panel-button-padding-size21 .panel-button { -natural-hpadding: 21px; -minimum-hpadding: 21px; } +.just-perfection-api-panel-button-padding-size22 .panel-button { -natural-hpadding: 22px; -minimum-hpadding: 22px; } +.just-perfection-api-panel-button-padding-size23 .panel-button { -natural-hpadding: 23px; -minimum-hpadding: 23px; } +.just-perfection-api-panel-button-padding-size24 .panel-button { -natural-hpadding: 24px; -minimum-hpadding: 24px; } +.just-perfection-api-panel-button-padding-size25 .panel-button { -natural-hpadding: 25px; -minimum-hpadding: 25px; } +.just-perfection-api-panel-button-padding-size26 .panel-button { -natural-hpadding: 26px; -minimum-hpadding: 26px; } +.just-perfection-api-panel-button-padding-size27 .panel-button { -natural-hpadding: 27px; -minimum-hpadding: 27px; } +.just-perfection-api-panel-button-padding-size28 .panel-button { -natural-hpadding: 28px; -minimum-hpadding: 28px; } +.just-perfection-api-panel-button-padding-size29 .panel-button { -natural-hpadding: 29px; -minimum-hpadding: 29px; } +.just-perfection-api-panel-button-padding-size30 .panel-button { -natural-hpadding: 30px; -minimum-hpadding: 30px; } +.just-perfection-api-panel-button-padding-size31 .panel-button { -natural-hpadding: 31px; -minimum-hpadding: 31px; } +.just-perfection-api-panel-button-padding-size32 .panel-button { -natural-hpadding: 32px; -minimum-hpadding: 32px; } +.just-perfection-api-panel-button-padding-size33 .panel-button { -natural-hpadding: 33px; -minimum-hpadding: 33px; } +.just-perfection-api-panel-button-padding-size34 .panel-button { -natural-hpadding: 34px; -minimum-hpadding: 34px; } +.just-perfection-api-panel-button-padding-size35 .panel-button { -natural-hpadding: 35px; -minimum-hpadding: 35px; } +.just-perfection-api-panel-button-padding-size36 .panel-button { -natural-hpadding: 36px; -minimum-hpadding: 36px; } +.just-perfection-api-panel-button-padding-size37 .panel-button { -natural-hpadding: 37px; -minimum-hpadding: 37px; } +.just-perfection-api-panel-button-padding-size38 .panel-button { -natural-hpadding: 38px; -minimum-hpadding: 38px; } +.just-perfection-api-panel-button-padding-size39 .panel-button { -natural-hpadding: 39px; -minimum-hpadding: 39px; } +.just-perfection-api-panel-button-padding-size40 .panel-button { -natural-hpadding: 40px; -minimum-hpadding: 40px; } +.just-perfection-api-panel-button-padding-size41 .panel-button { -natural-hpadding: 41px; -minimum-hpadding: 41px; } +.just-perfection-api-panel-button-padding-size42 .panel-button { -natural-hpadding: 42px; -minimum-hpadding: 42px; } +.just-perfection-api-panel-button-padding-size43 .panel-button { -natural-hpadding: 43px; -minimum-hpadding: 43px; } +.just-perfection-api-panel-button-padding-size44 .panel-button { -natural-hpadding: 44px; -minimum-hpadding: 44px; } +.just-perfection-api-panel-button-padding-size45 .panel-button { -natural-hpadding: 45px; -minimum-hpadding: 45px; } +.just-perfection-api-panel-button-padding-size46 .panel-button { -natural-hpadding: 46px; -minimum-hpadding: 46px; } +.just-perfection-api-panel-button-padding-size47 .panel-button { -natural-hpadding: 47px; -minimum-hpadding: 47px; } +.just-perfection-api-panel-button-padding-size48 .panel-button { -natural-hpadding: 48px; -minimum-hpadding: 48px; } +.just-perfection-api-panel-button-padding-size49 .panel-button { -natural-hpadding: 49px; -minimum-hpadding: 49px; } +.just-perfection-api-panel-button-padding-size50 .panel-button { -natural-hpadding: 50px; -minimum-hpadding: 50px; } +.just-perfection-api-panel-button-padding-size51 .panel-button { -natural-hpadding: 51px; -minimum-hpadding: 51px; } +.just-perfection-api-panel-button-padding-size52 .panel-button { -natural-hpadding: 52px; -minimum-hpadding: 52px; } +.just-perfection-api-panel-button-padding-size53 .panel-button { -natural-hpadding: 53px; -minimum-hpadding: 53px; } +.just-perfection-api-panel-button-padding-size54 .panel-button { -natural-hpadding: 54px; -minimum-hpadding: 54px; } +.just-perfection-api-panel-button-padding-size55 .panel-button { -natural-hpadding: 55px; -minimum-hpadding: 55px; } +.just-perfection-api-panel-button-padding-size56 .panel-button { -natural-hpadding: 56px; -minimum-hpadding: 56px; } +.just-perfection-api-panel-button-padding-size57 .panel-button { -natural-hpadding: 57px; -minimum-hpadding: 57px; } +.just-perfection-api-panel-button-padding-size58 .panel-button { -natural-hpadding: 58px; -minimum-hpadding: 58px; } +.just-perfection-api-panel-button-padding-size59 .panel-button { -natural-hpadding: 59px; -minimum-hpadding: 59px; } +.just-perfection-api-panel-button-padding-size60 .panel-button { -natural-hpadding: 60px; -minimum-hpadding: 60px; } + +.just-perfection-api-no-window-caption .window-caption +{ + spacing: 0; + background-color: transparent; + border-radius: 0; + border: 0; + padding: 0; + font-size: 0; +} + +.just-perfection-api-workspace-background-radius-size0 .workspace-background { border-radius: 0; } +.just-perfection-api-workspace-background-radius-size1 .workspace-background { border-radius: 1px; } +.just-perfection-api-workspace-background-radius-size2 .workspace-background { border-radius: 2px; } +.just-perfection-api-workspace-background-radius-size3 .workspace-background { border-radius: 3px; } +.just-perfection-api-workspace-background-radius-size4 .workspace-background { border-radius: 4px; } +.just-perfection-api-workspace-background-radius-size5 .workspace-background { border-radius: 5px; } +.just-perfection-api-workspace-background-radius-size6 .workspace-background { border-radius: 6px; } +.just-perfection-api-workspace-background-radius-size7 .workspace-background { border-radius: 7px; } +.just-perfection-api-workspace-background-radius-size8 .workspace-background { border-radius: 8px; } +.just-perfection-api-workspace-background-radius-size9 .workspace-background { border-radius: 9px; } +.just-perfection-api-workspace-background-radius-size10 .workspace-background { border-radius: 10px; } +.just-perfection-api-workspace-background-radius-size11 .workspace-background { border-radius: 11px; } +.just-perfection-api-workspace-background-radius-size12 .workspace-background { border-radius: 12px; } +.just-perfection-api-workspace-background-radius-size13 .workspace-background { border-radius: 13px; } +.just-perfection-api-workspace-background-radius-size14 .workspace-background { border-radius: 14px; } +.just-perfection-api-workspace-background-radius-size15 .workspace-background { border-radius: 15px; } +.just-perfection-api-workspace-background-radius-size16 .workspace-background { border-radius: 16px; } +.just-perfection-api-workspace-background-radius-size17 .workspace-background { border-radius: 17px; } +.just-perfection-api-workspace-background-radius-size18 .workspace-background { border-radius: 18px; } +.just-perfection-api-workspace-background-radius-size19 .workspace-background { border-radius: 19px; } +.just-perfection-api-workspace-background-radius-size20 .workspace-background { border-radius: 20px; } +.just-perfection-api-workspace-background-radius-size21 .workspace-background { border-radius: 21px; } +.just-perfection-api-workspace-background-radius-size22 .workspace-background { border-radius: 22px; } +.just-perfection-api-workspace-background-radius-size23 .workspace-background { border-radius: 23px; } +.just-perfection-api-workspace-background-radius-size24 .workspace-background { border-radius: 24px; } +.just-perfection-api-workspace-background-radius-size25 .workspace-background { border-radius: 25px; } +.just-perfection-api-workspace-background-radius-size26 .workspace-background { border-radius: 26px; } +.just-perfection-api-workspace-background-radius-size27 .workspace-background { border-radius: 27px; } +.just-perfection-api-workspace-background-radius-size28 .workspace-background { border-radius: 28px; } +.just-perfection-api-workspace-background-radius-size29 .workspace-background { border-radius: 29px; } +.just-perfection-api-workspace-background-radius-size30 .workspace-background { border-radius: 30px; } +.just-perfection-api-workspace-background-radius-size31 .workspace-background { border-radius: 31px; } +.just-perfection-api-workspace-background-radius-size32 .workspace-background { border-radius: 32px; } +.just-perfection-api-workspace-background-radius-size33 .workspace-background { border-radius: 33px; } +.just-perfection-api-workspace-background-radius-size34 .workspace-background { border-radius: 34px; } +.just-perfection-api-workspace-background-radius-size35 .workspace-background { border-radius: 35px; } +.just-perfection-api-workspace-background-radius-size36 .workspace-background { border-radius: 36px; } +.just-perfection-api-workspace-background-radius-size37 .workspace-background { border-radius: 37px; } +.just-perfection-api-workspace-background-radius-size38 .workspace-background { border-radius: 38px; } +.just-perfection-api-workspace-background-radius-size39 .workspace-background { border-radius: 39px; } +.just-perfection-api-workspace-background-radius-size40 .workspace-background { border-radius: 40px; } +.just-perfection-api-workspace-background-radius-size41 .workspace-background { border-radius: 41px; } +.just-perfection-api-workspace-background-radius-size42 .workspace-background { border-radius: 42px; } +.just-perfection-api-workspace-background-radius-size43 .workspace-background { border-radius: 43px; } +.just-perfection-api-workspace-background-radius-size44 .workspace-background { border-radius: 44px; } +.just-perfection-api-workspace-background-radius-size45 .workspace-background { border-radius: 45px; } +.just-perfection-api-workspace-background-radius-size46 .workspace-background { border-radius: 46px; } +.just-perfection-api-workspace-background-radius-size47 .workspace-background { border-radius: 47px; } +.just-perfection-api-workspace-background-radius-size48 .workspace-background { border-radius: 48px; } +.just-perfection-api-workspace-background-radius-size49 .workspace-background { border-radius: 49px; } +.just-perfection-api-workspace-background-radius-size50 .workspace-background { border-radius: 50px; } +.just-perfection-api-workspace-background-radius-size51 .workspace-background { border-radius: 51px; } +.just-perfection-api-workspace-background-radius-size52 .workspace-background { border-radius: 52px; } +.just-perfection-api-workspace-background-radius-size53 .workspace-background { border-radius: 53px; } +.just-perfection-api-workspace-background-radius-size54 .workspace-background { border-radius: 54px; } +.just-perfection-api-workspace-background-radius-size55 .workspace-background { border-radius: 55px; } +.just-perfection-api-workspace-background-radius-size56 .workspace-background { border-radius: 56px; } +.just-perfection-api-workspace-background-radius-size57 .workspace-background { border-radius: 57px; } +.just-perfection-api-workspace-background-radius-size58 .workspace-background { border-radius: 58px; } +.just-perfection-api-workspace-background-radius-size59 .workspace-background { border-radius: 59px; } +.just-perfection-api-workspace-background-radius-size60 .workspace-background { border-radius: 60px; } + +.just-perfection-api-panel-indicator-padding-size0 .panel-status-indicators-box { spacing: 0; } +.just-perfection-api-panel-indicator-padding-size1 .panel-status-indicators-box { spacing: 1px; } +.just-perfection-api-panel-indicator-padding-size2 .panel-status-indicators-box { spacing: 2px; } +.just-perfection-api-panel-indicator-padding-size3 .panel-status-indicators-box { spacing: 3px; } +.just-perfection-api-panel-indicator-padding-size4 .panel-status-indicators-box { spacing: 4px; } +.just-perfection-api-panel-indicator-padding-size5 .panel-status-indicators-box { spacing: 5px; } +.just-perfection-api-panel-indicator-padding-size6 .panel-status-indicators-box { spacing: 6px; } +.just-perfection-api-panel-indicator-padding-size7 .panel-status-indicators-box { spacing: 7px; } +.just-perfection-api-panel-indicator-padding-size8 .panel-status-indicators-box { spacing: 8px; } +.just-perfection-api-panel-indicator-padding-size9 .panel-status-indicators-box { spacing: 9px; } +.just-perfection-api-panel-indicator-padding-size10 .panel-status-indicators-box { spacing: 10px; } +.just-perfection-api-panel-indicator-padding-size11 .panel-status-indicators-box { spacing: 11px; } +.just-perfection-api-panel-indicator-padding-size12 .panel-status-indicators-box { spacing: 12px; } +.just-perfection-api-panel-indicator-padding-size13 .panel-status-indicators-box { spacing: 13px; } +.just-perfection-api-panel-indicator-padding-size14 .panel-status-indicators-box { spacing: 14px; } +.just-perfection-api-panel-indicator-padding-size15 .panel-status-indicators-box { spacing: 15px; } +.just-perfection-api-panel-indicator-padding-size16 .panel-status-indicators-box { spacing: 16px; } +.just-perfection-api-panel-indicator-padding-size17 .panel-status-indicators-box { spacing: 17px; } +.just-perfection-api-panel-indicator-padding-size18 .panel-status-indicators-box { spacing: 18px; } +.just-perfection-api-panel-indicator-padding-size19 .panel-status-indicators-box { spacing: 19px; } +.just-perfection-api-panel-indicator-padding-size20 .panel-status-indicators-box { spacing: 20px; } +.just-perfection-api-panel-indicator-padding-size21 .panel-status-indicators-box { spacing: 21px; } +.just-perfection-api-panel-indicator-padding-size22 .panel-status-indicators-box { spacing: 22px; } +.just-perfection-api-panel-indicator-padding-size23 .panel-status-indicators-box { spacing: 23px; } +.just-perfection-api-panel-indicator-padding-size24 .panel-status-indicators-box { spacing: 24px; } +.just-perfection-api-panel-indicator-padding-size25 .panel-status-indicators-box { spacing: 25px; } +.just-perfection-api-panel-indicator-padding-size26 .panel-status-indicators-box { spacing: 26px; } +.just-perfection-api-panel-indicator-padding-size27 .panel-status-indicators-box { spacing: 27px; } +.just-perfection-api-panel-indicator-padding-size28 .panel-status-indicators-box { spacing: 28px; } +.just-perfection-api-panel-indicator-padding-size29 .panel-status-indicators-box { spacing: 29px; } +.just-perfection-api-panel-indicator-padding-size30 .panel-status-indicators-box { spacing: 30px; } +.just-perfection-api-panel-indicator-padding-size31 .panel-status-indicators-box { spacing: 31px; } +.just-perfection-api-panel-indicator-padding-size32 .panel-status-indicators-box { spacing: 32px; } +.just-perfection-api-panel-indicator-padding-size33 .panel-status-indicators-box { spacing: 33px; } +.just-perfection-api-panel-indicator-padding-size34 .panel-status-indicators-box { spacing: 34px; } +.just-perfection-api-panel-indicator-padding-size35 .panel-status-indicators-box { spacing: 35px; } +.just-perfection-api-panel-indicator-padding-size36 .panel-status-indicators-box { spacing: 36px; } +.just-perfection-api-panel-indicator-padding-size37 .panel-status-indicators-box { spacing: 37px; } +.just-perfection-api-panel-indicator-padding-size38 .panel-status-indicators-box { spacing: 38px; } +.just-perfection-api-panel-indicator-padding-size39 .panel-status-indicators-box { spacing: 39px; } +.just-perfection-api-panel-indicator-padding-size40 .panel-status-indicators-box { spacing: 40px; } +.just-perfection-api-panel-indicator-padding-size41 .panel-status-indicators-box { spacing: 41px; } +.just-perfection-api-panel-indicator-padding-size42 .panel-status-indicators-box { spacing: 42px; } +.just-perfection-api-panel-indicator-padding-size43 .panel-status-indicators-box { spacing: 43px; } +.just-perfection-api-panel-indicator-padding-size44 .panel-status-indicators-box { spacing: 44px; } +.just-perfection-api-panel-indicator-padding-size45 .panel-status-indicators-box { spacing: 45px; } +.just-perfection-api-panel-indicator-padding-size46 .panel-status-indicators-box { spacing: 46px; } +.just-perfection-api-panel-indicator-padding-size47 .panel-status-indicators-box { spacing: 47px; } +.just-perfection-api-panel-indicator-padding-size48 .panel-status-indicators-box { spacing: 48px; } +.just-perfection-api-panel-indicator-padding-size49 .panel-status-indicators-box { spacing: 49px; } +.just-perfection-api-panel-indicator-padding-size50 .panel-status-indicators-box { spacing: 50px; } +.just-perfection-api-panel-indicator-padding-size51 .panel-status-indicators-box { spacing: 51px; } +.just-perfection-api-panel-indicator-padding-size52 .panel-status-indicators-box { spacing: 52px; } +.just-perfection-api-panel-indicator-padding-size53 .panel-status-indicators-box { spacing: 53px; } +.just-perfection-api-panel-indicator-padding-size54 .panel-status-indicators-box { spacing: 54px; } +.just-perfection-api-panel-indicator-padding-size55 .panel-status-indicators-box { spacing: 55px; } +.just-perfection-api-panel-indicator-padding-size56 .panel-status-indicators-box { spacing: 56px; } +.just-perfection-api-panel-indicator-padding-size57 .panel-status-indicators-box { spacing: 57px; } +.just-perfection-api-panel-indicator-padding-size58 .panel-status-indicators-box { spacing: 58px; } +.just-perfection-api-panel-indicator-padding-size59 .panel-status-indicators-box { spacing: 59px; } +.just-perfection-api-panel-indicator-padding-size60 .panel-status-indicators-box { spacing: 60px; } + +.just-perfection-api-no-window-close .window-close, +.just-perfection-api-no-window-close.just-perfection .window-close +{ + height: 0; + width: 0; + background: transparent; + border-radius: 0; + border: 0; + spacing: 0; + box-shadow: none; +} + +.just-perfection-api-no-ripple-box .ripple-box +{ + background-color: transparent; +} + +/** + * This can refresh other styles that is not inculding any standard css styles. + * values are not important here. Just do something that can change the look + */ +.just-perfection-api-refresh-styles .panel-button, +.just-perfection-api-refresh-styles .panel-status-indicators-box, +.just-perfection-api-refresh-styles .panel-button StIcon, +.just-perfection-api-refresh-styles .system-status-icon +{ + background-color: gold; + color: gold; + border-radius: 100px; +} + +.just-perfection-api-no-weather .weather-button, +.just-perfection-api-no-weather .weather-button *, +.just-perfection-api-no-world-clocks .world-clocks-button, +.just-perfection-api-no-world-clocks .world-clocks-button *, +.just-perfection-api-no-events-button .events-button, +.just-perfection-api-no-events-button .events-button * +{ + padding: 0; + margin: 0; + border: 0; + height: 0; + width: 0; +} + +.just-perfection-api-panel-icon-size1 .system-status-icon, .just-perfection-api-panel-icon-size1 .panel-button StIcon { icon-size: 1px; } +.just-perfection-api-panel-icon-size2 .system-status-icon, .just-perfection-api-panel-icon-size2 .panel-button StIcon { icon-size: 2px; } +.just-perfection-api-panel-icon-size3 .system-status-icon, .just-perfection-api-panel-icon-size3 .panel-button StIcon { icon-size: 3px; } +.just-perfection-api-panel-icon-size4 .system-status-icon, .just-perfection-api-panel-icon-size4 .panel-button StIcon { icon-size: 4px; } +.just-perfection-api-panel-icon-size5 .system-status-icon, .just-perfection-api-panel-icon-size5 .panel-button StIcon { icon-size: 5px; } +.just-perfection-api-panel-icon-size6 .system-status-icon, .just-perfection-api-panel-icon-size6 .panel-button StIcon { icon-size: 6px; } +.just-perfection-api-panel-icon-size7 .system-status-icon, .just-perfection-api-panel-icon-size7 .panel-button StIcon { icon-size: 7px; } +.just-perfection-api-panel-icon-size8 .system-status-icon, .just-perfection-api-panel-icon-size8 .panel-button StIcon { icon-size: 8px; } +.just-perfection-api-panel-icon-size9 .system-status-icon, .just-perfection-api-panel-icon-size9 .panel-button StIcon { icon-size: 9px; } +.just-perfection-api-panel-icon-size10 .system-status-icon, .just-perfection-api-panel-icon-size10 .panel-button StIcon { icon-size: 10px; } +.just-perfection-api-panel-icon-size11 .system-status-icon, .just-perfection-api-panel-icon-size11 .panel-button StIcon { icon-size: 11px; } +.just-perfection-api-panel-icon-size12 .system-status-icon, .just-perfection-api-panel-icon-size12 .panel-button StIcon { icon-size: 12px; } +.just-perfection-api-panel-icon-size13 .system-status-icon, .just-perfection-api-panel-icon-size13 .panel-button StIcon { icon-size: 13px; } +.just-perfection-api-panel-icon-size14 .system-status-icon, .just-perfection-api-panel-icon-size14 .panel-button StIcon { icon-size: 14px; } +.just-perfection-api-panel-icon-size15 .system-status-icon, .just-perfection-api-panel-icon-size15 .panel-button StIcon { icon-size: 15px; } +.just-perfection-api-panel-icon-size16 .system-status-icon, .just-perfection-api-panel-icon-size16 .panel-button StIcon { icon-size: 16px; } +.just-perfection-api-panel-icon-size17 .system-status-icon, .just-perfection-api-panel-icon-size17 .panel-button StIcon { icon-size: 17px; } +.just-perfection-api-panel-icon-size18 .system-status-icon, .just-perfection-api-panel-icon-size18 .panel-button StIcon { icon-size: 18px; } +.just-perfection-api-panel-icon-size19 .system-status-icon, .just-perfection-api-panel-icon-size19 .panel-button StIcon { icon-size: 19px; } +.just-perfection-api-panel-icon-size20 .system-status-icon, .just-perfection-api-panel-icon-size20 .panel-button StIcon { icon-size: 20px; } +.just-perfection-api-panel-icon-size21 .system-status-icon, .just-perfection-api-panel-icon-size21 .panel-button StIcon { icon-size: 21px; } +.just-perfection-api-panel-icon-size22 .system-status-icon, .just-perfection-api-panel-icon-size22 .panel-button StIcon { icon-size: 22px; } +.just-perfection-api-panel-icon-size23 .system-status-icon, .just-perfection-api-panel-icon-size23 .panel-button StIcon { icon-size: 23px; } +.just-perfection-api-panel-icon-size24 .system-status-icon, .just-perfection-api-panel-icon-size24 .panel-button StIcon { icon-size: 24px; } +.just-perfection-api-panel-icon-size25 .system-status-icon, .just-perfection-api-panel-icon-size25 .panel-button StIcon { icon-size: 25px; } +.just-perfection-api-panel-icon-size26 .system-status-icon, .just-perfection-api-panel-icon-size26 .panel-button StIcon { icon-size: 26px; } +.just-perfection-api-panel-icon-size27 .system-status-icon, .just-perfection-api-panel-icon-size27 .panel-button StIcon { icon-size: 27px; } +.just-perfection-api-panel-icon-size28 .system-status-icon, .just-perfection-api-panel-icon-size28 .panel-button StIcon { icon-size: 28px; } +.just-perfection-api-panel-icon-size29 .system-status-icon, .just-perfection-api-panel-icon-size29 .panel-button StIcon { icon-size: 29px; } +.just-perfection-api-panel-icon-size30 .system-status-icon, .just-perfection-api-panel-icon-size30 .panel-button StIcon { icon-size: 30px; } +.just-perfection-api-panel-icon-size31 .system-status-icon, .just-perfection-api-panel-icon-size31 .panel-button StIcon { icon-size: 31px; } +.just-perfection-api-panel-icon-size32 .system-status-icon, .just-perfection-api-panel-icon-size32 .panel-button StIcon { icon-size: 32px; } +.just-perfection-api-panel-icon-size33 .system-status-icon, .just-perfection-api-panel-icon-size33 .panel-button StIcon { icon-size: 33px; } +.just-perfection-api-panel-icon-size34 .system-status-icon, .just-perfection-api-panel-icon-size34 .panel-button StIcon { icon-size: 34px; } +.just-perfection-api-panel-icon-size35 .system-status-icon, .just-perfection-api-panel-icon-size35 .panel-button StIcon { icon-size: 35px; } +.just-perfection-api-panel-icon-size36 .system-status-icon, .just-perfection-api-panel-icon-size36 .panel-button StIcon { icon-size: 36px; } +.just-perfection-api-panel-icon-size37 .system-status-icon, .just-perfection-api-panel-icon-size37 .panel-button StIcon { icon-size: 37px; } +.just-perfection-api-panel-icon-size38 .system-status-icon, .just-perfection-api-panel-icon-size38 .panel-button StIcon { icon-size: 38px; } +.just-perfection-api-panel-icon-size39 .system-status-icon, .just-perfection-api-panel-icon-size39 .panel-button StIcon { icon-size: 39px; } +.just-perfection-api-panel-icon-size40 .system-status-icon, .just-perfection-api-panel-icon-size40 .panel-button StIcon { icon-size: 40px; } +.just-perfection-api-panel-icon-size41 .system-status-icon, .just-perfection-api-panel-icon-size41 .panel-button StIcon { icon-size: 41px; } +.just-perfection-api-panel-icon-size42 .system-status-icon, .just-perfection-api-panel-icon-size42 .panel-button StIcon { icon-size: 42px; } +.just-perfection-api-panel-icon-size43 .system-status-icon, .just-perfection-api-panel-icon-size43 .panel-button StIcon { icon-size: 43px; } +.just-perfection-api-panel-icon-size44 .system-status-icon, .just-perfection-api-panel-icon-size44 .panel-button StIcon { icon-size: 44px; } +.just-perfection-api-panel-icon-size45 .system-status-icon, .just-perfection-api-panel-icon-size45 .panel-button StIcon { icon-size: 45px; } +.just-perfection-api-panel-icon-size46 .system-status-icon, .just-perfection-api-panel-icon-size46 .panel-button StIcon { icon-size: 46px; } +.just-perfection-api-panel-icon-size47 .system-status-icon, .just-perfection-api-panel-icon-size47 .panel-button StIcon { icon-size: 47px; } +.just-perfection-api-panel-icon-size48 .system-status-icon, .just-perfection-api-panel-icon-size48 .panel-button StIcon { icon-size: 48px; } +.just-perfection-api-panel-icon-size49 .system-status-icon, .just-perfection-api-panel-icon-size49 .panel-button StIcon { icon-size: 49px; } +.just-perfection-api-panel-icon-size50 .system-status-icon, .just-perfection-api-panel-icon-size50 .panel-button StIcon { icon-size: 50px; } +.just-perfection-api-panel-icon-size51 .system-status-icon, .just-perfection-api-panel-icon-size51 .panel-button StIcon { icon-size: 51px; } +.just-perfection-api-panel-icon-size52 .system-status-icon, .just-perfection-api-panel-icon-size52 .panel-button StIcon { icon-size: 52px; } +.just-perfection-api-panel-icon-size53 .system-status-icon, .just-perfection-api-panel-icon-size53 .panel-button StIcon { icon-size: 53px; } +.just-perfection-api-panel-icon-size54 .system-status-icon, .just-perfection-api-panel-icon-size54 .panel-button StIcon { icon-size: 54px; } +.just-perfection-api-panel-icon-size55 .system-status-icon, .just-perfection-api-panel-icon-size55 .panel-button StIcon { icon-size: 55px; } +.just-perfection-api-panel-icon-size56 .system-status-icon, .just-perfection-api-panel-icon-size56 .panel-button StIcon { icon-size: 56px; } +.just-perfection-api-panel-icon-size57 .system-status-icon, .just-perfection-api-panel-icon-size57 .panel-button StIcon { icon-size: 57px; } +.just-perfection-api-panel-icon-size58 .system-status-icon, .just-perfection-api-panel-icon-size58 .panel-button StIcon { icon-size: 58px; } +.just-perfection-api-panel-icon-size59 .system-status-icon, .just-perfection-api-panel-icon-size59 .panel-button StIcon { icon-size: 59px; } +.just-perfection-api-panel-icon-size60 .system-status-icon, .just-perfection-api-panel-icon-size60 .panel-button StIcon { icon-size: 60px; } + + +.just-perfection-api-osd-position-top .osd-window { margin: 4em 2.5em; } +.just-perfection-api-osd-position-center .osd-window { margin: 4em 3.5em; } +.just-perfection-api-osd-position-bottom .osd-window { margin: 4em 3em; } + +.just-perfection-api-no-dash-separator .dash-separator, +.just-perfection-api-no-app-menu-label .panel-status-menu-box StLabel +{ + width: 0; + height: 0; + spacing: 0; + padding: 0; + margin: 0; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/behavior.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/behavior.ui new file mode 100644 index 0000000..37b57ff --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/behavior.ui @@ -0,0 +1,123 @@ + + + + + behavior + Behavior + applications-engineering-symbolic + + + + Behavior + + + + Hot Corner + hot_corner_switch + + + center + + + + + + + + App Gesture + + gesture_switch + + + center + + + + + + + + Workspace Wraparound + Next workspace will be the first workspace when you are in the last workspace. and previous workspace will be the last workspace when you are in the first workspace. + workspace_wrap_around_switch + + + center + + + + + + + + Window Demands Attention Focus + Removes window is ready notification and focus on the window + window_demands_attention_focus_switch + + + center + + + + + + + + Type to Search + You can start search without search entry or even focusing on it in overview + type_to_search_switch + + + center + + + + + + + + Always Show Workspace Switcher + Shows workspace switcher even when only one workspace used with dynamic workspaces + workspace_switcher_should_show_switch + + + center + + + + + + + + Double Super to App Grid + Shows app grid when you double hit super key fast + double_super_to_appgrid_switch + + + center + + + + + + + + Startup Status + When GNOME Shell is starting up for the first time + startup_status_model + + + + + + + + + + + Desktop + Overview + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/customize.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/customize.ui new file mode 100644 index 0000000..527094d --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/customize.ui @@ -0,0 +1,732 @@ + + + + + customize + Customize + applications-utilities-symbolic + + + + Customize + + + + Workspace Background Corner Size + Workspace background corner size in overview + workspace_background_corner_size_model + + + + + + Panel Size + panel_size_model + + + + + + Panel Icon Size + panel_icon_size_model + + + + + + Panel Button Padding Size + panel_button_padding_size_model + + + + + + Panel Indicator Padding Size + panel_indicator_padding_size_model + + + + + + Panel Corner Size + panel_corner_size_model + + + + + + Panel Position + top_panel_position_model + + + + + + Clock Menu Position + clock_menu_position_model + + + + + + Clock Menu Position Offset + clock_menu_position_offset_model + + + + + + Workspace Switcher Size + workspace_switcher_size_model + + + + + + Animation + animation_model + + + + + + Dash Icon Size + dash_icon_size_model + + + + + + Notification Banner Position + Notification popup position when notifications show up on the screen + notification_banner_position_model + + + + + + OSD Position + OSD position when on screen display shows up on the screen + osd_position_model + + + + + + Alt Tab Window Preview Size + alt_tab_window_preview_size_model + + + + + + Alt Tab Window Preview Icon Size + alt_tab_small_icon_size_model + + + + + + Alt Tab Icon Size + alt_tab_icon_size_model + + + + + + Looking Glass Width + looking_glass_width_model + + + + + + Looking Glass Height + looking_glass_height_model + + + + + + + + + + + By Shell Theme + 0px + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + + By Shell Theme + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + By Shell Theme + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + By Shell Theme + 0px + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + By Shell Theme + 0px + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + By Shell Theme + No Corner + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + + + + + + Top + Bottom + + + + + + Center + Right + Left + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + + + + + Default + 1% + 2% + 3% + 4% + 5% + 6% + 7% + 8% + 9% + 10% + 11% + 12% + 13% + 14% + 15% + 16% + 17% + 18% + 19% + 20% + 21% + 22% + 23% + 24% + 25% + 26% + 27% + 28% + 29% + 30% + + + + + + No Animation + Default Speed + Fastest + Faster + Fast + Slow + Slower + Slowest + + + + + + Default + 32px + 48px + 64px + + + + + + Top Start + Top Center + Top End + Bottom Start + Bottom Center + Bottom End + + + + + + Default + Top Start + Top Center + Top End + Bottom Start + Bottom Center + Bottom End + Center Start + Center + Center End + + + + + + Default + 32 + 64 + 128 + 256 + 512 + + + + + + Default + 32 + 64 + 128 + 256 + 512 + + + + + + Default + 32 + 64 + 128 + 256 + 512 + + + + + + Default + 10% + 20% + 30% + 40% + 50% + 60% + 70% + 80% + 90% + + + + + + Default + 10% + 20% + 30% + 40% + 50% + 60% + 70% + 80% + 90% + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/icons.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/icons.ui new file mode 100644 index 0000000..6f3d02a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/icons.ui @@ -0,0 +1,169 @@ + + + + + icons + Icons + emblem-photos-symbolic + + + + Icons + + + + App Menu Icon + app_menu_icon_switch + + + center + + + + + + + + Panel Notification Icon + panel_notification_icon_switch + + + center + + + + + + + + Power Icon + power_icon_switch + + + center + + + + + + + + Panel Arrow + panel_arrow_switch + + + center + + + + + + + + Window Picker Icon + The icon under window preview in overview + window_picker_icon_switch + + + center + + + + + + + + Activities Button Icon + The icon under window preview in overview + activities_button_icon_path_button + + + True + False + horizontal + + + + False + True + True + True + + + + True + False + edit-delete-symbolic + 1 + + + + + + + + + True + True + True + True + + + + True + False + document-open-symbolic + 1 + + + + + + + + + False + False + + + + + + + + + + + + + Activities Button Icon in Monochrome + activities_button_icon_monochrome_switch + + + center + + + + + + + + Activities Button Icon With Label + Only works when you have selected an icon for activities button + activities_button_label_switch + + + center + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/profile.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/profile.ui new file mode 100644 index 0000000..13841cb --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/profile.ui @@ -0,0 +1,161 @@ + + + + + + + + application/xml + image/png + image/jpeg + + + + + + + Select File + 0 + open + 1 + file_chooser_image_filter + + + + profile + Profile + view-list-symbolic + + + + Profile + + + + True + False + center + You can choose between pre-defined profiles or you can simply use your own customized settings + 0 + True + 0 + 12 + 12 + + + + + + + + + + True + True + 0 + 0 + + + True + True + Default + 1 + 1 + 1 + + + + + True + True + Custom + profile_default + 1 + 1 + + + + + True + True + Minimal + profile_default + 1 + 1 + + + + + True + True + Super Minimal + profile_default + 1 + 1 + + + + + + + + + + + + Override + + + + Shell Theme + Overrides the shell theme partially to create a minimal desktop + theme_switch + + + center + + + + + + + + + + + Links + + + + Bug Report + bug_report_linkbutton + + + https://gitlab.gnome.org/jrahmatzadeh/just-perfection/-/issues + + + + + + + + Support via Patreon + patreon_linkbutton + + + https://www.patreon.com/justperfection + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/visibility.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/visibility.ui new file mode 100644 index 0000000..80c589f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/adw/visibility.ui @@ -0,0 +1,368 @@ + + + + + visibility + Visibility + weather-clear-symbolic + + + + Visibility + + + + Panel + panel_switch + + + center + + + + + + + + Panel in Overview + panel_in_overview_switch + + + + center + + + + + + + + Activities Button + Button in panel to toggle overview visibility + activities_button_switch + + + center + + + + + + + + App Menu + The menu button in panel with focused window text + app_menu_switch + + + center + + + + + + + + App Menu Label + The text label in app menu button + app_menu_label_switch + + + center + + + + + + + + Clock Menu + Also known as date menu shows date and time in panel + clock_menu_switch + + + center + + + + + + + + Keyboard Layout + Keyboard Layout indicator button in panel + keyboard_layout_switch + + + center + + + + + + + + Accessibility Menu + Accessibility Menu indicator button in panel + accessibility_menu_switch + + + center + + + + + + + + System Menu (Aggregate Menu) + System menu holds power, volume and network icons in panel + aggregate_menu_switch + + + center + + + + + + + + Quick Settings + Quick settings menu in panel + quick_settings_switch + + + center + + + + + + + + World Clock + World clock in clock menu + world_clock_switch + + + center + + + + + + + + Weather + Weather in clock menu + weather_switch + + + center + + + + + + + + Calendar + Calendar in clock menu + calendar_switch + + + center + + + + + + + + Events + Events button in clock menu + events_button_switch + + + center + + + + + + + + Search + Search entry in overview + search_switch + + + center + + + + + + + + Dash + Dash holds favorite and opened applications icons + dash_switch + + + center + + + + + + + + Dash Separator + Dash separator line that separates pin apps from unpin apps + dash_separator_switch + + + center + + + + + + + + Show Applications Button + Button in dash that toggles applications list visibility + show_apps_button_switch + + + center + + + + + + + + On Screen Display (OSD) + Volume and brightness on screen display when the change happens + osd_switch + + + center + + + + + + + + Workspace Popup + Popup that appears on the screen when you change the workspace + workspace_popup_switch + + + center + + + + + + + + Workspace Switcher + Also refers to workspace thumbnails that you see in overview for selecting a workspace + workspace_switch + + + center + + + + + + + + Workspaces App Grid + Workspace boxes in app grid + workspaces_in_app_grid_switch + + + center + + + + + + + + Window Picker Close Button + The close button on window preview in overview + window_preview_close_button_switch + + + center + + + + + + + + Window Picker Caption + The text under window preview in overview + window_preview_caption_switch + + + center + + + + + + + + Background Menu + When you right click on desktop background + background_menu_switch + + + center + + + + + + + + Ripple Box + Hot corner animation effects + ripple_box_switch + + + center + + + + + + + + Take Screenshot button in Window Menu + Take screenshot button in title bar right click menu + window_menu_take_screenshot_button_switch + + + center + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/behavior.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/behavior.ui new file mode 100644 index 0000000..ba51130 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/behavior.ui @@ -0,0 +1,616 @@ + + + + + True + True + vertical + + + + True + False + 12 + + + + True + False + Behavior + + + + + + + + + + + + True + False + 0 + 36 + + + + True + False + none + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Hot Corner + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + App Gesture + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Workspace Wraparound + 0 + 1 + + + + + + True + False + center + Next workspace will be the first workspace when you are in the last workspace. and previous workspace will be the last workspace when you are in the first workspace. + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Window Demands Attention Focus + 0 + 1 + + + + + + True + False + center + Removes window is ready notification and focus on the window + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Type to Search + 0 + 1 + + + + + + True + False + center + You can start search without search entry or even focusing on it in overview + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Always Show Workspace Switcher + 0 + 1 + + + + + + True + False + center + Shows workspace switcher even when only one workspace used with dynamic workspaces + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Double Super to App Grid + 0 + 1 + + + + + + True + False + center + Shows app grid when you double hit super key fast + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Startup Status + 0 + 1 + + + + + + True + False + center + When GNOME Shell is starting up for the first time + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + Desktop + Overview + + + + + + + + + + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/customize.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/customize.ui new file mode 100644 index 0000000..116c6a6 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/customize.ui @@ -0,0 +1,1586 @@ + + + + + True + True + vertical + + + + True + False + 12 + + + + True + False + Customize + + + + + + + + + + + + True + False + 0 + + + + True + False + none + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Workspace Background Corner Size + 0 + 1 + + + + + + True + False + center + Workspace background corner size in overview + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + By Shell Theme + 0px + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Size + 0 + 1 + + + + + + True + True + center + + By Shell Theme + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Icon Size + 0 + 1 + + + + + + True + True + center + + By Shell Theme + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Button Padding Size + 0 + 1 + + + + + + True + True + center + + By Shell Theme + 0px + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Indicator Padding Size + 0 + 1 + + + + + + True + True + center + + By Shell Theme + 0px + 1px + 2px + 3px + 4px + 5px + 6px + 7px + 8px + 9px + 10px + 11px + 12px + 13px + 14px + 15px + 16px + 17px + 18px + 19px + 20px + 21px + 22px + 23px + 24px + 25px + 26px + 27px + 28px + 29px + 30px + 31px + 32px + 33px + 34px + 35px + 36px + 37px + 38px + 39px + 40px + 41px + 42px + 43px + 44px + 45px + 46px + 47px + 48px + 49px + 50px + 51px + 52px + 53px + 54px + 55px + 56px + 57px + 58px + 59px + 60px + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Corner Size + 0 + 1 + + + + + + True + True + center + + By Shell Theme + No Corner + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Position + 0 + 1 + + + + + + True + True + center + + Top + Bottom + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Clock Menu Position + 0 + 1 + + + + + + True + True + center + + Center + Right + Left + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Clock Menu Position Offset + 0 + 1 + + + + + + True + True + center + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Workspace Switcher Size + 0 + 1 + + + + + + True + True + center + + Default + 1% + 2% + 3% + 4% + 5% + 6% + 7% + 8% + 9% + 10% + 11% + 12% + 13% + 14% + 15% + 16% + 17% + 18% + 19% + 20% + 21% + 22% + 23% + 24% + 25% + 26% + 27% + 28% + 29% + 30% + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Animation + 0 + 1 + + + + + + True + True + center + + No Animation + Default Speed + Fastest + Faster + Fast + Slow + Slower + Slowest + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Dash Icon Size + 0 + 1 + + + + + + True + True + center + + Default + 32px + 48px + 64px + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Notification Banner Position + 0 + 1 + + + + + + True + False + center + Notification popup position when notifications show up on the screen + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + Top Start + Top Center + Top End + Bottom Start + Bottom Center + Bottom End + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + OSD Position + 0 + 1 + + + + + + True + False + center + OSD position when on screen display shows up on the screen + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + Default + Top Start + Top Center + Top End + Bottom Start + Bottom Center + Bottom End + Center Start + Center + Center End + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Alt Tab Window Preview Size + 0 + 1 + + + + + + True + True + center + + Default + 32 + 64 + 128 + 256 + 512 + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Alt Tab Window Preview Icon Size + 0 + 1 + + + + + + True + True + center + + Default + 32 + 64 + 128 + 256 + 512 + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Alt Tab Icon Size + 0 + 1 + + + + + + True + True + center + + Default + 32 + 64 + 128 + 256 + 512 + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Looking Glass Width + 0 + 1 + + + + + + True + True + center + + Default + 10% + 20% + 30% + 40% + 50% + 60% + 70% + 80% + 90% + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Looking Glass Height + 0 + 1 + + + + + + True + True + center + + Default + 10% + 20% + 30% + 40% + 50% + 60% + 70% + 80% + 90% + + + + + + + + + + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/icons.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/icons.ui new file mode 100644 index 0000000..a04053e --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/icons.ui @@ -0,0 +1,550 @@ + + + + + True + True + vertical + + + + True + False + 12 + + + + True + False + Icons + + + + + + + + + + + + True + False + 0 + 36 + + + + True + False + none + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + App Menu Icon + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Notification Icon + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Power Icon + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel Arrow + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Window Picker Icon + 0 + 1 + + + + + + True + False + center + The icon under window preview in overview + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Activities Button Icon + 0 + 1 + + + + + + True + False + horizontal + + + + False + True + True + True + + + + True + False + edit-delete-symbolic + 1 + + + + + + + + + True + True + True + True + + + + True + False + document-open-symbolic + 1 + + + + + + + + + False + False + + + + + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Activities Button Icon in Monochrome + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Activities Button Icon With Label + 0 + 1 + + + + + + True + False + center + Only works when you have selected an icon for activities button + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/intro.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/intro.ui new file mode 100644 index 0000000..ef60340 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/intro.ui @@ -0,0 +1,35 @@ + + + + + True + False + 36 + center + center + + + + True + True + start + start + 0 + 0 + https://www.patreon.com/justperfection + + + + True + False + center + vertical + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/main.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/main.ui new file mode 100644 index 0000000..ea81568 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/main.ui @@ -0,0 +1,176 @@ + + + + + + + +
+ + Bug Report + prefs.show-bug-report + + + Support via Patreon + prefs.show-patreon + +
+
+ + + + + True + True + 1 + + + + True + True + True + + + + True + False + system-search-symbolic + 1 + + + + + + + + + + True + True + True + True + primary_menu + + + + True + False + open-menu-symbolic + 1 + + + + + + + + + + application/xml + image/png + image/jpeg + + + + + + + Select File + 0 + open + 1 + file_chooser_image_filter + + + + + + True + True + vertical + 1 + + + + + + True + True + + + + True + True + slide-up + True + 24 + 24 + 5 + 5 + 1 + 250 + + + + True + True + vertical + 1 + + + + True + True + 1 + + + + + + + + + + + + + + + + + 450 + 450 + never + True + True + 1 + + + + True + False + + + + True + False + 36 + 36 + 36 + 36 + vertical + + + + + + + + + + + + + + +
diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/no-results-found.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/no-results-found.ui new file mode 100644 index 0000000..04571d8 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/no-results-found.ui @@ -0,0 +1,35 @@ + + + + + False + False + 0 + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + center + center + No Matches + 1 + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/override.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/override.ui new file mode 100644 index 0000000..d58bfcf --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/override.ui @@ -0,0 +1,131 @@ + + + + + True + True + vertical + + + + True + False + 12 + + + + True + False + Override + + + + + + + + + + + + True + False + 0 + 36 + + + + True + False + none + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + 1 + 1 + vertical + + + + True + False + center + Shell Theme + 0 + 1 + + + + + + True + False + center + Overrides the shell theme partially to create a minimal desktop + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/profile.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/profile.ui new file mode 100644 index 0000000..0eb06dc --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/profile.ui @@ -0,0 +1,104 @@ + + + + + True + True + vertical + 36 + + + + True + False + 12 + vertical + + + + True + False + Profile + 0 + + + + + + + + + True + False + center + You can choose between pre-defined profiles or you can simply use your own customized settings + 0 + True + 0 + 12 + 12 + + + + + + + + + + True + True + + + True + True + Default + 1 + 1 + 1 + + + + + True + True + Custom + profile_default + 1 + 1 + + + + + True + True + Minimal + profile_default + 1 + 1 + + + + + True + True + Super Minimal + profile_default + 1 + 1 + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/visibility.ui b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/visibility.ui new file mode 100644 index 0000000..ccc89ba --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/just-perfection-desktop@just-perfection/ui/visibility.ui @@ -0,0 +1,2078 @@ + + + + + True + True + vertical + + + + True + False + 12 + + + + True + False + Visibility + + + + + + + + + + + + True + False + 0 + 36 + + + + True + False + none + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + False + center + Panel in Overview + 0 + 1 + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + + True + True + vertical + + + + True + False + center + Activities Button + 0 + 1 + + + + + + True + False + center + Button in panel to toggle overview visibility + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + App Menu + 0 + 1 + + + + + + True + False + center + The menu button in panel with focused window text + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + App Menu Label + 0 + 1 + + + + + + True + False + center + The text label in app menu button + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Clock Menu + 0 + 1 + + + + + + True + False + center + Also known as date menu shows date and time in panel + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Keyboard Layout + 0 + 1 + + + + + + True + False + center + Keyboard Layout indicator button in panel + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Accessibility Menu + 0 + 1 + + + + + + True + False + center + Accessibility Menu indicator button in panel + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + System Menu (Aggregate Menu) + 0 + 1 + + + + + + True + False + center + System menu holds power, volume and network icons in panel + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Quick Settings + 0 + 1 + + + + + + True + False + center + Quick settings menu in panel + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + World Clock + 0 + 1 + + + + + + True + False + center + World clock in clock menu + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Weather + 0 + 1 + + + + + + True + False + center + Weather in clock menu + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Calendar + 0 + 1 + + + + + + True + False + center + Calendar in clock menu + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Events + 0 + 1 + + + + + + True + False + center + Events button in clock menu + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Search + 0 + 1 + + + + + + True + False + center + Search entry in overview + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Dash + 0 + 1 + + + + + + True + False + center + Dash holds favorite and opened applications icons + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Dash Separator + 0 + 1 + + + + + + True + False + center + Dash separator line that separates pin apps from unpin apps + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Show Applications Button + 0 + 1 + + + + + + True + False + center + Button in dash that toggles applications list visibility + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + On Screen Display (OSD) + 0 + 1 + + + + + + True + False + center + Volume and brightness on screen display when the change happens + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Workspace Popup + 0 + 1 + + + + + + True + False + center + Popup that appears on the screen when you change the workspace + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Workspace Switcher + 0 + 1 + + + + + + True + False + center + Also refers to workspace thumbnails that you see in overview for selecting a workspace + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Workspaces App Grid + 0 + 1 + + + + + + True + False + center + Workspace boxes in app grid + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Window Picker Close Button + 0 + 1 + + + + + + True + False + center + The close button on window preview in overview + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Window Picker Caption + 0 + 1 + + + + + + True + False + center + The text under window preview in overview + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Background Menu + 0 + 1 + + + + + + True + False + center + When you right click on desktop background + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Ripple Box + 0 + 1 + + + + + + True + False + center + Hot corner animation effects + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + True + True + + + + True + False + 12 + 12 + 12 + 12 + vertical + + + + True + False + 32 + + + + True + True + vertical + + + + True + False + center + Take Screenshot button in Window Menu + 0 + 1 + + + + + + True + False + center + Take screenshot button in title bar right click menu + 0 + True + 0 + 12 + + + + + + + + + + + + + True + True + center + + + + + + + + + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/extension.js new file mode 100644 index 0000000..645c360 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/extension.js @@ -0,0 +1,435 @@ +/* extension.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* exported init */ + +'use strict'; + +const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi; + +const Main = imports.ui.main; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; +const SystemActions = imports.misc.systemActions; +const ExtensionUtils = imports.misc.extensionUtils; +const System = Main.panel.statusArea.aggregateMenu._system; +const SystemMenu = System.menu; + +const GnomeSession = imports.misc.gnomeSession; +let SessionManager = null; + +const Config = imports.misc.config; +const SHELL_MAJOR_VERSION = parseInt(Config.PACKAGE_VERSION.split('.')[0]); + +let DefaultActions; +let bindFlags; +let item; +let button; + +var LabelLauncher = new GObject.registerClass( +class LabelLauncher extends St.Widget { +_init() { + this._labelText = ""; + this.label = new St.Label({ style_class: 'dash-label' }); + this.label.hide(); + Main.layoutManager.addChrome(this.label); + this.label_actor = this.label; + } + +showLabel(button) { + this.label.set_text(button.get_accessible_name()); + this.label.opacity = 0; + this.label.show(); + + let node = this.label.get_theme_node(); + let stageX; + let stageY; + let yOffset; + + if(SHELL_MAJOR_VERSION == 3) { + stageX = Math.floor(button.get_transformed_position().slice()[0] + (button.get_width()/2)); + stageY = Math.floor(Main.panel.statusArea.aggregateMenu.menu.box.get_transformed_position().slice()[1] + Main.panel.statusArea.aggregateMenu.menu.box.get_height()); + yOffset = node.get_length('-x-offset'); + } else if(SHELL_MAJOR_VERSION >= 40) { + stageX = button.get_transformed_extents().get_center().x; + stageY = Main.panel.statusArea.aggregateMenu.menu.box.get_transformed_extents().get_bottom_right().y; + yOffset = node.get_length('-y-offset'); + } + + const labelWidth = this.label.get_width(); + const xOffset = Math.floor(labelWidth / 2); + + const x = stageX - xOffset; + const y = stageY + yOffset; + + this.label.set_position(x, y); + this.label.ease({ + opacity: 255, + duration: 100, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + }); + } + +hideLabel() { + this.label.ease({ + opacity: 0, + duration: 100, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => this.label.hide(), + }); + } +}); + +var _systemMenuButtons = new GObject.registerClass( +class SystemMenuButtons extends PanelMenu.SystemIndicator { + +_init() { + + this._showLabelTimeoutId = 0; + this._resetHoverTimeoutId = 0; + this._labelShowing = false; + + DefaultActions = new SystemActions.getDefault(); + this._settings = ExtensionUtils.getSettings(); + + SystemMenu.actor.remove_child(System._orientationLockItem); + SystemMenu.actor.remove_child(System._settingsItem); + SystemMenu.actor.remove_child(System._lockScreenItem); + SystemMenu.actor.remove_child(System._sessionSubMenu); + + this._createMenu(); + + this._connectSettings(); + + SystemMenu.connect('open-state-changed', (menu, open) => { + if(!open) + return; + DefaultActions._updateOrientationLock(); + DefaultActions._sessionUpdated(); + DefaultActions.forceUpdate(); + }); + } + +_syncLabel(tooltip, button) { + if (tooltip.child.hover) { + if (this._showLabelTimeoutId == 0) { + let timeout = this._labelShowing ? 0 : 100; + this._showLabelTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, timeout, + () => { + this._labelShowing = true; + tooltip.showLabel(button); + this._showLabelTimeoutId = 0; + return GLib.SOURCE_REMOVE; + }); + GLib.Source.set_name_by_id(this._showLabelTimeoutId, '[gnome-shell] tooltip.showLabel'); + if (this._resetHoverTimeoutId > 0) { + GLib.source_remove(this._resetHoverTimeoutId); + this._resetHoverTimeoutId = 0; + } + } + } else { + if (this._showLabelTimeoutId > 0) + GLib.source_remove(this._showLabelTimeoutId); + this._showLabelTimeoutId = 0; + tooltip.hideLabel(); + if (this._labelShowing) { + this._resetHoverTimeoutId = GLib.timeout_add( + GLib.PRIORITY_DEFAULT, 100, + () => { + this._labelShowing = false; + this._resetHoverTimeoutId = 0; + return GLib.SOURCE_REMOVE; + }); + GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing'); + } + } + } + +_hookUpLabel(tooltip, button) { + tooltip.child.connect('notify::hover', () => { + this._syncLabel(tooltip, button); + }); + + tooltip.child.connect('clicked', () => { + this._labelShowing = false; + tooltip.hideLabel(); + }); + } + +_createActionButton(iconName, accessibleName) { + + let roundButton = new St.Button({ reactive: true, + can_focus: true, + track_hover: true, + accessible_name: accessibleName, + x_expand: true, + x_align: 2, + style_class: 'rounded-menu-buttons', + }); + + roundButton.child = new St.Icon({ icon_name: iconName, icon_size: this._settings.get_int('icon-size') }); + + let useCustomColor = this._settings.get_boolean('use-custom-color'); + roundButton.set_style("color: " + `${useCustomColor ? this._settings.get_string('color') : '#eeeeec'};` + + " padding: " + this._settings.get_int('padding') + "px; " + + "border-radius: " + this._settings.get_int('border-radius') + "px;"); + + + let tooltip = new LabelLauncher(); + tooltip.child = roundButton; + this._hookUpLabel(tooltip, roundButton); + + return roundButton; + } + +_createMenu() { + bindFlags = GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE; + item = new PopupMenu.PopupBaseMenuItem({ reactive: false, can_focus: false }); + let iconSize = this._settings.get_int('icon-size'); + let boolean; + + // ORIENTATION BUTTON + + this._orientationButton = this._createActionButton(DefaultActions.orientation_lock_icon, DefaultActions.getName(_('lock-orientation'))); + this._orientationButton.connect('clicked', () => { + DefaultActions.activateLockOrientation(); + }); + + item.actor.add(this._orientationButton); + DefaultActions.bind_property('can-lock-orientation', this._orientationButton, 'visible', bindFlags); + + DefaultActions.connect('notify::orientation-lock-icon', () => { + let iconName = DefaultActions.orientation_lock_icon; + let labelText = DefaultActions.getName('lock-orientation'); + + this._orientationButton.setIcon(iconName); + this._orientationButton.label.text = labelText; }); + + // SETTINGS BUTTON + + let app = this._settingsApp = Shell.AppSystem.get_default().lookup_app('org.gnome.Settings.desktop') ? + Shell.AppSystem.get_default().lookup_app('org.gnome.Settings.desktop') : + Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop') + if (app) { + this._settingsButton = this._createActionButton('org.gnome.Settings-symbolic', _('Settings')); + this._settingsButton.connect('clicked', () => { + Main.overview.hide(); + this._settingsApp.activate(); + }); + + item.actor.add(this._settingsButton); + } else { + log('Missing required core component Settings, expect trouble…'); + this._settingsButton = null; + } + + // LOCK BUTTON + + this._lockButton = this._createActionButton('changes-prevent-symbolic', _('Lock')); + this._lockButton.connect('clicked', () => { + DefaultActions.activateLockScreen(); + }); + + item.actor.add(this._lockButton); + DefaultActions.bind_property('can-lock-screen', this._lockButton, 'visible', bindFlags); + + // SUSPEND + + this._suspendButton = this._createActionButton('media-playback-pause-symbolic', _('Suspend')); + this._suspendButton.connect('clicked', () => { + DefaultActions.activateSuspend(); + }); + + boolean = this._settings.get_boolean('remove-suspend-button'); + + if(boolean) { + this._suspendButton = null; + } else { + item.actor.add(this._suspendButton); + DefaultActions.bind_property('can-suspend', this._suspendButton, 'visible', bindFlags); } + + // SWITCH USER + + this._switchUserButton = this._createActionButton('system-switch-user-symbolic', _('Switch User…')); + this._switchUserButton.connect('clicked', () => { + DefaultActions.activateSwitchUser(); + }); + + item.actor.add(this._switchUserButton); + DefaultActions.bind_property('can-switch-user', this._switchUserButton, 'visible', bindFlags); + + // LOGOUT + + this._logoutButton = this._createActionButton('system-log-out-symbolic', _('Log Out')); + this._logoutButton.connect('clicked', () => { + DefaultActions.activateLogout(); + }); + + boolean = this._settings.get_boolean('remove-logout-button'); + + if(boolean) { + this._logoutButton = null; + } else { + item.actor.add(this._logoutButton) + DefaultActions.bind_property('can-logout', this._logoutButton, 'visible', bindFlags); } + + // RESTART + + this._restartButton = this._createActionButton('system-reboot-symbolic', _('Restart…')); + this._restartButton.connect('clicked', () => { + SHELL_MAJOR_VERSION >= 40 ? DefaultActions.activateRestart() : SessionManager.RebootRemote(); + }); + + boolean = this._settings.get_boolean('remove-restart-button'); + + if(boolean) { + this._restartButton = null; + } else { + item.actor.add(this._restartButton) + SHELL_MAJOR_VERSION >=40 ? DefaultActions.bind_property('can-restart', this._restartButton, 'visible', bindFlags) : + DefaultActions.bind_property('can-power-off', this._restartButton, 'visible', bindFlags) } + + // POWEROFF + + this._powerButton = this._createActionButton('system-shutdown-symbolic', _('Power Off…')); + this._powerButton.connect('clicked', () => { + DefaultActions.activatePowerOff(); + }); + + boolean = this._settings.get_boolean('remove-poweroff-button'); + + if(boolean) { + this._powerButton = null; + } else { + item.actor.add(this._powerButton) + DefaultActions.bind_property('can-power-off', this._powerButton, 'visible', bindFlags); } + + // Main Course + + SystemMenu.box.add_actor(item); + + this._getAvailableButtons(); + + DefaultActions._updateOrientationLock(); + DefaultActions._sessionUpdated(); + DefaultActions.forceUpdate(); + } + +_getAvailableButtons() { + let BUTTONS_ORDER = this._settings.get_value('buttons-order').deepUnpack(); + + const initialArray = [ + this._orientationButton, + this._settingsButton, + this._lockButton, + this._suspendButton, + this._switchUserButton, + this._logoutButton, + this._restartButton, + this._powerButton + ] + + const orderedArray = BUTTONS_ORDER.map((idx) => initialArray[idx - 1]); + + const filterdArray = orderedArray.filter(obj => obj != null); + + for (let i = 0; i < filterdArray.length; i++) { + item.remove_actor(filterdArray[i]); + item.actor.add(filterdArray[i]); + } +} + +_connectSettings() { + this.colorChanged = this._settings.connect('changed::color', this._settingsChanged.bind(this)); + this.useCustomColorChanged = this._settings.connect('changed::use-custom-color', this._settingsChanged.bind(this)); + this.removeSuspendButtonChanged = this._settings.connect('changed::remove-suspend-button', this._settingsChanged.bind(this)); + this.removeLogoutButtonChanged = this._settings.connect('changed::remove-logout-button', this._settingsChanged.bind(this)); + this.removeRestartButtonChanged = this._settings.connect('changed::remove-restart-button', this._settingsChanged.bind(this)); + this.removePoweroffButtonChanged = this._settings.connect('changed::remove-poweroff-button', this._settingsChanged.bind(this)); + this.iconSizeChanged = this._settings.connect('changed::icon-size', this._settingsChanged.bind(this)); + this.borderRadiusChanged = this._settings.connect('changed::border-radius', this._settingsChanged.bind(this)); + this.paddingChanged = this._settings.connect('changed::padding', this._settingsChanged.bind(this)); + this.buttonsOrderChanged = this._settings.connect('changed::buttons-order', this._settingsChanged.bind(this)); + } + +_onDestroy() { + + const disconnectArray = [ + this.colorChanged, + this.useCustomColorChanged, + this.removeSuspendButtonChanged, + this.removeLogoutButtonChanged, + this.removeRestartButtonChanged, + this.removePoweroffButtonChanged, + this.iconSizeChanged, + this.borderRadiusChanged, + this.paddingChanged, + this.buttonsOrderChanged + ] + + for (let i = 0; i < disconnectArray.length; i++) { + if(disconnectArray[i]) { + this._settings.disconnect(disconnectArray[i]) + disconnectArray[i] = 0; } + } + + if(this._resetHoverTimeoutID) { + GLib.source_remove(this._resetHoverTimeoutID); + this._resetHoverTimeoutID = null; + } + + if(this._showLabelTimeoutID) { + GLib.source_remove(this._showLabelTimeoutID); + this._showLabelTimeoutID = null; + } + } + +_settingsChanged() { + SystemMenu.box.remove_actor(item); + this._createMenu(); + } +}); + +function init() { +} + +let modifiedMenu; + +function enable() { +SessionManager = GnomeSession.SessionManager(); +modifiedMenu = new _systemMenuButtons(); +} + +function disable() { + SystemMenu.box.remove_actor(item); + + if(SessionManager) { + SessionManager = null; + } + + modifiedMenu._onDestroy(); + modifiedMenu = null; + + SystemMenu.actor.insert_child_at_index(System._orientationLockItem, SystemMenu.numMenuItems); + SystemMenu.actor.insert_child_at_index(System._settingsItem, SystemMenu.numMenuItems); + SystemMenu.actor.insert_child_at_index(System._lockScreenItem, SystemMenu.numMenuItems); + SystemMenu.actor.insert_child_at_index(System._sessionSubMenu, SystemMenu.numMenuItems); +} + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/metadata.json b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/metadata.json new file mode 100644 index 0000000..f39dac9 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/metadata.json @@ -0,0 +1,14 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Rounded System Menu Buttons", + "name": "Rounded System Menu Buttons", + "settings-schema": "org.gnome.shell.extensions.round-system-menu-buttons", + "shell-version": [ + "40", + "41", + "42" + ], + "url": "https://github.com/PRATAP-KUMAR/rounded-system-menu-buttons", + "uuid": "roundedSystemMenuButtons@pratap.fastmail.fm", + "version": 20 +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/prefs.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/prefs.js new file mode 100644 index 0000000..da92b86 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/prefs.js @@ -0,0 +1,492 @@ +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; +const Gdk = imports.gi.Gdk; + +const ExtensionUtils = imports.misc.extensionUtils; + +const initialArray = [ + 'ORIENTATION BUTTON', + 'SETTINGS BUTTON', + 'LOCK BUTTON', + 'SUSPEND BUTTON', + 'SWITCH_USER BUTTON', + 'LOGOUT BUTTON', + 'RESTART BUTTON', + 'POWER BUTTON' + ] + +const GTK_VERSION = Gtk.get_major_version(); +let add; +let addRow; + if(GTK_VERSION == 4) { + add = 'append'; + addRow = 'set_child'; + } else { + add = 'add'; + addRow = 'add'; } + +function init() { +} + +function buildPrefsWidget() { + let widget = new PrefsWidget(); + if(GTK_VERSION == 3) { + widget.widget.show_all(); } + return widget.widget; +} + +class PrefsWidget { + constructor() { + this._settings = ExtensionUtils.getSettings(); + + this.BC_button = new Gtk.ColorButton(); + this._setButtonColor(); + + this.notebook = new Gtk.Notebook({ visible: true }); + + this.widget = new Gtk.Grid({ visible: true, column_homogeneous: true }); + this.notebook = new Gtk.Notebook({ visible: true }); + + this.listBox = []; + + this.listBox = new Gtk.ListBox({ visible: true }); + this.listBox.set_selection_mode(0); + + this.widget.attach(this.notebook, 0, 0, 1, 1); + + // Basic Settings Page + + let grid = new Gtk.Grid({ + column_spacing: 12, row_spacing: 12, + column_homogeneous: true, + hexpand: true, vexpand: true, + margin_start: 14, margin_end: 14, margin_top: 14, margin_bottom: 14, + visible: true + }); + + + let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 10, visible: true }); + + grid.attach(vbox, 0, 0, 3, 1); + + vbox[add](this.selectButtonColor()); + vbox[add](this.customColorButton()); + vbox[add](this.adjustIconSize()); + vbox[add](this.adjustPadding()); + vbox[add](this.adjustBorderRadius()); + vbox[add](this.resetButton()); + vbox[add](new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL, margin_bottom: 10, margin_top: 10 })); + vbox[add](this.removeSuspendButton()); + vbox[add](this.removeLogoutButton()); + vbox[add](this.removeRestartButton()); + vbox[add](this.removePoweroffButton()); + vbox[add](new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL, margin_bottom: 10, margin_top: 10 })); + vbox[add](this.tip()); + vbox[add](this.command()); + + this.notebook.append_page(grid, new Gtk.Label({ label: 'Basic Settings', visible: true, hexpand: true })); + + // End of Basic Settings Page + + // Arrange Button Order Page + + this.Buttons = []; + this.finalArray = []; + + let grid2 = new Gtk.Grid({ + column_spacing: 12, row_spacing: 12, + column_homogeneous: true, + hexpand: true, vexpand: true, + margin_start: 14, margin_end: 14, margin_top: 14, margin_bottom: 14, + visible: true + }); + + //let topHbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 20, visible: true }); + //grid.attach(topHbox, 0, 0, 2, 1); + + this.listBox = new Gtk.ListBox({ visible: true }); + this.listBox.set_selection_mode(0); + + this._prepareRow(initialArray); + this._saveOrder(); + this._removeListBox(); + + let BUTTONS_ORDER = this._settings.get_value('buttons-order').deepUnpack(); + let FINALARRAY = []; + + for (let i = 0; i < initialArray.length; i ++) { + let text = initialArray[BUTTONS_ORDER[i]-1] + FINALARRAY.push(text); + } + + this._prepareRow(FINALARRAY); + + grid2.attach(this.listBox, 0, 1, 1, 1); + + let RESET = new Gtk.Button(); + RESET.set_label("Reset 'Buttons Order' to Extensions Default."); + RESET.connect("clicked", () => { this._removeListBox(); + this._prepareRow(initialArray); + const value = new GLib.Variant('ai', [1, 2, 3, 4, 5, 6, 7, 8]); + this._settings.set_value('buttons-order', value); + }); + + grid2.attach(RESET, 0, 2, 1, 1); + + this.notebook.append_page(grid2, new Gtk.Label({ label: "Arrange 'Buttons Order'", visible: true, hexpand: true })); + + } + + // End of Arrange Button Order Page + +_prepareRow(ARRAY) { + + for(let i = 0; i < ARRAY.length; i++) { + + let row = new Gtk.ListBoxRow({ visible: true }); + + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, visible: true }); + + row[addRow](hbox); + + let TEXT = new Gtk.Button({ hexpand: true, margin_end: 10 }); + TEXT.set_label(ARRAY[i]); + + let ImageButton = new Gtk.Button({ margin_end: 10 }); + let B; + + let A = 'rotation-allowed-symbolic'; + + GTK_VERSION == 4 ? + B = 'org.gnome.Settings-symbolic' : B = 'system-settings-symbolic'; + + let C = 'changes-prevent-symbolic'; + let D = 'media-playback-pause-symbolic'; + let E = 'system-switch-user-symbolic'; + let F = 'system-log-out-symbolic'; + let G = 'system-reboot-symbolic'; + let H = 'system-shutdown-symbolic'; + + if(TEXT.get_label() == initialArray[0]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(A) : ImageButton.set_image(new Gtk.Image({ icon_name: A })); + if(TEXT.get_label() == initialArray[1]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(B) : ImageButton.set_image(new Gtk.Image({ icon_name: B })); + if(TEXT.get_label() == initialArray[2]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(C) : ImageButton.set_image(new Gtk.Image({ icon_name: C })); + if(TEXT.get_label() == initialArray[3]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(D) : ImageButton.set_image(new Gtk.Image({ icon_name: D })); + if(TEXT.get_label() == initialArray[4]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(E) : ImageButton.set_image(new Gtk.Image({ icon_name: E })); + if(TEXT.get_label() == initialArray[5]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(F) : ImageButton.set_image(new Gtk.Image({ icon_name: F })); + if(TEXT.get_label() == initialArray[6]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(G) : ImageButton.set_image(new Gtk.Image({ icon_name: G })); + if(TEXT.get_label() == initialArray[7]) + GTK_VERSION == 4 ? ImageButton.set_icon_name(H) : ImageButton.set_image(new Gtk.Image({ icon_name: H })); + + let upButton = new Gtk.Button({margin_end: 10}); + GTK_VERSION == 4 ? upButton.set_icon_name('go-up-symbolic') : upButton.set_image(new Gtk.Image({ icon_name: 'go-up-symbolic' })); + upButton.connect("clicked", () => { this._moveUp(i) }); + + let downButton = new Gtk.Button(); + GTK_VERSION == 4 ? downButton.set_icon_name('go-down-symbolic') : downButton.set_image(new Gtk.Image({ icon_name: 'go-down-symbolic' })); + downButton.connect("clicked", () => { this._moveDown(i) }); + + hbox[add](ImageButton); + hbox[add](TEXT); + hbox[add](upButton); + hbox[add](downButton); + + this.listBox[add](row) + } + + } + +_arraymove(array, fromIndex, toIndex) { + let element = array[fromIndex]; + array.splice(fromIndex, 1); + array.splice(toIndex, 0, element); + } + +_saveOrder () { + + if(GTK_VERSION == 4) { + for (let i = 0; i < initialArray.length; i++) { + let entry = this.listBox.get_row_at_index(i).get_child().get_first_child(); + entry = entry.get_next_sibling(); + let label = entry.get_label(); + this.Buttons.push(label); + } + } else { + for (let i = 0; i < initialArray.length; i++) { + let label = this.listBox.get_row_at_index(i).get_child().get_children()[1].get_label(); + this.Buttons.push(label); + } + } + + } + +_removeListBox () { + if(GTK_VERSION == 4) { + let child = this.listBox.get_first_child(); + while (child != null) { + let next = child.get_next_sibling(); + this.listBox.remove(child); + child = next; + } + } else { + this.listBox.foreach((element) => this.listBox.remove(element)); + } + } + +_moveUp (i) { + this.Buttons = []; + this._saveOrder(); + + this._removeListBox(); + + if(i == 0) { + this._arraymove(this.Buttons, 0, 7); + } else { + this._arraymove(this.Buttons, i, i-1) } + + this._prepareRow(this.Buttons); + + this.finalArray = []; + + for (let i = 0; i < initialArray.length; i ++) { + let index = initialArray.indexOf(this.Buttons[i]) + 1; + this.finalArray.push(index); + } + + const value = new GLib.Variant('ai', this.finalArray); + this._settings.set_value('buttons-order', value); + } + +_moveDown (i) { + this.Buttons = []; + this._saveOrder(); + + this._removeListBox(); + + if(i == 7) { + this._arraymove(this.Buttons, 7, 0); + } else { + this._arraymove(this.Buttons, i, i+1) } + + this._prepareRow(this.Buttons); + + this.finalArray = []; + + for (let i = 0; i < initialArray.length; i ++) { + let index = initialArray.indexOf(this.Buttons[i]) + 1; + this.finalArray.push(index); + } + + const value = new GLib.Variant('ai', this.finalArray); + this._settings.set_value('buttons-order', value); + } + +_setButtonColor() { + let rgba = new Gdk.RGBA(); + let hexString = this._settings.get_string('color'); + rgba.parse(hexString); + this.BC_button.set_rgba(rgba); + } + + +_cssHexString(css) { + let rrggbb = '#'; + let start; + for(let loop = 0; loop < 3; loop++) { + let end = 0; + let xx = ''; + for(let loop = 0; loop < 2; loop++) { + while(true) { + let x = css.slice(end, end + 1); + if(x == '(' || x == ',' || x == ')') + break; + end = end + 1; + } + if(loop == 0) { + end = end + 1; + start = end; + } + } + xx = parseInt(css.slice(start, end)).toString(16); + if(xx.length == 1) + xx = '0' + xx; + rrggbb = rrggbb + xx; + css = css.slice(end); + } + return rrggbb; + } + +_onPanelColorChanged() { + let rgba = this.BC_button.get_rgba(); + let css = rgba.to_string(); + let hexString = this._cssHexString(css); + this._settings.set_string('color', hexString); + } + +selectButtonColor() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5, halign: Gtk.Align.END }); + + this.BC_button.connect('notify::rgba', ()=> this._onPanelColorChanged() ); + + hbox[add](this.BC_button); + + return hbox; + } + +customColorButton() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let customColorButtonLabel = new Gtk.Label({ label: "Use Custom Color for Buttons", xalign: 0, hexpand: true }); + + this.cCBToggleSwitch = new Gtk.Switch({ active: this._settings.get_boolean('use-custom-color') }); + this.cCBToggleSwitch.connect('notify::active', (button) => { this._settings.set_boolean('use-custom-color', button.active); }); + + hbox[add](customColorButtonLabel); + hbox[add](this.cCBToggleSwitch) + + return hbox; + } + +removeSuspendButton() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let removeSuspendButtonLabel = new Gtk.Label({ label: "Remove Suspend Button", xalign: 0, hexpand: true }); + + this.rSBLToggleSwitch = new Gtk.Switch({ active: this._settings.get_boolean('remove-suspend-button') }); + this.rSBLToggleSwitch.connect('notify::active', (button) => { this._settings.set_boolean('remove-suspend-button', button.active); }); + + hbox[add](removeSuspendButtonLabel); + hbox[add](this.rSBLToggleSwitch) + + return hbox; + } + +removeLogoutButton() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let removeLogoutButtonLabel = new Gtk.Label({ label: "Remove Logout Button", xalign: 0, hexpand: true }); + + this.rLBLToggleSwitch = new Gtk.Switch({ active: this._settings.get_boolean('remove-logout-button') }); + this.rLBLToggleSwitch.connect('notify::active', (button) => { this._settings.set_boolean('remove-logout-button', button.active); }); + + hbox[add](removeLogoutButtonLabel); + hbox[add](this.rLBLToggleSwitch) + + return hbox; + } + +removeRestartButton() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let removeRestartButtonLabel = new Gtk.Label({ label: "Remove Restart Button", xalign: 0, hexpand: true }); + + this.rRBLToggleSwitch = new Gtk.Switch({ active: this._settings.get_boolean('remove-restart-button') }); + this.rRBLToggleSwitch.connect('notify::active', (button) => { this._settings.set_boolean('remove-restart-button', button.active); }); + + hbox[add](removeRestartButtonLabel); + hbox[add](this.rRBLToggleSwitch); + + return hbox; + } + +removePoweroffButton() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let removePoweroffButtonLabel = new Gtk.Label({ label: "Remove Poweroff Button", xalign: 0, hexpand: true }); + + this.rPBLToggleSwitch = new Gtk.Switch({ active: this._settings.get_boolean('remove-poweroff-button') }); + this.rPBLToggleSwitch.connect('notify::active', (button) => { this._settings.set_boolean('remove-poweroff-button', button.active); }); + + hbox[add](removePoweroffButtonLabel); + hbox[add](this.rPBLToggleSwitch) + + return hbox; + } + +adjustIconSize() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let IS_label = new Gtk.Label({ label: "Adjust Icon Size", xalign: 0, hexpand: true }); + + this.IS_button = new Gtk.SpinButton(); + this.IS_button.set_range(12, 20); + this.IS_button.set_value(this._settings.get_int('icon-size')); + this.IS_button.set_increments(2, 4); + this.IS_button.connect('value-changed', (entry) => { this._settings.set_int('icon-size', entry.get_value()); }); + + hbox[add](IS_label); + hbox[add](this.IS_button); + + return hbox; + } + +adjustPadding() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let PD_label = new Gtk.Label({ label: "Adjust Padding", xalign: 0, hexpand: true }); + + this.PD_button = new Gtk.SpinButton(); + this.PD_button.set_range(0, 16); + this.PD_button.set_value(this._settings.get_int('padding')); + this.PD_button.set_increments(2, 4); + this.PD_button.connect('value-changed', (entry) => { this._settings.set_int('padding', entry.get_value()); }); + + hbox[add](PD_label); + hbox[add](this.PD_button); + + return hbox; + } + +adjustBorderRadius() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5 }); + let BR_label = new Gtk.Label({ label: "Adjust Border Raidus", xalign: 0, hexpand: true }); + this.BR_button = new Gtk.SpinButton(); + this.BR_button.set_range(0, 32); + this.BR_button.set_value(this._settings.get_int('border-radius')); + this.BR_button.set_increments(2, 4); + this.BR_button.connect('value-changed', (entry) => { this._settings.set_int('border-radius', entry.get_value()); }); + + hbox[add](BR_label); + hbox[add](this.BR_button); + + return hbox; + } + +resetButton() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5, halign: Gtk.Align.CENTER }); + let resetButton = new Gtk.Button(); + resetButton.set_label("Reset to Extensions's Default Size'es By Cliking this Button"); + resetButton.connect('clicked', ()=> { + this._settings.set_int('icon-size', 16); + this._settings.set_int('padding', 8); + this._settings.set_int('border-radius', 16); + this.IS_button.set_value(this._settings.get_int('icon-size')); + this.PD_button.set_value(this._settings.get_int('padding')); + this.BR_button.set_value(this._settings.get_int('border-radius')); + + }); + + hbox[add](resetButton); + + return hbox; + } + +tip() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5, halign: Gtk.Align.START }); + let tipLabel = new Gtk.Label({ label: + "you can tweak the BACKGROUND COLOR of these system menu buttons by edititng this extensions stylesheet.css file.\n\ +Run below command to open the styles sheet file." }); + + hbox[add](tipLabel); + + return hbox; + } + +command() { + let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, margin_top: 5, margin_bottom: 20, halign: Gtk.Align.START }); + let command = new Gtk.Label({ label: "gedit $HOME/.local/share/gnome-shell/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/stylesheet.css", useMarkup: true, selectable: true }); + + hbox[add](command); + + return hbox; + } +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/gschemas.compiled b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..2c3039008b427e85e00cb4bd2ecbad4c2877fdc1 GIT binary patch literal 925 zcmZ`%J#W-N6kG^L62eC$5`>fr9fe)2eL@s8X%G^T5-KE=B7E5Ay}Omp-pj6?4^XIR zktk0{{D>5E6i75dg8u*&l+Yj=1T%X!M+#OR&v^X&*6;1ReJ`;(DN0eV%izt44o)^E zxV0?AZ>-6?4Ii@wf8|&DjbYT+#hQ2l{(3?PT*BCX)Gth~A~#UOVWjp-RXA-57gP7f0N&-JR?I-l9=i%P~-v!p+e0e~hdKvxzoC9wUo-VL{>K6Px@FB3RKi_0L z^(FX6;E%xl^_2tq)cl`M;1&vL`baIrhL{6)fav-8_l&3JzH8t+z}APOm-MM;;ctQ+ zaO>LY1^U$ff56XxnTO-o^r@E+KL)=7Qe!h^rA;zjvB`^o1-P#A7U*C<&^ipm$|>2c zTxoLIHAB-x1!<_erjSlQR@3i!R!hgfw<2SpV9gZ0F*4am9S6S2R{Y}sO^$ba0>tr9!4_be0hEC&|J>o2hAkiTii~bpa z@tiTvRx@*Gp`XQid#hZT*mAnNuWyuOnJ)SW^|_nQvDg3f*EhA@@e95S>zqT=H`O#H G>iGjkueaX- literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/org.gnome.shell.extensions.round-system-menu-buttons.gschema.xml b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/org.gnome.shell.extensions.round-system-menu-buttons.gschema.xml new file mode 100644 index 0000000..c6190b5 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/schemas/org.gnome.shell.extensions.round-system-menu-buttons.gschema.xml @@ -0,0 +1,69 @@ + + + + + +[ 1, 2, 3, 4, 5, 6, 7, 8 ] +Default Order +Default Order + + + +false +Turn ON if you wish to use Custom Color. +Custom Color + + + +'#000000' +color +color + + + + +16 +icon size +icon size + + + + +8 +padding +icon size + + + + +16 +border radius +icon size + + + +false +Remove Suspend Button +Remove Suspend Button + + + +false +Remove Logout Button +Remove Logout Button + + + +false +Remove Restart Button +Remove Restart Button + + + +false +Remove poweroff Button +Remove poweroff Button + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/stylesheet.css b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/stylesheet.css new file mode 100644 index 0000000..309593c --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/roundedSystemMenuButtons@pratap.fastmail.fm/stylesheet.css @@ -0,0 +1,13 @@ +/* Add your custom extension styling here */ + +.rounded-menu-buttons { + background-color: #353535 + } + +.rounded-menu-buttons:hover, .rounded-menu-buttons:focus { + background-color: rgba(255, 255, 255, 0.1); + } + +.rounded-menu-buttons:active { + background-color: #1b6acb; + } diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/base.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/base.js new file mode 100644 index 0000000..6db500f --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/base.js @@ -0,0 +1,759 @@ +/******************************************************************************* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see http://www.gnu.org/licenses/. + * ***************************************************************************** + * Original Author: Gopi Sankar Karmegam + ******************************************************************************/ +/* jshint moz:true */ + +const { GObject, GLib, Gvc } = imports.gi; + +const Signals = imports.signals; + +const PopupMenu = imports.ui.popupMenu; +const VolumeMenu = imports.ui.status.volume; +const Main = imports.ui.main; +const MessageTray = imports.ui.messageTray; + +const Config = imports.misc.config; +const ExtensionUtils = imports.misc.extensionUtils; +const Gettext = imports.gettext; + +const Me = ExtensionUtils.getCurrentExtension(); +const Lib = Me.imports.convenience; +const Prefs = Me.imports.prefs; + +ExtensionUtils.initTranslations(Me.metadata["gettext-domain"]); +const Domain = Gettext.domain(Me.metadata["gettext-domain"]); +const _ = Domain.gettext; +//const _ = Gettext.gettext; +const _d = Lib._log; +const getActor = Lib.getActor; + +const DISPLAY_OPTIONS = Prefs.DISPLAY_OPTIONS; +const SignalManager = Lib.SignalManager; +const isShellAbove34 = (parseFloat(Config.PACKAGE_VERSION) >= 3.34); + +var ProfileMenuItem40 = class + extends PopupMenu.PopupMenuItem { + _init(title, profileName) { + if (super._init) { + super._init(title); + } + _d("ProfileMenuItem: _init:" + title); + this._initialise(profileName); + } + + _initialise(profileName) { + this.profileName = profileName; + this._ornamentLabel.set_style("min-width: 3em;margin-left: 3em;"); + this.setProfileActive(false); + } + + setProfileActive(active) { + if (active) { + this.setOrnament(PopupMenu.Ornament.DOT); + // this._ornamentLabel.text = "\u2727"; + this._ornamentLabel.text = "\u266A"; + if (this.add_style_pseudo_class) { + this.remove_style_pseudo_class('insensitive'); + } + else { + getActor(this).remove_style_pseudo_class('insensitive'); + } + } + else { + this.setOrnament(PopupMenu.Ornament.NONE); + if (this.add_style_pseudo_class) { + this.add_style_pseudo_class('insensitive'); + } + else { + getActor(this).add_style_pseudo_class('insensitive'); + } + } + } + + setVisibility(visibility) { + getActor(this).visible = visibility; + } +} + +var ProfileMenuItem32 = class + extends ProfileMenuItem40 { + constructor(title, profileName){ + _d("ProfileMenuItem: constructor:" + title); + super(title); + this._initialise(profileName); + } +} + +var SoundDeviceMenuItem40 = class extends PopupMenu.PopupImageMenuItem { + _init(id, title, icon_name, profiles) { + if (super._init) { + super._init(title, icon_name); + } + _d("SoundDeviceMenuItem: _init:" + title); + this._initialise(id, title, icon_name, profiles); + } + + _initialise(id, title, icon_name, profiles) { + this.id = id; + this.title = title; + this.icon_name = icon_name; + this.profiles = (profiles) ? profiles : []; + + this.profilesitems = new Map(); + for (let profile of this.profiles) { + let profileName = profile.name; + if (!this.profilesitems.has(profileName)) { + let pItem = new ProfileMenuItem(_("Profile: ") + profile.human_name, profileName); + this.profilesitems.set(profileName, pItem); + pItem.connect('activate', () => { + _d("Activating Profile:" + id + profileName); + this.emit("profile-activated", this.id, profileName); + }); + } + } + + this.connect('activate', () => { + _d("Device Change request for " + id); + _d("Emitting Signal..."); + this.emit("device-activated", this.id); + }); + this.available = true; + this.activeProfile = ""; + this.activeDevice = false; + this._displayOption = DISPLAY_OPTIONS.INITIAL; + getActor(this).visible = false; + } + + isAvailable() { + return this.available; + } + + setAvailable(_ac) { + this.available = _ac; + } + + setActiveProfile(_p) { + if (_p && this.activeProfile != _p) { + if (this.profilesitems.has(this.activeProfile)) { + this.profilesitems.get(this.activeProfile).setProfileActive(false); + } + this.activeProfile = _p; + if (this.profilesitems.has(_p)) { + this.profilesitems.get(_p).setProfileActive(true); + } + } + } + + setVisibility(_v) { + getActor(this).visible = _v; + if (!_v) { + this.profilesitems.forEach((p) => p.setVisibility(false)); + } + }; + + setTitle(_t) { + _d("SoundDeviceMenuItem: " + "setTitle: " + this.title + "->" + _t); + this.title = _t; + this.label.text = _t; + } + + isVisible() { + return getActor(this).visible; + } + + setActiveDevice(_a) { + this.activeDevice = _a; + if (!_a) { + this.setOrnament(PopupMenu.Ornament.NONE); + } + else { + this.setOrnament(PopupMenu.Ornament.CHECK); + this._ornamentLabel.text = '\u266B'; + } + } + + setProfileVisibility(_v) { + this.profilesitems.forEach(p => + p.setVisibility(_v && this.canShowProfile())); + } + + canShowProfile() { + return (this.isVisible() && this.profilesitems.size >= 1); + } + + setDisplayOption(displayOption) { + _d("Setting Display Option to : " + displayOption); + this._displayOption = displayOption; + } + + getDisplayOption() { + return this._displayOption; + } +} + +var SoundDeviceMenuItem32 = class extends SoundDeviceMenuItem40 { + constructor(id, title, icon_name, profiles) { + _d("SoundDeviceMenuItem: constructor:" + title); + super(title, icon_name); + this._initialise(id, title, icon_name, profiles); + } +} + +var SoundDeviceMenuItem; +var ProfileMenuItem; +if (isShellAbove34) { + SoundDeviceMenuItem = SoundDeviceMenuItem40; + ProfileMenuItem = ProfileMenuItem40; + ProfileMenuItem = GObject.registerClass({ GTypeName: 'ProfileMenuItem' }, ProfileMenuItem); + + SoundDeviceMenuItem = GObject.registerClass({ + GTypeName: "SoundDeviceMenuItem", + Signals: { + "device-activated": { + param_types: [GObject.TYPE_INT] + }, + "profile-activated": { + param_types: [GObject.TYPE_INT, GObject.TYPE_STRING] + } + } + }, SoundDeviceMenuItem); +} +else +{ + SoundDeviceMenuItem = SoundDeviceMenuItem32; + ProfileMenuItem = ProfileMenuItem32; +} + +var SoundDeviceChooserBase = class SoundDeviceChooserBase { + constructor(deviceType) { + _d("SDC: init"); + this.menuItem = new PopupMenu.PopupSubMenuMenuItem(_("Extension initialising..."), true); + this.deviceType = deviceType; + this._devices = new Map(); + let _control = this._getMixerControl(); + this._settings = ExtensionUtils.getSettings(); + _d("Constructor:" + deviceType); + + this._setLog(); + this._signalManager = new SignalManager(); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.ENABLE_LOG, this._setLog.bind(this)); + + if (_control.get_state() == Gvc.MixerControlState.READY) { + this._onControlStateChanged(_control); + } + else { + this._controlStateChangeSignal = this._signalManager.addSignal(_control, "state-changed", this._onControlStateChanged.bind(this)); + } + + this._signalManager.addSignal(this.menuItem.menu, "open-state-changed", this._onSubmenuOpenStateChanged.bind(this)); + this._signalManager.addSignal(this.menuItem, "notify::visible", () => {this.emit('update-visibility', getActor(this.menuItem).visible);}); + } + + _getMixerControl() { return VolumeMenu.getMixerControl(); } + + _setLog() { Lib.setLog(this._settings.get_boolean(Prefs.ENABLE_LOG)); } + + _onControlStateChanged(control) { + if (control.get_state() == Gvc.MixerControlState.READY) { + + this._signalManager.addSignal(control, this.deviceType + "-added", this._deviceAdded.bind(this)); + this._signalManager.addSignal(control, this.deviceType + "-removed", this._deviceRemoved.bind(this)); + this._signalManager.addSignal(control, "active-" + this.deviceType + "-update", this._deviceActivated.bind(this)); + + this._signalManager.addSignal(this._settings, "changed::" + Prefs.HIDE_ON_SINGLE_DEVICE, this._setChooserVisibility.bind(this)); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.SHOW_PROFILES, this._setProfileVisibility.bind(this)); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.ICON_THEME, this._setIcons.bind(this)); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.HIDE_MENU_ICONS, this._setIcons.bind(this)); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.PORT_SETTINGS, this._resetDevices.bind(this)); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.OMIT_DEVICE_ORIGIN, this._refreshDeviceTitles.bind(this)); + + this._show_device_signal = Prefs["SHOW_" + this.deviceType.toUpperCase() + "_DEVICES"]; + + this._signalManager.addSignal(this._settings, "changed::" + this._show_device_signal, this._setVisibility.bind(this)); + + this._portsSettings = Prefs.getPortsFromSettings(this._settings); + + /** + * There is no direct way to get all the UI devices from + * mixercontrol. When enabled after shell loads, the signals + * will not be emitted, a simple hack to look for ids, until any + * uidevice is not found. The UI devices are always serialed + * from from 1 to n + */ + + let id = 0; + + let dummyDevice = new Gvc.MixerUIDevice(); + let maxId = dummyDevice.get_id(); + + _d("Max Id:" + maxId); + + while (++id < maxId) { + this._deviceAdded(control, id); + } + let defaultStream = this.getDefaultStream(control); + if (defaultStream) { + let defaultDevice = control.lookup_device_from_stream(defaultStream); + if (defaultDevice) { + this._deviceActivated(control, defaultDevice.get_id()); + } + } + + if (this._controlStateChangeSignal) { + this._controlStateChangeSignal.disconnect(); + delete this._controlStateChangeSignal; + } + this._setVisibility(); + } + } + + _onSubmenuOpenStateChanged(_menu, opened) { + _d(this.deviceType + "-Submenu is now open?: " + opened); + if (opened) { // Actions when submenu is opening + this._setActiveProfile(); + } + else { // Actions when submenu is closing + } + } + + _deviceAdded(control, id, dontcheck) { + let obj = this._devices.get(id); + let uidevice = this.lookupDeviceById(control, id); + + _d("Added - " + id); + + if (!obj) { + if (this._isDeviceInValid(uidevice)) { + return null; + } + + let title = this._getDeviceTitle(uidevice); + + let icon = uidevice.get_icon_name(); + if (icon == null || icon.trim() == "") + icon = this.getDefaultIcon(); + icon = this._getIcon(icon); + + obj = new SoundDeviceMenuItem(id, title, icon, Lib.getProfiles(control, uidevice)); + obj.connect("device-activated", (item, id) => this._changeDeviceBase(id)); + obj.connect("profile-activated", (item, id, name) => this._profileChangeCallback(id, name)); + + this.menuItem.menu.addMenuItem(obj); + obj.profilesitems.forEach(i => this.menuItem.menu.addMenuItem(i)); + + this._devices.set(id, obj); + } + else if (!obj.isAvailable()) + obj.setAvailable(true); + else + return; + + + _d("Device Name:" + obj.title); + + _d("Added: " + id + ":" + uidevice.description + ":" + uidevice.port_name + ":" + uidevice.origin); + + let stream = control.get_stream_from_device(uidevice); + if (stream) { + obj.setActiveProfile(uidevice.get_active_profile()); + } + + if (!dontcheck && !this._canShowDevice(control, uidevice, obj, uidevice.port_available)) { + _d("This device is hidden in settings, lets hide...") + this._deviceRemoved(control, id, true); + } + else { + this._setChooserVisibility(); + this._setVisibility(); + } + } + + _profileChangeCallback(id, profileName) { + let control = this._getMixerControl(); + let uidevice = this.lookupDeviceById(control, id); + if (!uidevice) { + this._deviceRemoved(control, id); + } + else { + _d("i am setting profile, " + profileName + ":" + uidevice.description + ":" + uidevice.port_name); + if (id != this._activeDeviceId) { + _d("Changing active device to " + uidevice.description + ":" + uidevice.port_name); + this._changeDeviceBase(id, control); + } + control.change_profile_on_selected_device(uidevice, profileName); + //this._setDeviceActiveProfile(control, this._devices.get(id)); //"Races" change_profile_...(...) and reports the old state + } + } + + _deviceRemoved(control, id, dontcheck) { + let obj = this._devices.get(id); + + if (obj && obj.isAvailable()) { + _d("Removed: " + id + ":" + obj.title); + /* + let uidevice = this.lookupDeviceById(control,id); + if (!dontcheck && this._canShowDevice(control, uidevice, obj, false)) { + _d('Device removed, but not hiding as its set to be shown always'); + return; + }*/ + obj.setVisibility(false); + obj.setAvailable(false); + + /* + if (this.deviceRemovedTimout) { + GLib.source_remove(this.deviceRemovedTimout); + this.deviceRemovedTimout = null; + } + */ + /** + * If the active uidevice is removed, then need to activate the + * first available uidevice. However for some cases like Headphones, + * when the uidevice is removed, Speakers are automatically + * activated. So, lets wait for sometime before activating. + */ + /* THIS MAY NOT BE NEEDED AS SHELL SEEMS TO ACTIVATE NEXT DEVICE + this.deviceRemovedTimout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1500, function() { + _d("Device Removed timeout"); + if (obj === this._activeDevice) { + let device = Object.keys(this._devices).map((id) => this._devices[id]).find(({active}) => active === true); + if(device){ + this._changeDeviceBase(device.id, this._getMixerControl()); + } + } + this.deviceRemovedTimout = null; + return false; + }.bind(this)); + */ + this._setChooserVisibility(); + this._setVisibility(); + } + } + + _deviceActivated(control, id) { + _d("Activated:- " + id); + let obj = this._devices.get(id); + if (!obj) { + _d("Activated device not found in the list of devices, try to add"); + this._deviceAdded(control, id); + obj = this._devices.get(id); + } + if (obj && id != this._activeDeviceId) { + _d("Activated: " + id + ":" + obj.title); + if (this._settings.get_boolean(Prefs.CANNOT_ACTIVATE_HIDDEN_DEVICE) + && obj.getDisplayOption() === DISPLAY_OPTIONS.HIDE_ALWAYS) { + _d("Preference does not allow this hidden device to be activated, fallback to the previous aka original device"); + let device = null; + + if (this._activeDeviceId) { + device = this._devices.get(this._activeDeviceId); + } + else { + device = Array.from(this._devices.values()).find(x => x.isAvailable()); + } + + if (device) { + _notify(Me.metadata["name"] + " " + _("Extension changed active sound device."), + _("Activated device is hidden in Port Settings.") + " \n" + + _("Deactivated Device: ") + obj.title + " \n" + _("Activated Device: ") + device.title + " \n" + + _("Disable in extension preferences to avoid this behaviour."), + device.icon_name); + this._changeDeviceBase(device.id, control); + } + else { + this._activateDeviceMenuItem(control, id, obj); + } + + } + else { + this._activateDeviceMenuItem(control, id, obj); + } + } + } + + _activateDeviceMenuItem(control, id, obj) { + let prevActiveDevce = this._activeDeviceId; + this._activeDeviceId = id; + if (prevActiveDevce) { + let prevObj = this._devices.get(prevActiveDevce); + if (prevObj) { + prevObj.setActiveDevice(false); + if (prevObj.getDisplayOption() === DISPLAY_OPTIONS.HIDE_ALWAYS) { + _d("Hiding previously activated device as it is set to hidden always"); + this._deviceRemoved(control, prevActiveDevce, true); + } + } + } + obj.setActiveDevice(true); + if (!obj.isAvailable()) { + _d("Activated device hidden, try to add"); + this._deviceAdded(control, id); + } + + this.menuItem.label.text = obj.title; + + if (!this._settings.get_boolean(Prefs.HIDE_MENU_ICONS)) { + this.menuItem.icon.icon_name = obj.icon_name; + } else { + this.menuItem.icon.gicon = null; + } + } + + _changeDeviceBase(id, control) { + if (!control) { + control = this._getMixerControl(); + } + let uidevice = this.lookupDeviceById(control, id); + if (uidevice) { + this.changeDevice(control, uidevice); + } + else { + this._deviceRemoved(control, id); + } + } + + _setActiveProfile() { + let control = this._getMixerControl(); + this._devices.forEach(device => { + if (device.isAvailable()) { + this._setDeviceActiveProfile(control, device); + } + }); + } + + _setDeviceActiveProfile(control, device) { + if (!device || !device.isAvailable()) { + return; + } + + let uidevice = this.lookupDeviceById(control, device.id); + if (!uidevice) { + this._deviceRemoved(control, device.id); + } + else { + let activeProfile = uidevice.get_active_profile(); + _d("Active Profile:" + activeProfile); + device.setActiveProfile(activeProfile); + } + } + + _getAvailableDevices() { + return Array.from(this._devices.values()).filter(x => x.isAvailable()); + } + + _getDeviceVisibility() { + let hideChooser = this._settings.get_boolean(Prefs.HIDE_ON_SINGLE_DEVICE); + let numAvailableDevices = this._getAvailableDevices().length; + if (hideChooser) { + return numAvailableDevices > 1; + } + else { + return numAvailableDevices > 0; + } + } + + _setChooserVisibility() { + let visibility = this._getDeviceVisibility(); + this._getAvailableDevices().forEach(x => x.setVisibility(visibility)) + + //getActor(this.menuItem._triangleBin).visible = visibility; + //getActor(this.menuItem).visible = visibility; + this._setProfileVisibility(); + this.setVisible(visibility); + } + + _setVisibility() { + if (!this._settings.get_boolean(this._show_device_signal)) + this.setVisible(false); + else + // if setting says to show device, check for any device, otherwise + // hide the "actor" + this.setVisible(this._getDeviceVisibility()); + } + + setVisible(visibility) { + getActor(this.menuItem).visible = visibility; + //this.emit('update-visibility', visibility); + } + + _setProfileVisibility() { + let visibility = this._settings.get_boolean(Prefs.SHOW_PROFILES); + this._getAvailableDevices().forEach(device => device.setProfileVisibility(visibility)); + } + + _getIcon(name) { + let iconsType = this._settings.get_string(Prefs.ICON_THEME); + switch (iconsType) { + case Prefs.ICON_THEME_COLORED: + return name; + case Prefs.ICON_THEME_MONOCHROME: + return name + "-symbolic"; + default: + //return "none"; + return null; + } + } + + _setIcons() { + // Set the icons in the selection list + let control = this._getMixerControl(); + this._devices.forEach((device, id) => { + let uidevice = this.lookupDeviceById(control, id); + if (uidevice) { + let icon = uidevice.get_icon_name(); + if (icon == null || icon.trim() == "") + icon = this.getDefaultIcon(); + _d(icon + " _setIcons") + device.setIcon(this._getIcon(icon)); + } + }); + + // These indicate the active device, which is displayed directly in the + // Gnome menu, not in the list. + if (!this._settings.get_boolean(Prefs.HIDE_MENU_ICONS)) { + this.menuItem.icon.icon_name = this._getIcon(this._devices.get(this._activeDeviceId).icon_name); + } else { + this.menuItem.icon.icon_name = null; + } + } + + _getDeviceDisplayOption(control, uidevice, obj) { + let displayOption = DISPLAY_OPTIONS.DEFAULT; + if (uidevice && uidevice.port_name != null && uidevice.description != null) { + let stream = control.get_stream_from_device(uidevice); + let cardName = null; + if (stream) { + let cardId = stream.get_card_index(); + if (cardId != null) { + _d("Card Index:" + cardId); + let _card = Lib.getCard(cardId); + if (_card) { + cardName = _card.name; + } + else { + //card id found, but not available in list + return DISPLAY_OPTIONS.DEFAULT; + } + _d("Card Name:" + cardName); + } + } + + _d("P:" + uidevice.port_name + "==" + uidevice.description + "==" + cardName + "==" + uidevice.origin); + + let matchedPort = this._portsSettings.find(port => (port + && port.name == uidevice.port_name + && port.human_name == uidevice.description + && (!cardName || port.card_name == cardName) + && (cardName || port.card_description == uidevice.origin))); + + if (matchedPort) { + displayOption = matchedPort.display_option; + } + } + + obj && obj.setDisplayOption(displayOption); + + return displayOption; + } + + _canShowDevice(control, uidevice, obj, defaultValue) { + if (!uidevice || !this._portsSettings || uidevice.port_name == null + || uidevice.description == null || (this._activeDeviceId && this._activeDeviceId == uidevice.get_id())) { + return defaultValue; + } + + let displayOption = obj.getDisplayOption(); + if (displayOption === DISPLAY_OPTIONS.INITIAL) { + displayOption = this._getDeviceDisplayOption(control, uidevice, obj); + } + + if (displayOption === DISPLAY_OPTIONS.SHOW_ALWAYS) { + _d("Display Device due Preference:" + displayOption); + return true; + } + else if (displayOption === DISPLAY_OPTIONS.HIDE_ALWAYS) { + _d("Hide Device due Preference:" + displayOption); + return false; + } + else { + _d("Default Device due Preference:" + displayOption); + return defaultValue; + } + } + + _resetDevices() { + this._portsSettings = Prefs.getPortsFromSettings(this._settings); + let control = this._getMixerControl(); + this._devices.forEach((device, id) => { + device.setDisplayOption(DISPLAY_OPTIONS.INITIAL); + let uidevice = this.lookupDeviceById(control, id); + if (this._isDeviceInValid(uidevice)) + _d("Device is invalid"); + else if (this._canShowDevice(control, uidevice, device, uidevice.port_available)) + this._deviceAdded(control, id, true); + else + this._deviceRemoved(control, id, true); + }); + } + + _isDeviceInValid(uidevice) { + return (!uidevice || (uidevice.description != null && uidevice.description.match(/Dummy\s+(Output|Input)/gi))); + } + + _refreshDeviceTitles() { + let control = this._getMixerControl(); + this._devices.forEach((device, id) => { + let uidevice = this.lookupDeviceById(control, id); + let title = this._getDeviceTitle(uidevice); + + device.setTitle(title); + }); + + let activeDevice = this._devices.get(this._activeDeviceId); + this.menuItem.label.text = activeDevice.title; + } + + _getDeviceTitle(uidevice) { + let title = uidevice.description; + if (!this._settings.get_boolean(Prefs.OMIT_DEVICE_ORIGIN) && uidevice.origin != "") + title += " - " + uidevice.origin; + + return title; + } + + destroy() { + this._signalManager.disconnectAll(); + if (this.deviceRemovedTimout) { + GLib.source_remove(this.deviceRemovedTimout); + this.deviceRemovedTimout = null; + } + if (this.activeProfileTimeout) { + GLib.source_remove(this.activeProfileTimeout); + this.activeProfileTimeout = null; + } + this.menuItem.destroy(); + } + +}; + +Signals.addSignalMethods(SoundDeviceChooserBase.prototype); + +function _notify(msg, details, icon_name) { + let source = new MessageTray.Source(Me.metadata["name"], icon_name); + Main.messageTray.add(source); + let notification = new MessageTray.Notification(source, msg, details); + //notification.setTransient(true); + source.showNotification(notification); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/convenience.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/convenience.js new file mode 100644 index 0000000..4cc6027 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/convenience.js @@ -0,0 +1,357 @@ +/******************************************************************************* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * ***************************************************************************** + * Original Author: Gopi Sankar Karmegam + ******************************************************************************/ +/* jshint moz:true */ + +const ByteArray = imports.byteArray; +const { Gio, GLib } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; + +const Me = ExtensionUtils.getCurrentExtension(); +const Prefs = Me.imports.prefs; + +var DEBUG = false; + +var logWrap; +if (log != undefined) { + logWrap = log; +} +else { + logWrap = global.log +} + + +let cards; + +function getCard(card_index) { + if (!cards || Object.keys(cards).length == 0) { + refreshCards(); + } + return cards[card_index]; +} + +function getCardByName(card_name) { + if (!cards || Object.keys(cards).length == 0) { + refreshCards(); + } + return Object.keys(cards).map((index) => cards[index]).find(({ name }) => name === card_name); +} + +function getProfiles(control, uidevice) { + let stream = control.lookup_stream_id(uidevice.get_stream_id()); + if (stream) { + if (!cards || Object.keys(cards).length == 0 || !cards[stream.card_index]) { + refreshCards(); + } + if (cards && cards[stream.card_index]) { + _log("Getting profile form stream id " + uidevice.port_name); + let profiles; + if ((profiles = getProfilesForPort(uidevice.port_name, cards[stream.card_index]))) { + return profiles; + } + } + } + else { + /* Device is not active device, lets try match with port name */ + refreshCards(); + for (let card of Object.values(cards)) { + let profiles; + _log("Getting profile from cards " + uidevice.port_name + " for card id " + card.id); + if ((profiles = getProfilesForPort(uidevice.port_name, card))) { + return profiles; + } + } + } + return []; +} + +let ports; +function getPorts(refresh) { + if (!ports || ports.length == 0 || refresh) { + refreshCards(); + } + return ports; +} + +function isCmdFound(cmd) { + try { + let [result, out, err, exit_code] = GLib.spawn_command_line_sync(cmd); + return true; + } + catch (e) { + _log("ERROR: " + cmd + " execution failed. " + e); + return false; + } +} + +function refreshCards() { + cards = {}; + ports = []; + let _settings = ExtensionUtils.getSettings(); + let error = false; + let newProfLogic = _settings.get_boolean(Prefs.NEW_PROFILE_ID_DEPRECATED); + + /** This block should be removed in the next release along the setting schema correct */ + if (!newProfLogic) { + _settings.set_boolean(Prefs.NEW_PROFILE_ID, false); + _settings.reset(Prefs.NEW_PROFILE_ID_DEPRECATED); + } + else { + newProfLogic = _settings.get_boolean(Prefs.NEW_PROFILE_ID); + } + + if (newProfLogic) { + _log("New logic"); + let pyLocation = Me.dir.get_child("utils/pa_helper.py").get_path(); + let pythonExec = ["python", "python3", "python2"].find(cmd => isCmdFound(cmd)); + if (!pythonExec) { + _log("ERROR: Python not found. fallback to default mode"); + _settings.set_boolean(Prefs.NEW_PROFILE_ID, false); + Gio.Settings.sync(); + newProfLogic = false; + } + else { + try { + _log("Python found." + pythonExec); + let [result, out, err, exit_code] = GLib.spawn_command_line_sync(pythonExec + " " + pyLocation); + // _log("result" + result +" out"+out + " exit_code" + + // exit_code + "err" +err); + if (result && !exit_code) { + if (out instanceof Uint8Array) { + out = ByteArray.toString(out); + } + let obj = JSON.parse(out); + cards = obj["cards"]; + ports = obj["ports"]; + } + } + catch (e) { + error = true; + _log("ERROR: Python execution failed. fallback to default mode" + e); + _settings.set_boolean(Prefs.NEW_PROFILE_ID, false); + Gio.Settings.sync(); + } + } + } + //error = true; + if (!newProfLogic || error) { + _log("Old logic"); + try { + let env = GLib.get_environ(); + env = GLib.environ_setenv(env, "LANG", "C", true); + let [result, out, err, exit_code] = GLib.spawn_sync(null, ["pactl", "list", "cards"], env, GLib.SpawnFlags.SEARCH_PATH, null); + //_log(result+"--"+out+"--"+ err+"--"+ exit_code) + if (result && !exit_code) { + parseOutput(out); + } + } + catch (e) { + _log("ERROR: pactl execution failed. No ports/profiles will be displayed." + e); + } + } + //_log(Array.isArray(cards)); + //_log(JSON.stringify(cards)); + //_log(Array.isArray(ports)); + //_log(JSON.stringify(ports)); +} + +function parseOutput(out) { + let lines; + if (out instanceof Uint8Array) { + lines = ByteArray.toString(out).split("\n"); + } else { + lines = out.toString().split("\n"); + } + + let cardIndex; + let parseSection = "CARDS"; + let port; + let matches; + // _log("Unmatched line:" + out); + while (lines.length > 0) { + let line = lines.shift(); + + if ((matches = /^Card\s#(\d+)$/.exec(line))) { + cardIndex = matches[1]; + if (!cards[cardIndex]) { + cards[cardIndex] = { "index": cardIndex, "profiles": [], "ports": [] }; + } + } + else if ((matches = /^\t*Name:\s+(.*?)$/.exec(line)) && cards[cardIndex]) { + cards[cardIndex].name = matches[1]; + parseSection = "CARDS" + } + else if (line.match(/^\tProperties:$/) && parseSection == "CARDS") { + parseSection = "PROPS"; + } + else if (line.match(/^\t*Profiles:$/)) { + parseSection = "PROFILES"; + } + else if (line.match(/^\t*Ports:$/)) { + parseSection = "PORTS"; + } + else if (cards[cardIndex]) { + switch (parseSection) { + case "PROPS": + if ((matches = /alsa\.card_name\s+=\s+"(.*?)"/.exec(line))) { + cards[cardIndex].alsa_name = matches[1]; + } + else if ((matches = /device\.description\s+=\s+"(.*?)"/.exec(line))) { + cards[cardIndex].card_description = matches[1]; + } + break; + case "PROFILES": + if ((matches = /.*?((?:output|input)[^+]*?):\s(.*?)\s\(sinks:.*?(?:available:\s*(.*?))*\)/.exec(line))) { + let availability = matches[3] ? matches[3] : "yes" //If no availability in out, assume profile is available + + cards[cardIndex].profiles.push({ + "name": matches[1], + "human_name": matches[2], + "available": (availability === "yes") ? 1 : 0 + }); + } + break; + case "PORTS": + if ((matches = /\t*(.*?):\s(.*)\s\(.*?priority:/.exec(line))) { + port = { + "name": matches[1], + "human_name": matches[2], + "card_name": cards[cardIndex].name, + "card_description": cards[cardIndex].card_description + }; + cards[cardIndex].ports.push(port); + ports.push(port); + } + else if (port && (matches = /\t*Part of profile\(s\):\s(.*)/.exec(line))) { + let profileStr = matches[1]; + port.profiles = profileStr.split(", "); + port = null; + } + break; + } + } + } + if (ports) { + ports.forEach(p => { + p.direction = p.profiles + .filter(pr => pr.indexOf("+input:") == -1) + .some(pr => (pr.indexOf("output:") >= 0)) ? "Output" : "Input"; + }); + } +} + +var Signal = class Signal { + + constructor(signalSource, signalName, callback) { + this._signalSource = signalSource; + this._signalName = signalName; + this._signalCallback = callback; + } + + connect() { + this._signalId = this._signalSource.connect(this._signalName, this._signalCallback); + } + + disconnect() { + if (this._signalId) { + this._signalSource.disconnect(this._signalId); + this._signalId = null; + } + } +} + +var SignalManager = class SignalManager { + constructor() { + this._signalsBySource = new Map(); + } + + addSignal(signalSource, signalName, callback) { + let obj = null; + if (signalSource && signalName && callback) { + obj = new Signal(signalSource, signalName, callback); + obj.connect(); + + if (!this._signalsBySource.has(signalSource)) { + this._signalsBySource.set(signalSource, []); + } + this._signalsBySource.get(signalSource).push(obj) + //_log(this._signalsBySource.get(signalSource).length + "Signal length"); + } + return obj; + } + + disconnectAll() { + this._signalsBySource.forEach(signals => this._disconnectSignals(signals)); + } + + disconnectBySource(signalSource) { + if (this._signalsBySource.has(signalSource)) { + this._disconnectSignals(this._signalsBySource.get(signalSource)); + } + } + + _disconnectSignals(signals) { + while (signals.length) { + var signal = signals.shift(); + signal.disconnect(); + signal = null; + } + } +} + + +function getProfilesForPort(portName, card) { + if (card.ports) { + let port = card.ports.find(port => (portName === port.name)); + if (port) { + if (port.profiles) { + return card.profiles.filter(profile => ( + profile.name.indexOf("+input:") == -1 + && profile.available === 1 + && port.profiles.includes(profile.name) + )); + } + } + } + return null; +} + +function setLog(value) { + DEBUG = value; +} + +function _log(msg) { + if (DEBUG == true) { + // global.log("SDC Debug: " + msg); + logWrap("SDC Debug: " + msg); + } +} + +function dump(obj) { + var propValue; + for (var propName in obj) { + try { + propValue = obj[propName]; + _log(propName + "=" + propValue); + } + catch (e) { _log(propName + "!!!Error!!!"); } + } +} + +function getActor(item) { + //.actor is needed for backward compatablity + return (item.actor) ? item.actor : item; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/extension.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/extension.js new file mode 100644 index 0000000..d358025 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/extension.js @@ -0,0 +1,290 @@ +/******************************************************************************* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * ***************************************************************************** + * Original Author: Gopi Sankar Karmegam + ******************************************************************************/ +/* jshint moz:true */ + +const { GObject } = imports.gi; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Base = Me.imports.base; +const Lib = Me.imports.convenience; +const _d = Lib._log; +const _dump = Lib.dump; +const getActor = Lib.getActor; +const SignalManager = Lib.SignalManager; +const Prefs = Me.imports.prefs; +const Main = imports.ui.main; +const PopupMenu = imports.ui.popupMenu; + +var SoundOutputDeviceChooser = class SoundOutputDeviceChooser + extends Base.SoundDeviceChooserBase { + constructor() { + super("output"); + } + lookupDeviceById(control, id) { + return control.lookup_output_id(id); + } + changeDevice(control, uidevice) { + control.change_output(uidevice); + } + getDefaultStream(control) { + return control.get_default_sink(); + } + getDefaultIcon() { + return "audio-card"; + } +}; + +var SoundInputDeviceChooser = class SoundInputDeviceChooser + extends Base.SoundDeviceChooserBase { + constructor() { + super("input"); + } + lookupDeviceById(control, id) { + return control.lookup_input_id(id); + } + changeDevice(control, uidevice) { + control.change_input(uidevice); + } + getDefaultStream(control) { + return control.get_default_source(); + } + getDefaultIcon() { + return "audio-input-microphone"; + } +}; + +var VolumeMenuInstance = class VolumeMenuInstance { + constructor(volumeMenu, settings) { + this._settings = settings; + + this._volumeMenu = volumeMenu; + this._input = this._volumeMenu._input; + + this._overrideFunctions(); + this._setSliderVisiblity(); + + this._signalManager = new SignalManager(); + this._signalManager.addSignal(this._settings, "changed::" + + Prefs.SHOW_INPUT_SLIDER, this._setSliderVisiblity.bind(this)); + } + _overrideFunctions() { + // Fix the indicator when using SHOW_INPUT_SLIDER. + // If not applied when SHOW_INPUT_SLIDER=True indication of mic being used will be on (even when not used) + this._volumeMenu._getInputVisibleOriginal = this._volumeMenu.getInputVisible; + this._volumeMenu._getInputVisibleCustom = function() { + return this._input._stream != null && this._input._showInput; + }; + this._volumeMenu.getInputVisible = this._volumeMenu._getInputVisibleCustom; + + this._input._updateVisibilityOriginal = this._input._updateVisibility; + this._input._updateVisibilityCustom = function() { + let old_state_visible = getActor(this.item).visible; + let visible = this._shouldBeVisible(); + + if (old_state_visible != visible) { + getActor(this.item).visible = visible; + } else { + getActor(this.item).notify('visible'); + } + }; + this._input._updateVisibility = this._input._updateVisibilityCustom; + + // Makes slider visible when SHOW_INPUT_SLIDER=True + this._input._showInputSlider = this._settings.get_boolean(Prefs.SHOW_INPUT_SLIDER); + this._input._shouldBeVisibleOriginal = this._input._shouldBeVisible; + this._input._shouldBeVisibleCustom = function() { + return this._showInputSlider && (this._stream != null) || this._shouldBeVisibleOriginal(); + }; + this._input._shouldBeVisible = this._input._shouldBeVisibleCustom; + } + _setSliderVisiblity() { + this._input._showInputSlider = this._settings.get_boolean(Prefs.SHOW_INPUT_SLIDER); + this._input._maybeShowInput(); + } + destroy() { + this._signalManager.disconnectAll(); + delete this._signalManager; + this._volumeMenu.getInputVisible = this._volumeMenu._getInputVisibleOriginal; + this._input._updateVisibility = this._input._updateVisibilityOriginal; + this._input._shouldBeVisible = this._input._shouldBeVisibleOriginal; + + this._input._maybeShowInput(); + + delete this._volumeMenu['_getInputVisibleOriginal']; + delete this._volumeMenu['_getInputVisibleCustom']; + delete this._input['_updateVisibilityOriginal']; + delete this._input['_updateVisibilityCustom']; + delete this._input['_shouldBeVisibleOriginal']; + delete this._input['_shouldBeVisibleCustom']; + delete this._input['_showInputSlider']; // variable + } +} + +var SDCInstance = class SDCInstance { + constructor() { + } + + enable() { + this._settings = ExtensionUtils.getSettings(); + this._signalManager = new SignalManager(); + this._aggregateMenu = Main.panel.statusArea.aggregateMenu; + this._volume = this._aggregateMenu._volume; + this._volumeMenu = this._volume._volumeMenu; + this._aggregateLayout = this._aggregateMenu.menu.box.get_layout_manager(); + let theme = imports.gi.Gtk.IconTheme.get_default(); + if (theme != null) { + let iconPath = Me.dir.get_child('icons'); + if (iconPath != null && iconPath.query_exists(null)) { + theme.append_search_path(iconPath.get_path()); + } + } + + if (this._outputInstance == null) { + this._outputInstance = new SoundOutputDeviceChooser(); + } + if (this._inputInstance == null) { + this._inputInstance = new SoundInputDeviceChooser(); + } + + if (this._volumeMenuInstance == null) { + this._volumeMenuInstance = new VolumeMenuInstance(this._volumeMenu, this._settings); + } + + this._addMenuItem(this._volumeMenu, this._volumeMenu._output.item, this._outputInstance.menuItem); + this._addMenuItem(this._volumeMenu, this._volumeMenu._input.item, this._inputInstance.menuItem); + this._expandVolMenu(); + + this._signalManager.addSignal(this._settings, "changed::" + Prefs.EXPAND_VOL_MENU, this._expandVolMenu.bind(this)); + this._signalManager.addSignal(this._settings, "changed::" + Prefs.INTEGRATE_WITH_SLIDER, this._switchSubmenuMenu.bind(this)); + this._signalManager.addSignal(this._outputInstance, "update-visibility", this._updateMenuVisibility.bind(this)); + this._signalManager.addSignal(this._inputInstance, "update-visibility", this._updateMenuVisibility.bind(this)); + + //If slider disappears remove menu integration, getting complicated!! + this._signalManager.addSignal(getActor(this._volumeMenu._output.item), + "notify::visible", () => { this._updateMenuVisibility(this._outputInstance, false) }); + this._signalManager.addSignal(getActor(this._volumeMenu._input.item), + "notify::visible", () => { this._updateMenuVisibility(this._inputInstance, false) }); + } + + _addMenuItem(_volumeMenu, checkItem, menuItem) { + let menuItems = _volumeMenu._getMenuItems(); + let i = menuItems.findIndex(elem => elem === checkItem); + if (i < 0) { + i = menuItems.length; + } + _volumeMenu.addMenuItem(menuItem, ++i); + this._integrateMenu(_volumeMenu, getActor(checkItem), getActor(menuItem)); + } + + _expandVolMenu() { + if (this._settings.get_boolean(Prefs.EXPAND_VOL_MENU)) { + this._aggregateLayout.addSizeChild(getActor(this._volumeMenu)); + } else { + this._revertVolMenuChanges(); + } + } + + _revertVolMenuChanges() { + this._aggregateLayout._sizeChildren = this._aggregateLayout._sizeChildren.filter(item => item !== getActor(this._volumeMenu)); + this._aggregateLayout.layout_changed(); + } + + _updateMenuVisibility(menuInstance, visible) { + if (menuInstance instanceof SoundOutputDeviceChooser) { + this._integrateMenu(this._volumeMenu, getActor(this._volumeMenu._output.item), getActor(menuInstance.menuItem), visible); + } else { + this._integrateMenu(this._volumeMenu, getActor(this._volumeMenu._input.item), getActor(menuInstance.menuItem), visible); + } + } + + _switchSubmenuMenu() { + _d("Output Device visibility"); + this._updateMenuVisibility(this._outputInstance, getActor(this._outputInstance.menuItem).visible); + _d("Input Device visibility"); + this._updateMenuVisibility(this._inputInstance, getActor(this._inputInstance.menuItem).visible); + } + + _integrateMenu(_volumeMenu, sliderItem, selectorItem, visible) { + let canIntegrate = sliderItem.visible && (visible || selectorItem.visible) && this._settings.get_boolean(Prefs.INTEGRATE_WITH_SLIDER); + if (canIntegrate == true) { + _d("Integrating with Volume menu "); + if (_volumeMenu.box.contains(sliderItem) == true) { + _volumeMenu.box.remove_child(sliderItem); + } + sliderItem.set_x_expand(true); + sliderItem.set_style('padding-right: 0px;'); + if(sliderItem._ornamentLabel) + { + sliderItem._ornamentLabel.hide(); + } + sliderItem.set_track_hover(false); + selectorItem.insert_child_above(sliderItem, selectorItem.label); + selectorItem.label.hide(); + sliderItem.get_next_sibling().hide(); //expander + selectorItem.icon.hide(); + selectorItem.set_style('padding-left: 0px;padding-top: 0px; padding-bottom: 0px'); + } else { + _d("Not integrating with Volume menu") + if (selectorItem.contains(sliderItem) == true) { + selectorItem.remove_child(sliderItem); + } + sliderItem.set_x_expand(false); + sliderItem.set_style(''); + if(sliderItem._ornamentLabel) + { + sliderItem._ornamentLabel.show(); + } + sliderItem.set_track_hover(true); + selectorItem.label.show(); + selectorItem.label.get_next_sibling().show(); //expander + selectorItem.icon.show(); + selectorItem.set_style(''); + if (_volumeMenu.box.contains(sliderItem) == false) { + let oriVisible = sliderItem.visible; + _volumeMenu.box.insert_child_below(sliderItem, selectorItem); + sliderItem.visible = oriVisible; + } + } + } + + disable() { + //this._switchSubmenuMenu(); + this._revertVolMenuChanges(); + if (this._outputInstance) { + this._outputInstance.setVisible(false); + this._outputInstance.destroy(); + this._outputInstance = null; + } + if (this._inputInstance) { + this._inputInstance.setVisible(false); + this._inputInstance.destroy(); + this._inputInstance = null; + } + if (this._volumeMenuInstance) { + this._volumeMenuInstance.destroy(); + this._volumeMenuInstance = null; + } + this._settings = null; + this._signalManager.disconnectAll(); + this._signalManager = null; + } +}; + +function init() { + ExtensionUtils.initTranslations(Me.metadata["gettext-domain"]); + return new SDCInstance(); +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/icons/blank.png b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/icons/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..23568c66ae427c6f153f5492dea442fcc385c1b5 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPNCzA+|#{XsCn}9+>o-U3d7N?UFBv= + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/de_DE/LC_MESSAGES/sound-output-device-chooser.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/de_DE/LC_MESSAGES/sound-output-device-chooser.mo new file mode 100644 index 0000000000000000000000000000000000000000..4929de7ee23d928c4c0affd278b264c507717314 GIT binary patch literal 1582 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 WfhL<{lh$^d(e-6g8#`*f!Ttx4mIj>w literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/nl/LC_MESSAGES/sound-output-device-chooser.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/nl/LC_MESSAGES/sound-output-device-chooser.mo new file mode 100644 index 0000000000000000000000000000000000000000..bd5188e72f8150a0a71570eea4b28e9943ea145a GIT binary patch literal 2891 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/sk/LC_MESSAGES/sound-output-device-chooser.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/sk/LC_MESSAGES/sound-output-device-chooser.mo new file mode 100644 index 0000000000000000000000000000000000000000..9c773a6667576acc15d73bce601091928726cc7d GIT binary patch literal 1632 zcmaKrO>A355XZNr&|xzI|9yUqQ>kL*x4)g;*`5E)u75jz z2a%68r%?1^x~`2Ofo(kn>6KA@D3X4_3jT_X7|=aT8t0?;|kyeFi=XexBQ3f}uX& zfG5E3!BB^v!H2;+V5sLGV9;?4hnxdvLC6));De+rr*Lj)VP9w=UZ_FHBeYP5r?SyR zTNs8Mp2+7yT$Cr%8#JL5SuR0Ws7cl?o5Wa-#Ui(5ns~9O+#r!#B-2V zOO6w6d1dszlWH05$mnE?l%B3rqMR2?S~e4=tENMJc20KKi8ooZl?ko0_eyu1cuU2c zb@^_DQEl>Fw)|p#ve8U24^@jr4e_Ya<^E*oL`@G;Pm9^A6D!KKI7y^tlfp9Ew7S;7 zc~yoE2Z?K`Ke(fAte=Wm@0t%q=#WkDnnZPzDKpu5&)m=?X`czIyfsNyqPd=s5G@(Q8yBEMKaYX=aA>#p)SMl`vI4y-*O#(sEOew?!Q<7}|7Yatnb- z;~M0UwUT1JXSeol<(Mw;%OrcmH}G#rHXrPJ)EBO2ak i<2_aU-*q!g#@n&H{Rwpw>6AClE0k^jLb?aimEu2@aKR%0 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/sv/LC_MESSAGES/sound-output-device-chooser.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/sv/LC_MESSAGES/sound-output-device-chooser.mo new file mode 100644 index 0000000000000000000000000000000000000000..2bb16f258b6e03b48c210521a71a0661aa35f642 GIT binary patch literal 1883 zcmZ9L&u<$=6vqc>fSTW>{1g&{C;uLRb! zc%H-aH=dX9+`J1fthKv^xDQ+hXTcBZ{iomq*nbY50>7;J6Zkmx2jC0fEs)Qhyhn&f z!L#5oa20$7Tn8KA$KVY38Tb(RMa}E=_isQx_kGPD!H2QG39|k#wfqn81oj6Y`|&Tx z_s`()Da7;|cpUq6Ty_rp5WF9}4zm1fkp2F)=5OHB*#85*2p+#zh}3uOOq)!%1u=p^=yn$Lr?*e`-y zqQ~$&h=&*Ff$PZk<9KNwDDQg)^m<58R|vt?Egx-=WLM9nz7XO@VhiRM6qJkRYP*sWiqD_R7PPc zvvh50TI!T+)P3DkrRkO3NH&#Q&J;Px4%tFR2X~`PD=)2rHSr!<^2*2!ic#Avh>NgO zzG^q%ukLf?o?fn9be3u(q7BDocR)Fne}ib-VG(7Oh#)#T^vD=x$rac+>v{w4pnM6J zi%T#hE*J6k6Kl@LLuWPy?wa5i(!yGm>!A|4>f{}=Q57z{ir$$r+i6vtsmE*HZ6o_h zJ59F82UMXY8&_zEdy`JcbegAoeysL^S6Rt`O#pKCVGBRG^g;Wlf@NW1ZMbegtjWpAK-pm=Vxdm%Y zXOk7%b1914l4q{!*myswieGxX<|svPEX*y=Ei}Z1$)3-Q%DAPY%ye%D1&Ab7#3ZOR zRWkFFJ%na;jDb7b%KqdATE&Jq*)zuC8s)`CR5n#UMZXRxhBzLIEgh6J+eKQBgs%>c z6b6l0tJ2UrXbulairh*q3lELJ^PsF)+KGCEw#8ItSx#w6Xfd?^;fLukkcT5ujiepd zgCaKL)ai&T&BD@Vxbh4NnpP)ESMIqAir)a#(&>y{=xtN literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/ta/LC_MESSAGES/sound-output-device-chooser.mo b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/locale/ta/LC_MESSAGES/sound-output-device-chooser.mo new file mode 100644 index 0000000000000000000000000000000000000000..d3809ee2a44472ab13d20c6888330439d78abdda GIT binary patch literal 4780 zcmcJRTZ|-C8OINZ0^^07qIh8sATk@Q-kHflmR^SF?kvm19hfi!!9eSohS{jm z%5?qf)cMYL`G5a&YW{NLRc95~9sEAcZ~qla?E{Zp$&Krp_bGK4ycWC>TmU~0ejU6T zJPm#hJPUpl{7v!x58wwGzXRR}z6*X9+;f%3Ik3q%0&fD(gSUaNf#UB^1zz!frEXz7 z30@B#0+~`v;3W72I00^f{HgDA`!IN>z@LCJ-v?#g>jl06euVK`pxD0+UJDM3`M-lw z?>|7v@5&GOylw{1z|k!DXWsuF5*`9yx<;uB;6K6Zz+d3(r{JsLA@Iv2aVz*^@MiGW z;LpLg!3cZ`vNplLg1-g7@*$-j0QZnw41Nt1``>{%_$0|61^)&%zy?7j|F442fF1Av z_%0}MZ-u=5;4CP1DR?LNG>D1%87Ta}3`$@A2;L1|cZ2WuK~VVUf)e+e-~#v-_#Aix zlhEQWkn zi}I4(rCK7a)=$7`mzLLJvzM5Pzv1#RcpKhDXKjvMdQ}bjmN==)$ z8&S*XDADrzXkyolUb4NUt(Q!mM@c8!tG?LEqm3}fdd^ulb?sH@Ak*Eb-8PB1TC{0i zt#7EqHnzk9dvRMQHrKHY+b-aGYF15Zl9tKzWAl17ijA5x;m&|_W;N`^Ig>8m<;`^r zqbyvBUGnCs+$33K6J7V1TODrLNJ2%KUNPNpBeK1;AuHG8a8rl9c4S#%C2*!!ZK^#< zc&dz|mQ6BklXz2VtLAkaW#nU%yK)`Iu{}|8xeE`PY*vh}YEwrNm;Eu@(Q78l!j8$x zcZoSsW~C!Y&7;+*73PxF5vjDTAGdLjRxOyMCyrO6ybPa&c=KkCkXAQLI`qy3Hac_7 z^<8V!%%UX9qmY{Dd85%#M@?eVFs|CD9wHHUD=2`gXjPh+n!5^mY+{Nm)I6l=<*r#X z?lDvI$$Bp@1eB?TC~KKG4ijU0jBH|C-4yMqhsj<&j3f0(FR!l{)0A5DEklV*U3O%Wvr zHIhj)lg~c3{9tfkWG5-ITZ1D>%eIk8Qy*A~@`)z`uN9a3qBU)_IMdkQn4VaSdq^mF z(57oyQzz?gn9a@{)c$dHGSRoq>gl})apG4796o8w9QGMBwNF7!4*O?^gVV$QFNcHg z4f}nb^{{_t*nfH0f0L(Y-Mdr6{)^6v`_nNeBj^>EK3$=* ztp*9d;2Lz%Q^)v{8$&m2RvtQWTLvn;M*rS6o%@{+NqKh!&l^}UB0id7K z^WYS(e&|w%)r$SXHHi3|%Bxhl(~2U|>6i|X|M$TjWk zw%t@QCCs`cT|-G}N0-WZ0*tn-55@h0U+j8U3tRM!21}EO4kypMP&E5Zg-?iL zTz#SgYAZYBWi>dd98-So5~ek`LPEJnHkWWug<}rgatYuK2bk<^CR>`wW8(6P@yCRy zwH9`_gKw}!uo2zT z7p4-7`^@-5ywp&QTC&_ZH&%S@h?jM8q!3`V9qL7nwlyY*mU3W?&UjKeJFqB@&&zIS zF>@7{qLv|KkpQk_R?Gi-C7(`lP7b?^dT<)^;`9@^nDeeC?Kh+e&0qHo)}MKI1rUtlpF4^T=9llR>7Qr~yHo*Z>P@4{8R zOC_gHdMu&{HpB&CSsGw9reVfE@Ewt$zQj@|jw$&9Fo8(@|1_nz zgfDz<=Y4x}qr~;)jx5(*l7<}a{$xgXep77U((XSF)I-e}LR wA6+;Z5#-uX9fN-3`6}gmjF`S#5+dgxub3>41Zmv1&fv-S91{J1AlnH07wElvr~m)} literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/metadata.json b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/metadata.json new file mode 100644 index 0000000..e5c1fae --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/metadata.json @@ -0,0 +1,20 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Shows a list of sound output and input devices (similar to gnome sound settings) in the status menu below the volume slider. Various active ports like HDMI , Speakers etc. of the same device are also displayed for selection. V20+ needs python as dependency. If you want to continue with the old method without Python, use options to switch off New Port identification. But it works with only English", + "gettext-domain": "sound-output-device-chooser", + "name": "Sound Input & Output Device Chooser", + "original-author": "GopI", + "settings-schema": "org.gnome.shell.extensions.sound-output-device-chooser", + "shell-version": [ + "3.34", + "3.32", + "3.36", + "3.38", + "40", + "41", + "42" + ], + "url": "https://github.com/kgshank/gse-sound-output-device-chooser", + "uuid": "sound-output-device-chooser@kgshank.net", + "version": 43 +} \ No newline at end of file diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/prefs.js b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/prefs.js new file mode 100644 index 0000000..38093b0 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/prefs.js @@ -0,0 +1,328 @@ +/******************************************************************************* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * Original Author: Gopi Sankar Karmegam + ******************************************************************************/ +/* jshint moz:true */ + +const { Gio, GObject, Gtk } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Lib = Me.imports.convenience; +const _d = Lib._log; +const SignalManager = Lib.SignalManager; + +const Gettext = imports.gettext; +const _ = Gettext.gettext; + +var HIDE_ON_SINGLE_DEVICE = "hide-on-single-device"; +var HIDE_MENU_ICONS = "hide-menu-icons"; +var SHOW_PROFILES = "show-profiles"; +var PORT_SETTINGS = "ports-settings"; +var SHOW_INPUT_SLIDER = "show-input-slider"; +var SHOW_INPUT_DEVICES = "show-input-devices"; +var SHOW_OUTPUT_DEVICES = "show-output-devices"; +var ENABLE_LOG = "enable-log"; +var NEW_PROFILE_ID_DEPRECATED = "new-profile-indentification"; +var NEW_PROFILE_ID = "new-profile-identification"; +var EXPAND_VOL_MENU = "expand-volume-menu"; +var CANNOT_ACTIVATE_HIDDEN_DEVICE = "cannot-activate-hidden-device"; +var OMIT_DEVICE_ORIGIN = "omit-device-origins"; +var INTEGRATE_WITH_SLIDER = "integrate-with-slider"; + +var ICON_THEME = "icon-theme"; +var ICON_THEME_COLORED = "colored"; +var ICON_THEME_MONOCHROME = "monochrome"; +var ICON_THEME_NONE = "none"; + +var DISPLAY_OPTIONS = { SHOW_ALWAYS: 1, HIDE_ALWAYS: 2, DEFAULT: 3, INITIAL: -1 }; + +const PORT_SETTINGS_VERSION = 3; + +function init() { + ExtensionUtils.initTranslations(); +} + +function getPortsFromSettings(_settings) { + //_d(_settings.get_string(PORT_SETTINGS)); + let obj = JSON.parse(_settings.get_string(PORT_SETTINGS)); + let currentSettingsVersion = PORT_SETTINGS_VERSION; + if (Array.isArray(obj)) { + currentSettingsVersion = 1; + } + else { + currentSettingsVersion = obj.version; + } + + if (currentSettingsVersion < PORT_SETTINGS_VERSION) { + obj = migratePortSettings(currentSettingsVersion, obj, _settings); + } + return obj.ports; +} + +function setPortsSettings(ports, _settings) { + let settingsObj = { "version": PORT_SETTINGS_VERSION }; + settingsObj.ports = ports; + //_d(JSON.stringify(settingsObj)); + _settings.set_string(PORT_SETTINGS, JSON.stringify(settingsObj)); + return settingsObj; +} + +function getPortDisplayName(port) { + return `${port.human_name} - ${port.card_description}`; +} + +function migratePortSettings(currVersion, currSettings, _settings) { + let ports = []; + let _lPorts = Lib.getPorts(true).slice(); + switch (currVersion) { + case 1: + for (let port of currSettings) { + for (var i = 0; i < _lPorts.length; i++) { + let _lPort = _lPorts[i]; + if (port.human_name == _lPort.human_name && port.name == _lPort.name) { + port.card_name = _lPort.card_name; + port.card_description = _lPort.card_description; + port.display_name = getPortDisplayName(_lPort); + _lPorts.splice(i, 1); + ports.push(port); + break; + } + } + } + break; + + case 2: + for (let port of currSettings.ports) { + for (var i = 0; i < _lPorts.length; i++) { + let _lPort = _lPorts[i]; + if (port.human_name == _lPort.human_name && port.name == _lPort.name && port.card_name == _lPort.card_name) { + port.card_description = _lPort.card_description; + _lPorts.splice(i, 1); + ports.push(port); + break; + } + } + } + break; + } + return setPortsSettings(ports, _settings); +} + +const SDCSettingsWidget = new GObject.Class({ + Name: "SDC.Prefs.Widget", + GTypeName: "SDCSettingsWidget", + Extends: Gtk.Box, + + _init: function(params) { + this.parent(params); + this.orientation = Gtk.Orientation.VERTICAL; + this.spacing = 0; + let uiFileSuffix = ""; + + if (Gtk.get_major_version() >= "4") { + uiFileSuffix = "40"; + this.__addFn = this.append; + this.__showFn = this.show; + } + else { + this.__addFn = x => this.pack_start(x, true, true, 0); + this.__showFn = this.show_all; + } + // creates the settings + this._settings = ExtensionUtils.getSettings(); + + Lib.setLog(this._settings.get_boolean(ENABLE_LOG)); + + // creates the ui builder and add the main resource file + let uiFilePath = Me.path + "/ui/prefs-dialog" + uiFileSuffix + ".glade"; + let builder = new Gtk.Builder(); + builder.set_translation_domain("sound-output-device-chooser"); + + if (builder.add_from_file(uiFilePath) == 0) { + _d("JS LOG: could not load the ui file: %s".format(uiFilePath)); + let label = new Gtk.Label({ + label: _("Could not load the preferences UI file"), + vexpand: true + }); + this.__addFn(label); + } else { + _d("JS LOG:_UI file receive and load: " + uiFilePath); + + let mainContainer = builder.get_object("main-container"); + + this.__addFn(mainContainer); + + this._signalManager = new SignalManager(); + + let showProfileSwitch = builder.get_object(SHOW_PROFILES); + let volMenuSwitch = builder.get_object(EXPAND_VOL_MENU); + let singleDeviceSwitch = builder.get_object(HIDE_ON_SINGLE_DEVICE); + let showInputSliderSwitch = builder.get_object(SHOW_INPUT_SLIDER); + let showInputDevicesSwitch = builder.get_object(SHOW_INPUT_DEVICES); + let showOutputDevicesSwitch = builder.get_object(SHOW_OUTPUT_DEVICES); + let hideMenuIconsSwitch = builder.get_object(HIDE_MENU_ICONS); + let iconThemeCombo = builder.get_object(ICON_THEME); + let logSwitch = builder.get_object(ENABLE_LOG); + let newProfileIdSwitch = builder.get_object(NEW_PROFILE_ID); + let cantActHiddSwitch = builder.get_object(CANNOT_ACTIVATE_HIDDEN_DEVICE); + let omitDeviceOrigin = builder.get_object(OMIT_DEVICE_ORIGIN); + let integrateWithSlider = builder.get_object(INTEGRATE_WITH_SLIDER); + + this._settings.bind(HIDE_ON_SINGLE_DEVICE, singleDeviceSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(SHOW_PROFILES, showProfileSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(EXPAND_VOL_MENU, volMenuSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(SHOW_INPUT_SLIDER, showInputSliderSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(SHOW_INPUT_DEVICES, showInputDevicesSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(SHOW_OUTPUT_DEVICES, showOutputDevicesSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(HIDE_MENU_ICONS, hideMenuIconsSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(ENABLE_LOG, logSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(NEW_PROFILE_ID, newProfileIdSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(CANNOT_ACTIVATE_HIDDEN_DEVICE, cantActHiddSwitch, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(OMIT_DEVICE_ORIGIN, omitDeviceOrigin, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(INTEGRATE_WITH_SLIDER, integrateWithSlider, "active", Gio.SettingsBindFlags.DEFAULT); + this._settings.bind(ICON_THEME, iconThemeCombo, "active-id", Gio.SettingsBindFlags.DEFAULT); + + //Show always is not working always, hidden in the UI directly + let showAlwaysToggleRender = builder.get_object("ShowAlwaysToggleRender"); + let hideAlwaysToggleRender = builder.get_object("HideAlwaysToggleRender"); + let showActiveToggleRender = builder.get_object("ShowActiveToggleRender"); + + this._signalManager.addSignal(showAlwaysToggleRender, "toggled", this._showAlwaysToggleRenderCallback.bind(this)); + this._signalManager.addSignal(hideAlwaysToggleRender, "toggled", this._hideAlwaysToggleRenderCallback.bind(this)); + this._signalManager.addSignal(showActiveToggleRender, "toggled", this._showActiveToggleRenderCallback.bind(this)); + + this._portsStore = builder.get_object("ports-store"); + + this._populatePorts(); + this._restorePortsFromSettings(); + } + }, + + _populatePorts: function() { + let ports = Lib.getPorts(true); + ports.sort((a, b) => (b.direction.localeCompare(a.direction)) || getPortDisplayName(a).localeCompare(getPortDisplayName(b))).forEach(port => { + this._portsStore.set(this._portsStore.append(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [port.human_name, false, false, true, port.name, 3, port.card_name, port.card_description, getPortDisplayName(port), port.direction]); + }); + }, + + _showAlwaysToggleRenderCallback: function(widget, path) { + //this._toggleCallback(widget, path, 1, [2, 3]); + this._toggleCallback(widget, path, DISPLAY_OPTIONS.SHOW_ALWAYS, [2, 3]); + }, + + _hideAlwaysToggleRenderCallback: function(widget, path) { + //this._toggleCallback(widget, path, 2, [1, 3]); + this._toggleCallback(widget, path, DISPLAY_OPTIONS.HIDE_ALWAYS, [1, 3]); + }, + + _showActiveToggleRenderCallback: function(widget, path) { + //this._toggleCallback(widget, path, 3, [1, 2]); + this._toggleCallback(widget, path, DISPLAY_OPTIONS.DEFAULT, [1, 2]); + }, + + _toggleCallback: function(widget, path, activeCol, inactiveCols) { + let active = !widget.active; + if (!active) { + return; + } + let [success, iter] = this._portsStore.get_iter_from_string(path); + if (!success) { + return; + } + /*Dont support non-pci cards for show always*/ + let card_name = this._portsStore.get_value(iter, 6); + if (!/\.pci-/.exec(card_name) && activeCol == 1) { + //this._toggleCallback(widget, path, 3, [1, 2]); + this._toggleCallback(widget, path, DISPLAY_OPTIONS.DEFAULT, [1, 2]); + } + else { + this._portsStore.set_value(iter, activeCol, active); + this._portsStore.set_value(iter, 5, activeCol); + for (let col of inactiveCols) { + this._portsStore.set_value(iter, col, !active); + } + this._commitSettings(); + } + }, + + _commitSettings: function() { + let ports = []; + let [success, iter] = this._portsStore.get_iter_first(); + while (iter && success) { + if (!this._portsStore.get_value(iter, 3)) { + let display_option = this._portsStore.get_value(iter, 5); + //if (display_option != 3) {//Dont store default value + if (display_option != DISPLAY_OPTIONS.DEFAULT) {//Dont store default value + ports.push({ + human_name: this._portsStore.get_value(iter, 0), + name: this._portsStore.get_value(iter, 4), + display_option: display_option, + card_name: this._portsStore.get_value(iter, 6), + card_description: this._portsStore.get_value(iter, 7), + display_name: this._portsStore.get_value(iter, 8) + }); + } + } + success = this._portsStore.iter_next(iter); + } + setPortsSettings(ports, this._settings); + }, + + _restorePortsFromSettings: function() { + let ports = getPortsFromSettings(this._settings); + + let found; + for (let port of ports) { + found = false; + if (!port || !port.human_name || !port.name) { + continue; + } + + let [success, iter] = this._portsStore.get_iter_first(); + + while (iter && success) { + let human_name = this._portsStore.get_value(iter, 0); + let name = this._portsStore.get_value(iter, 4); + let card_name = this._portsStore.get_value(iter, 6); + + if (port.name == name && port.human_name == human_name && port.card_name == card_name) { + this._portsStore.set_value(iter, 3, false); + this._portsStore.set_value(iter, port.display_option, true); + this._portsStore.set_value(iter, 5, port.display_option); + found = true; + break; + } + success = this._portsStore.iter_next(iter); + } + + if (!found) { + iter = this._portsStore.append(); + this._portsStore.set(iter, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [port.human_name, false, false, false, port.name, port.display_option, port.card_name, port.card_description, port.display_name, ""]); + this._portsStore.set_value(iter, port.display_option, true); + } + } + } +}); + + +function buildPrefsWidget() { + let _settingsWidget = new SDCSettingsWidget(); + _settingsWidget.__showFn(); + + return _settingsWidget; +} diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/schemas/gschemas.compiled b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/schemas/gschemas.compiled new file mode 100644 index 0000000000000000000000000000000000000000..7c5c5c13e178dad8219965fa3e2e4ad9ad9a059e GIT binary patch literal 1248 zcmaJ>J!lj`7#)8uYGM)-2^>m54vPfbJ3&-TWh06Ne+olD18z2x+kxGgV|VT@pwWnk z_C^Ik2!iQ^Alg}IWsqoNx_}1MDi8uTcJaO0%b8fX@OW?E&dm4C?Dx&tAwN;RwxaRm z!NZyE+rD9fb3H<=he@<}m6L;+&WUPh;XXuu00rvNo|SrlE|YqMWc& zr^@KGn3}2{^GwxNs@5BmH5EuN2#rZ)f{8-(bvw$|VIDhymIii%TmL~D-uD6>4RnI{ zHE{U(#Pu#{=5;{S#2oky@bKm3xAdvI;Ln3U0Us9^KGUb}gue{_39R0I`i(wyEBrO^ zI`C_@{+d2@H~jn#A$oy&a%ho0bvyi{;N!siFCQM!r|yA&348_k9$i?YPrV<02#$eh zb)in5n(I%2?*XswTrAS3J_vsX`~rA4d8>{8iaG~>4!i>N++R7#@lM0%q2_?0-w&S9 zr|y8C2loOuJH9@qPu&auH24f)=LhoishQ_6cm!BlJGDfgn&%UOWBRi#x9L-J{VDJ> zV56p}g%}hw;AKF|x>rfexQe8w#-z4tTm`;G;jkY1M*Gvy)IFtHJ86Uws2S&n&|WNc z)l&hgjH{xQM*I2Z*-*w(#73JSOi+~gl5SoptHQ>lO>r8TG(NaEN?Tb@d@H@WvSBla zW;_$CW>uR+l@)VA9&)1MqwH%Ys>WHOS)45!)?0S$;uR~t4YSotXsVKHs*-D}(%+^k z{imr)LZt3=a1g1|Wt?obUzb-kMK+rb2BBQsz}MPX&kwAsakp3j$u(y(BR9_dk1frd zI$vsk6p + + + + + false + Preference to show the chooser when only one device is available + Value set to false hides the device chooser when only one device is available + + + + true + Preference to show the available profiles for all devices + Value set to true displays the individual available profiles for each device + + + + true + Preference to expand volume menu to fit the name of the sound devices + Value set to true expands the volume menu to fit the names of sound devices displayed in the selector + + + + true + Preference to use monochrome icons instead of default icons + Value set to true uses monochrome icons + + + + true + Preference to show input slider always + Value set to true displays the slider control for input device volume + + + + true + Preference to show input device chooser + Value set to true displays the device chooser for input devices + + + + true + Preference to show output device chooser + Value set to true displays the device chooser for output devices + + + + "{\"version\":3,\"ports\":[]}" + Preference to hide/show different ports always + + + + + "monochrome" + Preference indicating the type of icons used by the extension + Value can be "colored", "monochrome", "none", etc. + + + + false + Preference indicating whether the icons are hidden in the drop-down menu (but are visible in the expanded list). + + + + + false + Preference indicating log messages should be written to console + + + + + true + (Deprecated)Old preference name with a typo. To be removed in the next shell version + + + + + true + Preference to enable python script to identify port profiles + + + + + true + Preference to avoid activation of hidden devices in Port Settings + + + + + false + Preference to omit device origin at Volume Menu + + + + + false + Preference to integrate selector with slider + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog.glade b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog.glade new file mode 100644 index 0000000..b6e62e7 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog.glade @@ -0,0 +1,956 @@ + + + + + + + + + + + + + + monochrome + Monochrome + + + colored + Colored + + + none + None + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + 6 + 6 + vertical + 2 + + + True + False + True + True + True + + + True + False + 12 + 12 + vertical + 12 + + + True + False + 10 + 10 + 0.029999999329447746 + out + + + True + False + none + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Integrate selector with slider + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Hide selector if there's only one device + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Display audio profiles for selection + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Omit device origins at Volume Menu + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Extend Volume Menu to fit device names + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + + + True + False + start + Don't allow device hidden in Port Settings to be activated + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + + + True + False + start + (Select / deselect the required device in the Gnome Sound Settings) + + + True + True + 0 + + + + + + + + + + + True + False + General Settings + + + + + + + + False + True + 0 + + + + + True + False + 10 + 10 + 0.029999999329447746 + out + + + True + False + + + 100 + True + True + + + True + False + center + 6 + 6 + + + True + False + start + Show output devices + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + + + True + False + Output Devices + + + + + + + + False + True + 1 + + + + + True + False + 10 + 10 + 0.029999999329447746 + out + + + True + False + none + + + 100 + True + True + True + + + True + False + center + 6 + 6 + + + True + False + start + Show input devices + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + 100 + True + True + center + + + True + False + 6 + 6 + + + True + False + start + Show volume control for default device + + + True + True + 0 + + + + + True + True + end + + + False + True + 1 + + + + + + + + + + + True + False + Input Devices + + + + + + + + False + True + 2 + + + + + True + False + 10 + 10 + 0.029999999329447746 + in + + + True + False + none + + + 100 + True + True + + + 6 + True + False + 6 + 6 + + + True + False + start + Icon Theme + + + True + True + 0 + + + + + 100 + True + False + icon-theme-store + 0 + + + + 1 + + + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Display icons only in selection list + + + True + True + 0 + + + + + True + True + + + False + True + 1 + + + + + + + + + + + True + False + Icons + + + + + + + + False + True + 3 + + + + + True + False + 10 + 10 + 0.029999999329447746 + in + + + True + False + none + + + 100 + True + True + + + 6 + True + False + 6 + 6 + + + True + False + start + Enable Log messages + + + True + True + 0 + + + + + True + True + + + False + True + 1 + + + + + + + + + 100 + True + True + + + True + False + 6 + 6 + + + True + False + start + Enable new profile identification + + + True + True + 0 + + + + + True + True + True + + + False + True + 1 + + + + + + + + + + + True + False + Miscellaneous + + + + + + + + False + True + 4 + + + + + False + True + 0 + + + + + True + False + 12 + 12 + vertical + + + True + False + 10 + 10 + True + 0.029999999329447746 + out + + + True + False + 4 + True + vertical + + + True + True + 0.9999999986588954 + True + True + queue + in + 500 + + + True + True + True + ports-store + False + both + + + + + + True + autosize + 100 + Name + True + + + + 8 + + + + + + + autosize + 100 + Device Type + True + descending + + + + 9 + + + + + + + False + autosize + Show + + + True + + + 1 + + + + + + + autosize + Hide + + + True + + + 2 + + + + + + + autosize + Default + + + True + + + 3 + + + + + + + + + False + True + 1 + + + + + + + True + False + Port Settings + + + + + + + + False + True + 0 + + + + + False + True + 1 + + + + + False + True + 1 + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog40.glade b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog40.glade new file mode 100644 index 0000000..7e30ccc --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/ui/prefs-dialog40.glade @@ -0,0 +1,655 @@ + + + + + + + + + + + + + monochrome + Monochrome + + + colored + Colored + + + none + None + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 6 + 6 + 6 + 6 + vertical + 2 + + + 0 + 1 + 1 + 1 + + + 12 + 6 + 12 + 12 + vertical + 12 + + + 0 + + + 0 + none + + + 100 + + + 0 + 6 + 6 + + + 1 + start + 5 + Integrate selector with slider + + + + + end + 5 + + + + + + + + + 100 + + + 0 + 6 + 6 + + + 1 + start + 5 + Hide selector if there's only one device + + + + + end + 5 + + + + + + + + + 100 + + + 6 + 6 + + + 1 + start + 5 + Display audio profiles for selection + + + + + end + 5 + + + + + + + + + 100 + + + 6 + 6 + + + 1 + start + 5 + 20 + Omit device origins at Volume Menu + + + + + end + 5 + + + + + + + + + 100 + + + 6 + 6 + + + 1 + start + 5 + 20 + Extend Volume Menu to fit device names + + + + + end + 5 + + + + + + + + + 100 + + + 6 + + + 1 + start + 5 + 20 + Don't allow device hidden in Port Settings to be activated + + + + + end + 5 + + + + + + + + + 100 + + + 6 + + + 1 + start + 5 + 20 + (Select / deselect the required device in the Gnome Sound Settings) + + + + + + + + + + + General Settings + + + + + + + + + + + + + + + 100 + + + center + 6 + 6 + + + 1 + start + 5 + Show output devices + + + + + end + 5 + + + + + + + + + + + + Output Devices + + + + + + + + + + + + + none + + + 100 + 1 + + + center + 6 + 6 + + + 1 + start + 5 + Show input devices + + + + + end + 5 + + + + + + + + + 100 + center + + + 6 + 6 + + + 1 + start + 5 + Show volume control for default device + + + + + end + 5 + + + + + + + + + + + + Input Devices + + + + + + + + + + + + + none + + + 100 + + + 6 + 6 + 6 + + + 1 + start + 5 + Icon Theme + + + + + 100 + 5 + icon-theme-store + 0 + + + + 1 + + + + + + + + + + + 100 + + + 6 + 6 + + + 1 + start + 5 + Display icons only in selection list + + + + + 5 + + + + + + + + + + + + Icons + + + + + + + + + + + + + none + + + 100 + + + 6 + 6 + 6 + + + 1 + start + 5 + Enable Log messages + + + + + + + + + + + + 100 + + + 6 + 6 + + + 1 + start + 5 + Enable new profile identification + + + + + 1 + + + + + + + + > + + + + Miscellaneous + + + + + + + + + + + + 6 + 12 + 12 + 12 + vertical + + + 1 + + + + 4 + 4 + 4 + 1 + vertical + + + 0.9999999986588954 + 1 + 1 + 500 + + + + + 1 + ports-store + + + + + + 1 + autosize + 100 + Name + 1 + descending + + + + 8 + + + + + + + autosize + 100 + Device Type + True + descending + + + + 9 + + + + + + + False + autosize + Show + + + 1 + + + 1 + + + + + + + autosize + Hide + + + 1 + + + 2 + + + + + + + autosize + Default + + + 1 + + + 3 + + + + + + + + + + + + + + + Port Settings + + + + + + + + + + + + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/__pycache__/libpulse_introspect.cpython-310.pyc b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/__pycache__/libpulse_introspect.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc586a51aa6516defa59813f54a7d7bed6f7e259 GIT binary patch literal 9746 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 literal 0 HcmV?d00001 diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py new file mode 100644 index 0000000..af4209a --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/libpulse_introspect.py @@ -0,0 +1,544 @@ +# This file is generated using clang2py script. The following files are used +# '/usr/include/pulse/introspect.h' '/usr/include/pulse/mainloop.h' '/usr/include/pulse/context.h' +# Refer additional licensing requirements for the files included +# sample commands used +# python3 /usr/bin/clang2py --clang-args="-I/usr/include/clang/6.0/include -I/usr/include/pulse" -l /usr/lib/libpulse.so '/usr/include/pulse/introspect.h' '/usr/include/pulse/mainloop.h' '/usr/include/pulse/proplist.h' +# python3 /usr/local/bin/clang2py --clang-args="-I/usr/include/clang/6.0/include -I/usr/include/pulse" -l /usr/lib/x86_64-linux-gnu/libpulse.so '/usr/include/pulse/introspect.h' '/usr/include/pulse/mainloop.h' +# python3 /usr/local/bin/clang2py --clang-args="-I/usr/include/clang/6.0/include -I/usr/include/pulse" -l /usr/lib/x86_64-linux-gnu/libpulse.so '/usr/include/pulse/context.h' +################################################################################ +# # This program is free software: you can redistribute it and/or modify it under +# # the terms of the GNU General Public License as published by the Free Software +# # Foundation, either version 3 of the License, or (at your option) any later +# # version. +# # +# # This program is distributed in the hope that it will be useful, but WITHOUT +# # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# # details. +# # +# # You should have received a copy of the GNU General Public License along with +# # this program. If not, see . +# # +# # Original Author: Gopi Sankar Karmegam +# ############################################################################## +# -#- coding: utf-8 -#- +# +# TARGET arch is: ['-I/usr/include/clang/6.0/include', '-I/usr/include/pulse'] +# WORD_SIZE is: 8 +# POINTER_SIZE is: 8 +# LONGDOUBLE_SIZE is: 16 +# + +# Updated to determine libpulse.so location +import ctypes +from ctypes.util import find_library + +c_int128 = ctypes.c_ubyte*16 +c_uint128 = c_int128 +void = None +if ctypes.sizeof(ctypes.c_longdouble) == 16: + c_long_double_t = ctypes.c_longdouble +else: + c_long_double_t = ctypes.c_ubyte*16 + +# if local wordsize is same as target, keep ctypes pointer function. +if ctypes.sizeof(ctypes.c_void_p) == 8: + POINTER_T = ctypes.POINTER +else: + # required to access _ctypes + import _ctypes + # Emulate a pointer class using the approriate c_int32/c_int64 type + # The new class should have : + # ['__module__', 'from_param', '_type_', '__dict__', '__weakref__', '__doc__'] + # but the class should be submitted to a unique instance for each base type + # to that if A == B, POINTER_T(A) == POINTER_T(B) + ctypes._pointer_t_type_cache = {} + def POINTER_T(pointee): + # a pointer should have the same length as LONG + fake_ptr_base_type = ctypes.c_uint64 + # specific case for c_void_p + if pointee is None: # VOID pointer type. c_void_p. + pointee = type(None) # ctypes.c_void_p # ctypes.c_ulong + clsname = 'c_void' + else: + clsname = pointee.__name__ + if clsname in ctypes._pointer_t_type_cache: + return ctypes._pointer_t_type_cache[clsname] + # make template + class _T(_ctypes._SimpleCData,): + _type_ = 'L' + _subtype_ = pointee + def _sub_addr_(self): + return self.value + def __repr__(self): + return '%s(%d)'%(clsname, self.value) + def contents(self): + raise TypeError('This is not a ctypes pointer.') + def __init__(self, **args): + raise TypeError('This is not a ctypes pointer. It is not instanciable.') + _class = type('LP_%d_%s'%(8, clsname), (_T,),{}) + ctypes._pointer_t_type_cache[clsname] = _class + return _class + +_libraries = {} + +libpulse_library_name = find_library('pulse') +if libpulse_library_name is None: + raise Exception('No libpulse.so library found!') + +try: + _libraries['libpulse.so'] = ctypes.cdll.LoadLibrary(libpulse_library_name) +except OSError: + raise Exception('Cannot load libpulse.so library!') + + +uint32_t = ctypes.c_uint32 + +size_t = ctypes.c_uint64 +class struct_pa_context(ctypes.Structure): + pass + +pa_context = struct_pa_context +pa_context_notify_cb_t = ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), POINTER_T(None)) +pa_context_success_cb_t = POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), ctypes.c_int32, POINTER_T(None))) + +class struct_pa_proplist(ctypes.Structure): + pass + +pa_context_event_cb_t = POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), ctypes.c_char_p, POINTER_T(struct_pa_proplist), POINTER_T(None))) +class struct_pa_mainloop_api(ctypes.Structure): + pass + +pa_context_new = _libraries['libpulse.so'] .pa_context_new +pa_context_new.restype = POINTER_T(struct_pa_context) +pa_context_new.argtypes = [POINTER_T(struct_pa_mainloop_api), ctypes.c_char_p] + +# pa_context_new_with_proplist = _libraries['libpulse.so'] .pa_context_new_with_proplist +# pa_context_new_with_proplist.restype = POINTER_T(struct_pa_context) +# pa_context_new_with_proplist.argtypes = [POINTER_T(struct_pa_mainloop_api), ctypes.c_char_p, POINTER_T(struct_pa_proplist)] + +pa_context_unref = _libraries['libpulse.so'] .pa_context_unref +pa_context_unref.restype = None +pa_context_unref.argtypes = [POINTER_T(struct_pa_context)] + +# pa_context_ref = _libraries['libpulse.so'] .pa_context_ref +# pa_context_ref.restype = POINTER_T(struct_pa_context) +# pa_context_ref.argtypes = [POINTER_T(struct_pa_context)] + +pa_context_set_state_callback = _libraries['libpulse.so'] .pa_context_set_state_callback +pa_context_set_state_callback.restype = None +pa_context_set_state_callback.argtypes = [POINTER_T(struct_pa_context), pa_context_notify_cb_t, POINTER_T(None)] +# +# pa_context_set_event_callback = _libraries['libpulse.so'] .pa_context_set_event_callback +# pa_context_set_event_callback.restype = None +# pa_context_set_event_callback.argtypes = [POINTER_T(struct_pa_context), pa_context_event_cb_t, POINTER_T(None)] +# +# pa_context_errno = _libraries['libpulse.so'] .pa_context_errno +# pa_context_errno.restype = ctypes.c_int32 +# pa_context_errno.argtypes = [POINTER_T(struct_pa_context)] +# +# pa_context_is_pending = _libraries['libpulse.so'] .pa_context_is_pending +# pa_context_is_pending.restype = ctypes.c_int32 +# pa_context_is_pending.argtypes = [POINTER_T(struct_pa_context)] + + + +# values for enumeration 'pa_context_state' +pa_context_state__enumvalues = { + 0: 'PA_CONTEXT_UNCONNECTED', + 1: 'PA_CONTEXT_CONNECTING', + 2: 'PA_CONTEXT_AUTHORIZING', + 3: 'PA_CONTEXT_SETTING_NAME', + 4: 'PA_CONTEXT_READY', + 5: 'PA_CONTEXT_FAILED', + 6: 'PA_CONTEXT_TERMINATED', +} + +PA_CONTEXT_UNCONNECTED = 0 +PA_CONTEXT_CONNECTING = 1 +PA_CONTEXT_AUTHORIZING = 2 +PA_CONTEXT_SETTING_NAME = 3 +PA_CONTEXT_READY = 4 +PA_CONTEXT_FAILED = 5 +PA_CONTEXT_TERMINATED = 6 + +pa_context_state = ctypes.c_int # enum +pa_context_state_t = pa_context_state +pa_context_state_t__enumvalues = pa_context_state__enumvalues + +pa_context_get_state = _libraries['libpulse.so'] .pa_context_get_state +pa_context_get_state.restype = pa_context_state_t +pa_context_get_state.argtypes = [POINTER_T(struct_pa_context)] + +# values for enumeration 'pa_context_flags' +pa_context_flags__enumvalues = { + 0: 'PA_CONTEXT_NOFLAGS', + 1: 'PA_CONTEXT_NOAUTOSPAWN', + 2: 'PA_CONTEXT_NOFAIL', +} +PA_CONTEXT_NOFLAGS = 0 +PA_CONTEXT_NOAUTOSPAWN = 1 +PA_CONTEXT_NOFAIL = 2 +pa_context_flags = ctypes.c_int # enum +pa_context_flags_t = pa_context_flags +pa_context_flags_t__enumvalues = pa_context_flags__enumvalues +class struct_pa_spawn_api(ctypes.Structure): + pass + +pa_context_connect = _libraries['libpulse.so'] .pa_context_connect +pa_context_connect.restype = ctypes.c_int32 +pa_context_connect.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_flags_t, POINTER_T(struct_pa_spawn_api)] +pa_context_disconnect = _libraries['libpulse.so'] .pa_context_disconnect +pa_context_disconnect.restype = None +pa_context_disconnect.argtypes = [POINTER_T(struct_pa_context)] + +class struct_pa_operation(ctypes.Structure): + pass + +# pa_context_drain = _libraries['libpulse.so'] .pa_context_drain +# pa_context_drain.restype = POINTER_T(struct_pa_operation) +# pa_context_drain.argtypes = [POINTER_T(struct_pa_context), pa_context_notify_cb_t, POINTER_T(None)] +# pa_context_exit_daemon = _libraries['libpulse.so'] .pa_context_exit_daemon +# pa_context_exit_daemon.restype = POINTER_T(struct_pa_operation) +# pa_context_exit_daemon.argtypes = [POINTER_T(struct_pa_context), pa_context_success_cb_t, POINTER_T(None)] +# pa_context_set_default_sink = _libraries['libpulse.so'] .pa_context_set_default_sink +# pa_context_set_default_sink.restype = POINTER_T(struct_pa_operation) +# pa_context_set_default_sink.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_success_cb_t, POINTER_T(None)] +# pa_context_set_default_source = _libraries['libpulse.so'] .pa_context_set_default_source +# pa_context_set_default_source.restype = POINTER_T(struct_pa_operation) +# pa_context_set_default_source.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_success_cb_t, POINTER_T(None)] +# pa_context_is_local = _libraries['libpulse.so'] .pa_context_is_local +# pa_context_is_local.restype = ctypes.c_int32 +# pa_context_is_local.argtypes = [POINTER_T(struct_pa_context)] +# pa_context_set_name = _libraries['libpulse.so'] .pa_context_set_name +# pa_context_set_name.restype = POINTER_T(struct_pa_operation) +# pa_context_set_name.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_success_cb_t, POINTER_T(None)] +# pa_context_get_server = _libraries['libpulse.so'] .pa_context_get_server +# pa_context_get_server.restype = ctypes.c_char_p +# pa_context_get_server.argtypes = [POINTER_T(struct_pa_context)] + +# pa_context_get_protocol_version = _libraries['libpulse.so'] .pa_context_get_protocol_version +# pa_context_get_protocol_version.restype = uint32_t +# pa_context_get_protocol_version.argtypes = [POINTER_T(struct_pa_context)] +# pa_context_get_server_protocol_version = _libraries['libpulse.so'] .pa_context_get_server_protocol_version +# pa_context_get_server_protocol_version.restype = uint32_t +# pa_context_get_server_protocol_version.argtypes = [POINTER_T(struct_pa_context)] +class struct_pa_card_profile_info(ctypes.Structure): + _pack_ = True # source:False + _fields_ = [ + ('name', ctypes.c_char_p), + ('description', ctypes.c_char_p), + ('n_sinks', ctypes.c_uint32), + ('n_sources', ctypes.c_uint32), + ('priority', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ] + +pa_card_profile_info = struct_pa_card_profile_info +class struct_pa_card_profile_info2(ctypes.Structure): + _pack_ = True # source:False + _fields_ = [ + ('name', ctypes.c_char_p), + ('description', ctypes.c_char_p), + ('n_sinks', ctypes.c_uint32), + ('n_sources', ctypes.c_uint32), + ('priority', ctypes.c_uint32), + ('available', ctypes.c_int32), + ] + +pa_card_profile_info2 = struct_pa_card_profile_info2 +class struct_pa_card_port_info(ctypes.Structure): + _pack_ = True # source:False + _fields_ = [ + ('name', ctypes.c_char_p), + ('description', ctypes.c_char_p), + ('priority', ctypes.c_uint32), + ('available', ctypes.c_int32), + ('direction', ctypes.c_int32), + ('n_profiles', ctypes.c_uint32), + ('profiles', POINTER_T(POINTER_T(struct_pa_card_profile_info))), + ('proplist', POINTER_T(struct_pa_proplist)), + ('latency_offset', ctypes.c_int64), + ('profiles2', POINTER_T(POINTER_T(struct_pa_card_profile_info2))), + ] + +pa_card_port_info = struct_pa_card_port_info +class struct_pa_card_info(ctypes.Structure): + _pack_ = True # source:False + _fields_ = [ + ('index', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ('name', ctypes.c_char_p), + ('owner_module', ctypes.c_uint32), + ('PADDING_1', ctypes.c_ubyte * 4), + ('driver', ctypes.c_char_p), + ('n_profiles', ctypes.c_uint32), + ('PADDING_2', ctypes.c_ubyte * 4), + ('profiles', POINTER_T(struct_pa_card_profile_info)), + ('active_profile', POINTER_T(struct_pa_card_profile_info)), + ('proplist', POINTER_T(struct_pa_proplist)), + ('n_ports', ctypes.c_uint32), + ('PADDING_3', ctypes.c_ubyte * 4), + ('ports', POINTER_T(POINTER_T(struct_pa_card_port_info))), + ('profiles2', POINTER_T(POINTER_T(struct_pa_card_profile_info2))), + ('active_profile2', POINTER_T(struct_pa_card_profile_info2)), + ] + +pa_card_info = struct_pa_card_info +pa_card_info_cb_t = ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), POINTER_T(struct_pa_card_info), ctypes.c_int32, POINTER_T(None)) +pa_context_get_card_info_by_index = _libraries['libpulse.so'].pa_context_get_card_info_by_index +pa_context_get_card_info_by_index.restype = POINTER_T(struct_pa_operation) +pa_context_get_card_info_by_index.argtypes = [POINTER_T(struct_pa_context), uint32_t, pa_card_info_cb_t, POINTER_T(None)] + + +pa_context_get_card_info_list = _libraries['libpulse.so'].pa_context_get_card_info_list +pa_context_get_card_info_list.restype = POINTER_T(struct_pa_operation) +pa_context_get_card_info_list.argtypes = [POINTER_T(struct_pa_context), pa_card_info_cb_t, POINTER_T(None)] + + +# values for enumeration 'pa_update_mode' +# pa_update_mode__enumvalues = { +# 0: 'PA_UPDATE_SET', +# 1: 'PA_UPDATE_MERGE', +# 2: 'PA_UPDATE_REPLACE', +# } +# PA_UPDATE_SET = 0 +# PA_UPDATE_MERGE = 1 +# PA_UPDATE_REPLACE = 2 +# pa_update_mode = ctypes.c_int # enum +# pa_update_mode_t = pa_update_mode +# pa_update_mode_t__enumvalues = pa_update_mode__enumvalues +# pa_context_proplist_update = _libraries['libpulse.so'] .pa_context_proplist_update +# pa_context_proplist_update.restype = POINTER_T(struct_pa_operation) +# pa_context_proplist_update.argtypes = [POINTER_T(struct_pa_context), pa_update_mode_t, POINTER_T(struct_pa_proplist), pa_context_success_cb_t, POINTER_T(None)] +# pa_context_proplist_remove = _libraries['libpulse.so'] .pa_context_proplist_remove +# pa_context_proplist_remove.restype = POINTER_T(struct_pa_operation) +# pa_context_proplist_remove.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p * 0, pa_context_success_cb_t, POINTER_T(None)] +# pa_context_get_index = _libraries['libpulse.so'] .pa_context_get_index +# pa_context_get_index.restype = uint32_t +# pa_context_get_index.argtypes = [POINTER_T(struct_pa_context)] +class struct_pa_time_event(ctypes.Structure): + pass + +# pa_usec_t = ctypes.c_uint64 +class struct_timeval(ctypes.Structure): + pass +# +# pa_time_event_cb_t = POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_time_event), POINTER_T(struct_timeval), POINTER_T(None))) +# pa_context_rttime_new = _libraries['libpulse.so'] .pa_context_rttime_new +# pa_context_rttime_new.restype = POINTER_T(struct_pa_time_event) +# pa_context_rttime_new.argtypes = [POINTER_T(struct_pa_context), pa_usec_t, pa_time_event_cb_t, POINTER_T(None)] +# pa_context_rttime_restart = _libraries['libpulse.so'] .pa_context_rttime_restart +# pa_context_rttime_restart.restype = None +# pa_context_rttime_restart.argtypes = [POINTER_T(struct_pa_context), POINTER_T(struct_pa_time_event), pa_usec_t] +class struct_pa_sample_spec(ctypes.Structure): + pass + +# pa_context_get_tile_size = _libraries['libpulse.so'] .pa_context_get_tile_size +# pa_context_get_tile_size.restype = size_t +# pa_context_get_tile_size.argtypes = [POINTER_T(struct_pa_context), POINTER_T(struct_pa_sample_spec)] +# pa_context_load_cookie_from_file = _libraries['libpulse.so'] .pa_context_load_cookie_from_file +# pa_context_load_cookie_from_file.restype = ctypes.c_int32 +# pa_context_load_cookie_from_file.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p] +# struct_pa_spawn_api._pack_ = True # source:False +# struct_pa_spawn_api._fields_ = [ +# ('prefork', POINTER_T(ctypes.CFUNCTYPE(None))), +# ('postfork', POINTER_T(ctypes.CFUNCTYPE(None))), +# ('atfork', POINTER_T(ctypes.CFUNCTYPE(None))), +# ] +# + +# values for enumeration 'pa_io_event_flags' +pa_io_event_flags__enumvalues = { + 0: 'PA_IO_EVENT_NULL', + 1: 'PA_IO_EVENT_INPUT', + 2: 'PA_IO_EVENT_OUTPUT', + 4: 'PA_IO_EVENT_HANGUP', + 8: 'PA_IO_EVENT_ERROR', +} +PA_IO_EVENT_NULL = 0 +PA_IO_EVENT_INPUT = 1 +PA_IO_EVENT_OUTPUT = 2 +PA_IO_EVENT_HANGUP = 4 +PA_IO_EVENT_ERROR = 8 +pa_io_event_flags = ctypes.c_int # enum +class struct_pa_io_event(ctypes.Structure): + pass + +class struct_pa_defer_event(ctypes.Structure): + pass + +struct_pa_mainloop_api._pack_ = True # source:False +struct_pa_mainloop_api._fields_ = [ + ('userdata', POINTER_T(None)), + ('io_new', POINTER_T(ctypes.CFUNCTYPE(POINTER_T(struct_pa_io_event), POINTER_T(struct_pa_mainloop_api), ctypes.c_int32, pa_io_event_flags, POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_io_event), ctypes.c_int32, pa_io_event_flags, POINTER_T(None))), POINTER_T(None)))), + ('io_enable', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_io_event), pa_io_event_flags))), + ('io_free', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_io_event)))), + ('io_set_destroy', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_io_event), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_io_event), POINTER_T(None)))))), + ('time_new', POINTER_T(ctypes.CFUNCTYPE(POINTER_T(struct_pa_time_event), POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_timeval), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_time_event), POINTER_T(struct_timeval), POINTER_T(None))), POINTER_T(None)))), + ('time_restart', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_time_event), POINTER_T(struct_timeval)))), + ('time_free', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_time_event)))), + ('time_set_destroy', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_time_event), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_time_event), POINTER_T(None)))))), + ('defer_new', POINTER_T(ctypes.CFUNCTYPE(POINTER_T(struct_pa_defer_event), POINTER_T(struct_pa_mainloop_api), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_defer_event), POINTER_T(None))), POINTER_T(None)))), + ('defer_enable', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_defer_event), ctypes.c_int32))), + ('defer_free', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_defer_event)))), + ('defer_set_destroy', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_defer_event), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_defer_event), POINTER_T(None)))))), + ('quit', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), ctypes.c_int32))), +] + +class struct_pollfd(ctypes.Structure): + pass + +class struct_pa_mainloop(ctypes.Structure): + pass + +pa_mainloop = struct_pa_mainloop +pa_mainloop_new = _libraries['libpulse.so'] .pa_mainloop_new +pa_mainloop_new.restype = POINTER_T(struct_pa_mainloop) +pa_mainloop_new.argtypes = [] +pa_mainloop_free = _libraries['libpulse.so'] .pa_mainloop_free +pa_mainloop_free.restype = None +pa_mainloop_free.argtypes = [POINTER_T(struct_pa_mainloop)] + +# pa_mainloop_prepare = _libraries['libpulse.so'] .pa_mainloop_prepare +# pa_mainloop_prepare.restype = ctypes.c_int32 +# pa_mainloop_prepare.argtypes = [POINTER_T(struct_pa_mainloop), ctypes.c_int32] +# pa_mainloop_poll = _libraries['libpulse.so'] .pa_mainloop_poll +# pa_mainloop_poll.restype = ctypes.c_int32 +# pa_mainloop_poll.argtypes = [POINTER_T(struct_pa_mainloop)] +# pa_mainloop_dispatch = _libraries['libpulse.so'] .pa_mainloop_dispatch +# pa_mainloop_dispatch.restype = ctypes.c_int32 +# pa_mainloop_dispatch.argtypes = [POINTER_T(struct_pa_mainloop)] +# pa_mainloop_get_retval = _libraries['libpulse.so'] .pa_mainloop_get_retval +# pa_mainloop_get_retval.restype = ctypes.c_int32 +# pa_mainloop_get_retval.argtypes = [POINTER_T(struct_pa_mainloop)] + +pa_mainloop_iterate = _libraries['libpulse.so'] .pa_mainloop_iterate +pa_mainloop_iterate.restype = ctypes.c_int32 +pa_mainloop_iterate.argtypes = [POINTER_T(struct_pa_mainloop), ctypes.c_int32, POINTER_T(ctypes.c_int32)] + +# pa_mainloop_run = _libraries['libpulse.so'] .pa_mainloop_run +# pa_mainloop_run.restype = ctypes.c_int32 +# pa_mainloop_run.argtypes = [POINTER_T(struct_pa_mainloop), POINTER_T(ctypes.c_int32)] +pa_mainloop_get_api = _libraries['libpulse.so'] .pa_mainloop_get_api +pa_mainloop_get_api.restype = POINTER_T(struct_pa_mainloop_api) +pa_mainloop_get_api.argtypes = [POINTER_T(struct_pa_mainloop)] +# pa_mainloop_quit = _libraries['libpulse.so'] .pa_mainloop_quit +# pa_mainloop_quit.restype = None +# pa_mainloop_quit.argtypes = [POINTER_T(struct_pa_mainloop), ctypes.c_int32] +# pa_mainloop_wakeup = _libraries['libpulse.so'] .pa_mainloop_wakeup +# pa_mainloop_wakeup.restype = None +# pa_mainloop_wakeup.argtypes = [POINTER_T(struct_pa_mainloop)] +# pa_poll_func = POINTER_T(ctypes.CFUNCTYPE(ctypes.c_int32, POINTER_T(struct_pollfd), ctypes.c_uint64, ctypes.c_int32, POINTER_T(None))) +# pa_mainloop_set_poll_func = _libraries['libpulse.so'] .pa_mainloop_set_poll_func +# pa_mainloop_set_poll_func.restype = None +# pa_mainloop_set_poll_func.argtypes = [POINTER_T(struct_pa_mainloop), pa_poll_func, POINTER_T(None)] + +pa_operation_unref = _libraries['libpulse.so'] .pa_operation_unref +pa_operation_unref.restype = None +pa_operation_unref.argtypes = [POINTER_T(struct_pa_operation)] + +# values for enumeration 'pa_sample_format' +# pa_sample_format__enumvalues = { +# 0: 'PA_SAMPLE_U8', +# 1: 'PA_SAMPLE_ALAW', +# 2: 'PA_SAMPLE_ULAW', +# 3: 'PA_SAMPLE_S16LE', +# 4: 'PA_SAMPLE_S16BE', +# 5: 'PA_SAMPLE_FLOAT32LE', +# 6: 'PA_SAMPLE_FLOAT32BE', +# 7: 'PA_SAMPLE_S32LE', +# 8: 'PA_SAMPLE_S32BE', +# 9: 'PA_SAMPLE_S24LE', +# 10: 'PA_SAMPLE_S24BE', +# 11: 'PA_SAMPLE_S24_32LE', +# 12: 'PA_SAMPLE_S24_32BE', +# 13: 'PA_SAMPLE_MAX', +# -1: 'PA_SAMPLE_INVALID', +# } +# PA_SAMPLE_U8 = 0 +# PA_SAMPLE_ALAW = 1 +# PA_SAMPLE_ULAW = 2 +# PA_SAMPLE_S16LE = 3 +# PA_SAMPLE_S16BE = 4 +# PA_SAMPLE_FLOAT32LE = 5 +# PA_SAMPLE_FLOAT32BE = 6 +# PA_SAMPLE_S32LE = 7 +# PA_SAMPLE_S32BE = 8 +# PA_SAMPLE_S24LE = 9 +# PA_SAMPLE_S24BE = 10 +# PA_SAMPLE_S24_32LE = 11 +# PA_SAMPLE_S24_32BE = 12 +# PA_SAMPLE_MAX = 13 +# PA_SAMPLE_INVALID = -1 +# pa_sample_format = ctypes.c_int # enum +# struct_pa_sample_spec._pack_ = True # source:False +# struct_pa_sample_spec._fields_ = [ +# ('format', pa_sample_format), +# ('rate', ctypes.c_uint32), +# ('channels', ctypes.c_ubyte), +# ('PADDING_0', ctypes.c_ubyte * 3), +# ] +# +# struct_timeval._pack_ = True # source:False +# struct_timeval._fields_ = [ +# ('tv_sec', ctypes.c_int64), +# ('tv_usec', ctypes.c_int64), +# ] + +pa_proplist_to_string = _libraries['libpulse.so'].pa_proplist_to_string +pa_proplist_to_string.restype = POINTER_T(ctypes.c_char) +pa_proplist_to_string.argtypes = [POINTER_T(struct_pa_proplist)] + +pa_proplist_gets = _libraries['libpulse.so'].pa_proplist_gets +pa_proplist_gets.restype = POINTER_T(ctypes.c_char) +pa_proplist_gets.argtypes = [POINTER_T(struct_pa_proplist), POINTER_T(ctypes.c_char)] +PA_DIRECTION_OUTPUT = 0x0001 +PA_DIRECTION_INPUT = 0x0002 + + +__all__ = \ + ['PA_CONTEXT_AUTHORIZING', 'PA_CONTEXT_CONNECTING', + 'PA_CONTEXT_FAILED', 'PA_CONTEXT_NOAUTOSPAWN', + 'PA_CONTEXT_NOFAIL', 'PA_CONTEXT_NOFLAGS', 'PA_CONTEXT_READY', + 'PA_CONTEXT_SETTING_NAME', 'PA_CONTEXT_TERMINATED', + 'PA_CONTEXT_UNCONNECTED', 'PA_IO_EVENT_ERROR', + 'PA_IO_EVENT_HANGUP', 'PA_IO_EVENT_INPUT', 'PA_IO_EVENT_NULL', + 'PA_IO_EVENT_OUTPUT', 'PA_SAMPLE_ALAW', 'PA_SAMPLE_FLOAT32BE', + 'PA_SAMPLE_FLOAT32LE', 'PA_SAMPLE_INVALID', 'PA_SAMPLE_MAX', + 'PA_SAMPLE_S16BE', 'PA_SAMPLE_S16LE', 'PA_SAMPLE_S24BE', + 'PA_SAMPLE_S24LE', 'PA_SAMPLE_S24_32BE', 'PA_SAMPLE_S24_32LE', + 'PA_SAMPLE_S32BE', 'PA_SAMPLE_S32LE', 'PA_SAMPLE_U8', + 'PA_SAMPLE_ULAW', 'PA_UPDATE_MERGE', 'PA_UPDATE_REPLACE', + 'PA_UPDATE_SET', 'pa_context', 'pa_context_connect', + 'pa_context_disconnect', 'pa_context_drain', 'pa_context_errno', + 'pa_context_event_cb_t', 'pa_context_exit_daemon', + 'pa_context_flags', 'pa_context_flags_t', + 'pa_context_flags_t__enumvalues', 'pa_context_get_index', + 'pa_context_get_protocol_version', 'pa_context_get_server', + 'pa_context_get_server_protocol_version', 'pa_context_get_state', + 'pa_context_get_tile_size', 'pa_context_is_local', + 'pa_context_is_pending', 'pa_context_load_cookie_from_file', + 'pa_context_new', 'pa_context_new_with_proplist', + 'pa_context_notify_cb_t', 'pa_context_proplist_remove', + 'pa_context_proplist_update', 'pa_context_ref', + 'pa_context_rttime_new', 'pa_context_rttime_restart', + 'pa_context_set_default_sink', 'pa_context_set_default_source', + 'pa_context_set_event_callback', 'pa_context_set_name', + 'pa_context_set_state_callback', 'pa_context_state', + 'pa_context_state_t', 'pa_context_state_t__enumvalues', + 'pa_context_success_cb_t', 'pa_context_unref', + 'pa_io_event_flags', 'pa_mainloop', 'pa_mainloop_dispatch', + 'pa_mainloop_free', 'pa_mainloop_get_api', + 'pa_mainloop_get_retval', 'pa_mainloop_iterate', + 'pa_mainloop_new', 'pa_mainloop_poll', 'pa_mainloop_prepare', + 'pa_mainloop_quit', 'pa_mainloop_run', + 'pa_mainloop_set_poll_func', 'pa_mainloop_wakeup', 'pa_poll_func', + 'pa_sample_format', 'pa_time_event_cb_t', 'pa_update_mode', + 'pa_update_mode_t', 'pa_update_mode_t__enumvalues', 'pa_usec_t', + 'size_t', 'struct_pa_context', 'struct_pa_defer_event', + 'struct_pa_io_event', 'struct_pa_mainloop', + 'struct_pa_mainloop_api', 'struct_pa_operation', + 'struct_pa_proplist', 'struct_pa_sample_spec', + 'struct_pa_spawn_api', 'struct_pa_time_event', 'struct_pollfd', + 'struct_timeval', 'uint32_t','pa_proplist_to_string','pa_proplist_gets','PA_DIRECTION_OUTPUT', 'PA_DIRECTION_INPUT'] diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/pa_helper.py b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/pa_helper.py new file mode 100644 index 0000000..6ec79a0 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/extensions/sound-output-device-chooser@kgshank.net/utils/pa_helper.py @@ -0,0 +1,141 @@ +#!/usr/bin/python +############################################################################### + # This program is free software: you can redistribute it and/or modify it under + # the terms of the GNU General Public License as published by the Free Software + # Foundation, either version 3 of the License, or (at your option) any later + # version. + # + # This program is distributed in the hope that it will be useful, but WITHOUT + # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + # details. + # + # You should have received a copy of the GNU General Public License along with + # this program. If not, see . + # + # Original Author: Gopi Sankar Karmegam + ############################################################################## + +import libpulse_introspect as pa +import sys +from ctypes import c_int,byref, c_char_p, cast +import time +from json import dumps + +class PAHelper(): + + _error = { + 'success': False, + 'error': None, + } + _card_op_done = None + _pa_state = pa.PA_CONTEXT_UNCONNECTED + + + def __init__(self): + self._ports = [] + self._cards = {} + self.mainloop = pa.pa_mainloop_new() + self._context = pa.pa_context_new( pa.pa_mainloop_get_api(self.mainloop), b'PAHelper') + self._pa_context_notify_cb_t = pa.pa_context_notify_cb_t(self.pa_context_notify_cb_t) + pa.pa_context_set_state_callback(self._context, self._pa_context_notify_cb_t , None) + pa.pa_context_connect(self._context, None, 0, None) + self._opn_completed = False + + def print_card_info(self, index = None): + operation = None + retVal = c_int() + counter = 0 + + while counter < 10000 and self._opn_completed == False: + counter += 1 + if self._pa_state == pa.PA_CONTEXT_READY and operation == None: + self._pa_card_info_cb_t = pa.pa_card_info_cb_t(self.pa_card_info_cb) +# operation = pa.pa_context_get_card_info_by_index(self._context, +# index, self._pa_card_info_cb_t , None) + operation = pa.pa_context_get_card_info_list(self._context, + self._pa_card_info_cb_t , None) + + pa.pa_mainloop_iterate(self.mainloop, 0, byref(retVal)) + print(dumps({'cards': self._cards, 'ports':self._ports}, indent = 5)) + + try: + if operation: + pa.pa_operation_unref(operation) + + pa.pa_context_disconnect(self._context) + pa.pa_context_unref(self._context) + pa.pa_mainloop_free(self.mainloop) + except: + pass + + def pa_card_info_cb(self, context, card_info, eol, whatever): + + if not card_info or not card_info[0]: + return + + card = card_info[0] + #print (card.index) + card_obj = {} + card_obj['index'] = str(card.index) + self._cards[card.index] = card_obj + card_obj['profiles'] = [] + + card_name = cast(pa.pa_proplist_gets(card.proplist,c_char_p(b'alsa.card_name')),c_char_p) + card_obj['alsa_name'] = card_name.value.decode('utf8') if card_name else '' + description = cast(pa.pa_proplist_gets(card.proplist,c_char_p(b'device.description')),c_char_p) + card_obj['card_description'] = description.value.decode('utf8') if description else '' + + card_obj['name'] = card.name.decode('utf8') if card.name else '' + for k in range(0, card.n_profiles): + if(card.profiles2[k]): + profile = card.profiles2[k].contents + pobj = {} + pobj['name'] = profile.name.decode('utf8') if profile.name else '' + pobj['human_name'] = profile.description.decode('utf8') if profile.description else '' + pobj['available'] = profile.available + card_obj['profiles'].append(pobj) + + card_obj['ports'] = [] + for i in range(0, card.n_ports): + port = card.ports[i].contents +# print ("Port name "+ str(port.name)) + obj = {} + obj['name'] = port.name.decode('utf8') if port.name else '' + obj['human_name'] = port.description.decode('utf8') if port.description else '' + obj['direction'] = 'Output' if (port.direction & pa.PA_DIRECTION_OUTPUT) else 'Input' + obj['available'] = port.available + obj['n_profiles'] = port.n_profiles + obj['profiles'] = [] + obj['card_name'] = card_obj['name'] + obj['card_description'] = card_obj['card_description'] + for j in range(0, port.n_profiles): + if(port.profiles2[j]): + profile = port.profiles2[j].contents +# pobj = {} +# pobj['name'] = profile.name.decode('utf8') if profile.name else '' +# pobj['human_name'] = profile.description.decode('utf8') if profile.description else '' +# pobj['available'] = profile.available +# obj['profiles'].append(pobj) + if profile.name: + obj['profiles'].append(profile.name.decode('utf8')) + + self._ports.append(obj) + card_obj['ports'].append(obj) + + + + self._opn_completed = True + + + def pa_context_notify_cb_t(self, context, userdata): + try: + self._pa_state = pa.pa_context_get_state(context) + + except Exception: + self._pa_state = pa.PA_CONTEXT_FAILED + + +PAHelper().print_card_info() + + diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/gnome b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/gnome new file mode 100644 index 0000000..76933ca --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/gnome @@ -0,0 +1,156 @@ +# Calculate format=dconf dconf=/org/gnome + +[desktop/app-folders] +folder-children=['Utilities', 'YaST', 'Sound & Video', 'Graphics', 'Internet', 'Office', 'System Tools', 'Accessories', 'Settings'] + +[desktop/app-folders/folders/Accessories] +apps=['org.gnome.Extensions.desktop', 'org.gnome.Weather.desktop'] +categories=['Utility'] +name='Utility.directory' +translate=true + +[desktop/app-folders/folders/Graphics] +apps=['zzz-gimp.desktop', 'org.fontforge.FontForge.desktop', 'shotwell.desktop'] +categories=['Graphics'] +name='Graphics.directory' +translate=true + +[desktop/app-folders/folders/Internet] +apps=['org.gnome.Epiphany.desktop', 'org.gajim.Gajim.desktop', 'transmission-gtk.desktop', 'org.remmina.Remmina.desktop', 'spicy-spice-gtk.desktop'] +categories=['Network'] +name='Network.directory' +translate=true + +[desktop/app-folders/folders/Office] +apps=['FBReader.desktop', 'libreoffice-base.desktop', 'libreoffice-calc.desktop', 'libreoffice-draw.desktop', 'libreoffice-impress.desktop', 'libreoffice-math.desktop', 'libreoffice-writer.desktop', 'org.gnome.Contacts.desktop', 'gucharmap.desktop'] +categories=['Office'] +name='Office.directory' +translate=true + +[desktop/app-folders/folders/Settings] +apps=['Gentoo-system-config-printer.desktop', 'org.gnome.Settings.desktop', 'cl-console-gui.desktop', 'nm-connection-editor.desktop'] +categories=['Settings'] +name='SystemSettings.directory' +translate=true + +[desktop/app-folders/folders/Sound & Video] +apps=['brasero.desktop', 'org.gnome.Cheese.desktop', 'org.gnome.SoundJuicer.desktop'] +categories=['AudioVideo'] +name='AudioVideo.directory' +translate=true + +[desktop/app-folders/folders/System Tools] +apps=['gparted.desktop', 'cpu-x-root.desktop', 'cpu-x.desktop', 'virt-manager.desktop', 'ca.desrt.dconf-editor.desktop'] +categories=['System'] +name='System-Tools.directory' +translate=true + +[desktop/app-folders/folders/Utilities] +apps=['gnome-abrt.desktop', 'gnome-system-log.desktop', 'nm-connection-editor.desktop', 'org.gnome.baobab.desktop', 'org.gnome.Connections.desktop', 'org.gnome.DejaDup.desktop', 'org.gnome.Dictionary.desktop', 'org.gnome.DiskUtility.desktop', 'org.gnome.eog.desktop', 'org.gnome.Evince.desktop', 'org.gnome.FileRoller.desktop', 'org.gnome.fonts.desktop', 'org.gnome.seahorse.Application.desktop', 'org.gnome.tweaks.desktop', 'org.gnome.Usage.desktop', 'vinagre.desktop', 'gnome-system-monitor.desktop', 'simple-scan.desktop'] +categories=['X-GNOME-Utilities'] +name='X-GNOME-Utilities.directory' +translate=true + +[desktop/app-folders/folders/YaST] +categories=['X-SuSE-YaST'] +name='suse-yast.directory' +translate=true + +[desktop/background] +color-shading-type='solid' +picture-options='zoom' +picture-uri='file:///usr/share/backgrounds/calculate/Calculate%20Linux%2011%20Blue.jpg' +picture-uri-dark='file:///usr/share/backgrounds/calculate/Calculate%20Linux%2011%20Brown.jpg' +primary-color='#000000' +secondary-color='#000000' + +[desktop/input-sources] +sources=[('xkb', 'us'), ('xkb', 'ru')] +xkb-options=['grp:alt_shift_toggle'] + +[desktop/interface] +color-scheme='prefer-dark' +cursor-theme='Adwaita' +enable-animations=true +font-antialiasing='grayscale' +font-hinting='slight' +gtk-theme='Adwaita-dark' +icon-theme='Adwaita' + +[desktop/privacy] +disable-microphone=false + +[desktop/screensaver] +color-shading-type='solid' +picture-options='zoom' +picture-uri='file:///usr/share/backgrounds/calculate/Calculate%20Linux%2015.jpg' +primary-color='#000000' +secondary-color='#000000' + +[desktop/session] +idle-delay=uint32 900 + +[desktop/wm/preferences] +button-layout='appmenu:minimize,maximize,close' + +[gedit/preferences/editor] +scheme='oblivion' +wrap-last-split-mode='word' + +[shell] +app-picker-layout=[{'Sound & Video': <{'position': <0>}>, 'Graphics': <{'position': <1>}>, 'Internet': <{'position': <2>}>, 'Office': <{'position': <3>}>, 'System Tools': <{'position': <4>}>, 'Accessories': <{'position': <5>}>, 'Utilities': <{'position': <6>}>, 'Settings': <{'position': <7>}>}] +disable-user-extensions=false +enabled-extensions=['user-theme@gnome-shell-extensions.gcampax.github.com', 'appindicatorsupport@rgcjonas.gmail.com', 'tweaks-system-menu@extensions.gnome-shell.fifi.org', 'applications-overview-tooltip@RaphaelRochet', 'ControlBlurEffectOnLockScreen@pratap.fastmail.fm', 'dash-to-dock@micxgx.gmail.com', 'MaximizeToEmptyWorkspace-extension@kaisersite.de', 'no-overview@fthx', 'ding@rastersoft.com', 'RemoveAppMenu@Dragon8oy.com', 'blur-my-shell@aunetx'] +favorite-apps=['firefox.desktop', 'org.gnome.Evolution.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Polari.desktop', 'libreoffice-startcenter.desktop', 'org.gnome.Calculator.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Music.desktop', 'org.gnome.Totem.desktop', 'org.gnome.gedit.desktop', 'org.gnome.Terminal.desktop', 'org.gnome.Nautilus.desktop', 'cl-console-gui-update.desktop'] + +[shell/extensions/blur-my-shell/applications] +blur=false + +[shell/extensions/blur-my-shell/dash-to-dock] +blur=false + +[shell/extensions/blur-my-shell/overview] +blur=true +brightness=0.80000000000000004 +customize=true +style-components=1 + +[shell/extensions/blur-my-shell/panel] +blur=true +brightness=0.68000000000000005 +customize=true +override-background-dynamically=true +static-blur=true +style-panel=0 +unblur-dynamically=true +unblur-in-overview=false + +[shell/extensions/dash-to-dock] +apply-custom-theme=false +background-opacity=0.80000000000000004 +custom-background-color=false +custom-theme-shrink=true +dash-max-icon-size=42 +dock-position='BOTTOM' +height-fraction=0.90000000000000002 +preferred-monitor=-2 +show-apps-at-top=false +transparency-mode='DYNAMIC' + +[shell/extensions/dash-to-panel] +available-monitors=[0] + +[shell/extensions/ding] +show-home=false +show-trash=false +show-volumes=false + +[shell/extensions/shutdowntimer-deminder] +preferences-selected-page-value=4 +shutdown-timestamp-value=-1 + +[terminal/legacy] +theme-variant='dark' + +[tweaks] +show-extensions-notice=false diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/ini.env b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/ini.env new file mode 100644 index 0000000..18695b7 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/ini.env @@ -0,0 +1,11 @@ +# Calculate format=samba path=~/.calculate + +[ver] +#?pkg(gnome-base/gnome-shell)>=40# +gnome = 40.0 +#!pkg# +gnome = 3.0 +#pkg# + +[update] +gnome = on diff --git a/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/user-folders.lst b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/user-folders.lst new file mode 100644 index 0000000..ad40ec2 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/2-user/gnome-base/Gnome-40.0/user-folders.lst @@ -0,0 +1 @@ +# Calculate path=~/.local/share/backgrounds diff --git a/profiles/templates/6_ac_desktop_profile/README-eng.txt b/profiles/templates/6_ac_desktop_profile/README-eng.txt new file mode 100644 index 0000000..228e706 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/README-eng.txt @@ -0,0 +1,8 @@ +# Calculate append=skip + +The ac_desktop_profile event: +- package installation +- user profile configuration + +Action: package configuration within a user profile +env: desktop diff --git a/profiles/templates/6_ac_desktop_profile/README-rus.txt b/profiles/templates/6_ac_desktop_profile/README-rus.txt new file mode 100644 index 0000000..5df4536 --- /dev/null +++ b/profiles/templates/6_ac_desktop_profile/README-rus.txt @@ -0,0 +1,8 @@ +# Calculate append=skip + +Событие ac_desktop_profile: +- установка пакета +- настройка профиля пользователя + +Действие: настройка пакета в профиле пользователя +env: desktop \ No newline at end of file diff --git a/profiles/templates/6_ac_install_configure/.calculate_directory b/profiles/templates/6_ac_install_configure/.calculate_directory new file mode 100644 index 0000000..986581c --- /dev/null +++ b/profiles/templates/6_ac_install_configure/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip env=install ac_install_configure==on diff --git a/profiles/templates/6_ac_install_configure/README-eng.txt b/profiles/templates/6_ac_install_configure/README-eng.txt new file mode 100644 index 0000000..e9f97db --- /dev/null +++ b/profiles/templates/6_ac_install_configure/README-eng.txt @@ -0,0 +1,7 @@ +# Calculate append=skip + +ac_install_configure event: +- System setup with 'cl-setup-*' + +Action: calling templates for system configuration +env: install diff --git a/profiles/templates/6_ac_install_configure/README-rus.txt b/profiles/templates/6_ac_install_configure/README-rus.txt new file mode 100644 index 0000000..82e15c4 --- /dev/null +++ b/profiles/templates/6_ac_install_configure/README-rus.txt @@ -0,0 +1,8 @@ +# Calculate append=skip + +Событие ac_install_configure: +- настройка системы при помощи утилит 'cl-setup-*' + +Действие: Вызовы шаблонов настройки компонентов системы +env: install + diff --git a/profiles/templates/6_ac_install_configure/session b/profiles/templates/6_ac_install_configure/session new file mode 100644 index 0000000..4376773 --- /dev/null +++ b/profiles/templates/6_ac_install_configure/session @@ -0,0 +1,7 @@ +# Calculate format=samba merge=x11-misc/sddm,x11-base/xorg-server,x11-misc/lightdm,gnome-base/gdm cl_setup==session||cl_setup== path=/var/lib/calculate name=calculate.env + +[main] +cl_home_crypt_set = #-cl_install_home_crypt_set-# + +[install] +cl_autologin = #-cl_autologin-# diff --git a/profiles/templates/6_ac_update_sync/.calculate_directory b/profiles/templates/6_ac_update_sync/.calculate_directory new file mode 100644 index 0000000..6cc8a04 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip env=update ac_update_sync==on diff --git a/profiles/templates/6_ac_update_sync/README-eng.txt b/profiles/templates/6_ac_update_sync/README-eng.txt new file mode 100644 index 0000000..2996b91 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/README-eng.txt @@ -0,0 +1,7 @@ +# Calculate append=skip + +The ac_update_sync event: +- Portage syncing + +Action: world update, fix system +env: install diff --git a/profiles/templates/6_ac_update_sync/README-rus.txt b/profiles/templates/6_ac_update_sync/README-rus.txt new file mode 100644 index 0000000..fe3ae65 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/README-rus.txt @@ -0,0 +1,7 @@ +# Calculate append=skip + +Событие ac_update_sync: +- обновление портежей + +Действие: обновление world файла, исправление системы +env: install diff --git a/profiles/templates/6_ac_update_sync/world/.calculate_directory b/profiles/templates/6_ac_update_sync/world/.calculate_directory new file mode 100644 index 0000000..28b07ff --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/.calculate_directory @@ -0,0 +1 @@ +# Calculate path=/var/lib name=portage \ No newline at end of file diff --git a/profiles/templates/6_ac_update_sync/world/0-ini b/profiles/templates/6_ac_update_sync/world/0-ini new file mode 100644 index 0000000..8bf0886 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/0-ini @@ -0,0 +1,4 @@ +# Calculate path=/var/lib/calculate name=ini.env format=samba cl_update_world==rebuild||cl_update_world==merge||ini(gnome-profile.world)== + +[gnome-profile] +world = 20220905 diff --git a/profiles/templates/6_ac_update_sync/world/create/.calculate_directory b/profiles/templates/6_ac_update_sync/world/create/.calculate_directory new file mode 100644 index 0000000..efc7485 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip cl_update_world==merge||cl_update_world==rebuild diff --git a/profiles/templates/6_ac_update_sync/world/create/applications b/profiles/templates/6_ac_update_sync/world/create/applications new file mode 100644 index 0000000..765466c --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/applications @@ -0,0 +1,13 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +app-office/libreoffice +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-text/fbreader +#in# + +#?in(os_linux_pkglist, CLDG)!=# +sys-apps/flatpak +#in# diff --git a/profiles/templates/6_ac_update_sync/world/create/base b/profiles/templates/6_ac_update_sync/world/create/base new file mode 100644 index 0000000..ccad521 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/base @@ -0,0 +1,11 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, calculate)!=# +app-editors/nano +media-fonts/terminus-font +sys-apps/busybox +sys-apps/calculate-toolkit +sys-apps/ifplugd +sys-apps/less +sys-kernel/dracut +#in# diff --git a/profiles/templates/6_ac_update_sync/world/create/decoration b/profiles/templates/6_ac_update_sync/world/create/decoration new file mode 100644 index 0000000..df02c19 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/decoration @@ -0,0 +1,23 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +media-gfx/grub-splashes-calculate +#in# + +#?in(os_linux_pkglist, CLDG)!=# +media-fonts/noto-emoji +media-gfx/calculate-wallpapers +media-gfx/dm-themes-calculate +media-gfx/splash-themes-calculate +x11-themes/calculate-icon-theme +#in# + +#?in(os_linux_pkglist, CLDG)!=# +media-gfx/lightdm-themes-calculate +x11-themes/adwaita-qt +#in# + +#?in(os_linux_pkglist, CLDG)!=# +x11-misc/qt5ct +#in# + diff --git a/profiles/templates/6_ac_update_sync/world/create/gnome b/profiles/templates/6_ac_update_sync/world/create/gnome new file mode 100644 index 0000000..1dc9bff --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/gnome @@ -0,0 +1,18 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +gnome-base/gnome +gnome-extra/gnome-shell-extension-appindicator +gnome-extra/gnome-shell-extension-applications-overview-tooltip +gnome-extra/gnome-shell-extension-control-blur-effect-on-lock-screen +gnome-extra/gnome-shell-extension-dash-to-dock +gnome-extra/gnome-shell-extension-dash-to-panel +gnome-extra/gnome-shell-extension-desktop-icons-ng +gnome-extra/gnome-shell-extension-maximize-to-empty-workspace +gnome-extra/gnome-shell-extension-no-overview +gnome-extra/gnome-shell-extension-remove-app-menu +gnome-extra/gnome-shell-extension-tweaks-system-menu +gnome-extra/gnome-power-manager +sys-power/power-profiles-daemon +net-irc/polari +#in# diff --git a/profiles/templates/6_ac_update_sync/world/create/graphics b/profiles/templates/6_ac_update_sync/world/create/graphics new file mode 100644 index 0000000..91a9dd0 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/graphics @@ -0,0 +1,10 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +sys-firmware/nvidia-firmware +#in# + +#?in(os_linux_pkglist, CLDG)!=# +media-gfx/imagemagick +#in# + diff --git a/profiles/templates/6_ac_update_sync/world/create/multimedia b/profiles/templates/6_ac_update_sync/world/create/multimedia new file mode 100644 index 0000000..77aa662 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/multimedia @@ -0,0 +1,8 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +media-plugins/alsa-plugins +media-sound/alsa-utils +media-sound/bluez-alsa +sys-firmware/sof-firmware +#in# diff --git a/profiles/templates/6_ac_update_sync/world/create/netapps b/profiles/templates/6_ac_update_sync/world/create/netapps new file mode 100644 index 0000000..dad7c0e --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/netapps @@ -0,0 +1,22 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +app-text/wgetpaste +net-analyzer/nmap +net-analyzer/traceroute +net-dns/bind-tools +net-misc/ntp +net-misc/whois +#in# + +#?in(os_linux_pkglist, CLDG)!=# +www-client/firefox +#in# + +#?in(os_linux_pkglist, CLDG)!=# +net-im/gajim +net-misc/remmina +net-p2p/transmission +x11-misc/x11vnc +#in# + diff --git a/profiles/templates/6_ac_update_sync/world/create/network b/profiles/templates/6_ac_update_sync/world/create/network new file mode 100644 index 0000000..b2ad828 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/network @@ -0,0 +1,17 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +net-dialup/pptpclient +net-dialup/rp-pppoe +net-dialup/xl2tpd +net-firewall/shorewall +#in# + +#?in(os_linux_pkglist, CLDG)!=# +net-vpn/networkmanager-l2tp +net-vpn/networkmanager-openvpn +net-vpn/networkmanager-pptp +net-vpn/networkmanager-vpnc +net-vpn/networkmanager-wireguard +#in# + diff --git a/profiles/templates/6_ac_update_sync/world/create/printer b/profiles/templates/6_ac_update_sync/world/create/printer new file mode 100644 index 0000000..9fde16e --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/printer @@ -0,0 +1,22 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +media-gfx/epsonscan2 +net-print/cndrvcups-common-lb +net-print/cnijfilter2 +net-print/cups +net-print/epson-inkjet-printer-escpr +net-print/foomatic-db-engine +net-print/gutenprint +net-print/hplip +net-print/hplip-plugin +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-admin/system-config-printer +#in# + + +#?in(os_linux_pkglist, CLDG)!=# +media-gfx/simple-scan +#in# diff --git a/profiles/templates/6_ac_update_sync/world/create/tools b/profiles/templates/6_ac_update_sync/world/create/tools new file mode 100644 index 0000000..63593ef --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/tools @@ -0,0 +1,87 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +app-arch/lbzip2 +app-arch/pigz +app-misc/tmux +app-text/tree +net-misc/dhcp +sys-auth/pam_update +sys-fs/btrfs-progs +sys-fs/cryptsetup +sys-fs/f2fs-tools +sys-fs/reiserfsprogs +sys-fs/xfsprogs +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-admin/logrotate +app-admin/syslog-ng +sys-apps/ethtool +sys-apps/usbutils +sys-process/cronie +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-editors/vim +app-vim/colorschemes +sys-apps/inxi +sys-fs/mdadm +sys-process/htop +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-admin/hddtemp +app-admin/sudo +app-admin/testdisk +app-cdr/cdrtools +app-cdr/dvd+rw-tools +app-misc/mc +app-portage/portage-utils +sys-apps/acl +sys-apps/dmidecode +sys-apps/lm-sensors +sys-apps/memtest86+ +sys-apps/pciutils +sys-apps/pv +sys-apps/smartmontools +sys-fs/dmraid +sys-fs/dosfstools +sys-fs/mtools +sys-fs/ncdu +sys-process/lsof +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-arch/p7zip +app-arch/rar +app-arch/unzip +sys-apps/hdparm +sys-apps/keyexec +sys-apps/pcmciautils +sys-apps/usb_modeswitch +sys-fs/exfatprogs +sys-fs/ntfs3g +sys-power/acpi +sys-power/acpid +sys-power/cpupower +sys-power/powernowd +sys-power/powertop +#in# + +#?in(os_linux_pkglist, CLDG)!=# +sys-power/upower +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-pda/usbmuxd +dev-python/gst-python +sys-block/gparted +#для корректной поддержки мультимедиа клавиатур +x11-misc/wmctrl +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-portage/cpuid2cpuflags +app-misc/resolve-march-native +#in# diff --git a/profiles/templates/6_ac_update_sync/world/create/wireless b/profiles/templates/6_ac_update_sync/world/create/wireless new file mode 100644 index 0000000..5dc9c58 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/wireless @@ -0,0 +1,15 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +net-wireless/broadcom-sta +net-wireless/rtl8814au +net-wireless/rtl8821ce +net-wireless/rtl8821cu +net-wireless/rtl88x2bu +net-wireless/wireless-tools +net-wireless/wpa_supplicant +sys-firmware/b43-firmware +sys-firmware/ipw2100-firmware +sys-firmware/ipw2200-firmware +#in# + diff --git a/profiles/templates/6_ac_update_sync/world/create/xorg b/profiles/templates/6_ac_update_sync/world/create/xorg new file mode 100644 index 0000000..846df85 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/create/xorg @@ -0,0 +1,13 @@ +# Calculate name=world format=world + +#?in(os_linux_pkglist, CLDG)!=# +app-misc/xorg-meta +#in# + +#?in(os_linux_pkglist, CLDG)!=# +app-i18n/uim +#in# + +#?in(os_linux_pkglist, CLDG)!=# +x11-misc/lightdm +#in# diff --git a/profiles/templates/6_ac_update_sync/world/update/.calculate_directory b/profiles/templates/6_ac_update_sync/world/update/.calculate_directory new file mode 100644 index 0000000..06d9075 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/update/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip cl_update_world!=merge&&cl_update_world!=rebuild diff --git a/profiles/templates/6_ac_update_sync/world/update/2022/.calculate_directory b/profiles/templates/6_ac_update_sync/world/update/2022/.calculate_directory new file mode 100644 index 0000000..60d90d1 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/update/2022/.calculate_directory @@ -0,0 +1 @@ +# Calculate append=skip ini(overlay-distros.world)<20230101 diff --git a/profiles/templates/6_ac_update_sync/world/update/2022/20220204 b/profiles/templates/6_ac_update_sync/world/update/2022/20220204 new file mode 100644 index 0000000..059ba7b --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/update/2022/20220204 @@ -0,0 +1,5 @@ +# Calculate format=world name=world ini(overlay-distros.world)<#-cut()-# + +#-ini(overlay-distros.world,#-cut()-#)-# + +!media-gfx/utsushi diff --git a/profiles/templates/6_ac_update_sync/world/update/2022/20220420 b/profiles/templates/6_ac_update_sync/world/update/2022/20220420 new file mode 100644 index 0000000..72a1baf --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/update/2022/20220420 @@ -0,0 +1,5 @@ +# Calculate format=world name=world ini(overlay-distros.world)<#-cut()-# + +#-ini(overlay-distros.world,#-cut()-#)-# + +!net-misc/vinagre diff --git a/profiles/templates/6_ac_update_sync/world/update/2022/20220805 b/profiles/templates/6_ac_update_sync/world/update/2022/20220805 new file mode 100644 index 0000000..3b30621 --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/update/2022/20220805 @@ -0,0 +1,5 @@ +# Calculate format=world name=world ini(overlay-distros.world)<#-cut()-# + +#-ini(overlay-distros.world,#-cut()-#)-# + +!sys-process/cpu-x diff --git a/profiles/templates/6_ac_update_sync/world/update/2022/20220905 b/profiles/templates/6_ac_update_sync/world/update/2022/20220905 new file mode 100644 index 0000000..a3ae3bd --- /dev/null +++ b/profiles/templates/6_ac_update_sync/world/update/2022/20220905 @@ -0,0 +1,7 @@ +# Calculate format=world name=world ini(overlay-distros.world)<#-cut()-# + +#-ini(overlay-distros.world,#-cut()-#)-# + +#?in(os_linux_pkglist, CLDG)!=# +media-gfx/epsonscan2 +#in# diff --git a/sys-power/power-profiles-daemon/Manifest b/sys-power/power-profiles-daemon/Manifest new file mode 100644 index 0000000..0c8ccb6 --- /dev/null +++ b/sys-power/power-profiles-daemon/Manifest @@ -0,0 +1,7 @@ +AUX power-profiles-daemon.confd 49 BLAKE2B 22d24c4826d99e27dfe3fd7ece09af8e610c09fac6e3cd85bcec976a0cae52eac244383fc9606546e3dd08b0ba0207cccac9e035b25ffcbb46b4c81c5d81ec9f SHA512 6f8fdcc7f7cd3e8d0aea8a61befc168dcf3e5701c9b814de72b47b95f5280e1c2a646b7f45a68895c73a9625a9b5cb379233b1935fd2a6a39427cff2160fe323 +AUX power-profiles-daemon.initd 299 BLAKE2B c5af2c1b1a899d0497a093ecf33c6e9c25c97005f94903720847c2cd65451196446ed3705f15dba2a53e2991c4c2f2944c9ffa1aca9431ab59d7e2308e4ddbeb SHA512 6dea5b8b7b4f28a4379d97983e76bbc89210d8685735d1d3ea5c1a75c2f5f37899ef17fc5d5bedadc859d29a69927faa9b55356af2bdac15c250c57cfefaf4c4 +AUX power-profiles-daemon.tmpfiles 58 BLAKE2B 4448feb0622ee95017b38dd0cc54a012df20132d4e409dc80ddea2137132892c3d596f752829b5644dc5f4aa420a6f0b050824e775881920982b96fdd9783ee5 SHA512 35a32bb666e3bc84c304823775e4671b736fdaf07f74ee0806e6c201edbd9c76121d11e96457eb1a126136c7ba4d2516aa9f691d24813da62c06c7da39519199 +DIST power-profiles-daemon-0.11.1.tar.gz 54336 BLAKE2B 53514a3de851da349b39e0261a1ce4cdd7e3e62ed08d1ed7374518132e1f5ce2230ae869c34c7461bcdaf4eb89b9d78360526ac7e21c525c09de31bd19503ab4 SHA512 0fedb425675b153897b2e257fd71b37bb26f3fde849b5e9f6c972feb54a2d80bf6584322ff0a4edd1f2bab67d62136924491be47ea391ca263f40a92a86ab4e4 +DIST power-profiles-daemon-0.12.tar.gz 55705 BLAKE2B 7e78744186d1175d7dc67e3fe84481f68e14ed409639a44bd834ffae820b0828428271360f4f7faa0e2c2323f2ce4d1061e1b260b74aaf5da5cd35881def4a6f SHA512 d6645432751cbf94166307d2d3f982a598c28c0541bda666bc04c2da68ca7d0a129209312a9e6437fe80b786d7040ea34e5e921bc23f0a8d554f72fac1aada5a +EBUILD power-profiles-daemon-0.11.1.ebuild 1285 BLAKE2B 64459bf89380a5f3ad6f2e9df3970d154ea00022767edbe56ae40711e4d0d50855a0036ebc8cd8fdf3e8bb8e902cfb6d1bb787dc986f9333781428eea3f56b14 SHA512 50b29424434b34fca29a45f01c82ace40036c36a5d3e6d425dc471718d60266fbf913b3f01e06a225545218908c100f8f6451da768b46028d0f10a4ea861d3a8 +EBUILD power-profiles-daemon-0.12.ebuild 1285 BLAKE2B 64459bf89380a5f3ad6f2e9df3970d154ea00022767edbe56ae40711e4d0d50855a0036ebc8cd8fdf3e8bb8e902cfb6d1bb787dc986f9333781428eea3f56b14 SHA512 50b29424434b34fca29a45f01c82ace40036c36a5d3e6d425dc471718d60266fbf913b3f01e06a225545218908c100f8f6451da768b46028d0f10a4ea861d3a8 diff --git a/sys-power/power-profiles-daemon/files/power-profiles-daemon.confd b/sys-power/power-profiles-daemon/files/power-profiles-daemon.confd new file mode 100644 index 0000000..de3fd31 --- /dev/null +++ b/sys-power/power-profiles-daemon/files/power-profiles-daemon.confd @@ -0,0 +1,3 @@ +# /etc/conf.d/power-profiles-daemon + +#PPDARGS="" diff --git a/sys-power/power-profiles-daemon/files/power-profiles-daemon.initd b/sys-power/power-profiles-daemon/files/power-profiles-daemon.initd new file mode 100644 index 0000000..d483e82 --- /dev/null +++ b/sys-power/power-profiles-daemon/files/power-profiles-daemon.initd @@ -0,0 +1,13 @@ +#!/sbin/openrc-run +# Copyright 2022 Calculate Linux by jksf +# Distributed under the terms of the GNU General Public License v2 + +command="/usr/libexec/power-profiles-daemon" +command_args="${PPDARGS}" +supervisor="supervise-daemon" +command_args_foreground="" + +depend() { + use clock logger + need dbus +} diff --git a/sys-power/power-profiles-daemon/files/power-profiles-daemon.tmpfiles b/sys-power/power-profiles-daemon/files/power-profiles-daemon.tmpfiles new file mode 100644 index 0000000..8b8c70d --- /dev/null +++ b/sys-power/power-profiles-daemon/files/power-profiles-daemon.tmpfiles @@ -0,0 +1 @@ +f /var/lib/power-profiles-daemon/state.ini 0644 root root diff --git a/sys-power/power-profiles-daemon/power-profiles-daemon-0.11.1.ebuild b/sys-power/power-profiles-daemon/power-profiles-daemon-0.11.1.ebuild new file mode 100644 index 0000000..9600602 --- /dev/null +++ b/sys-power/power-profiles-daemon/power-profiles-daemon-0.11.1.ebuild @@ -0,0 +1,50 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +inherit meson systemd + +DESCRIPTION="Makes power profiles handling available over D-Bus." +HOMEPAGE="https://gitlab.freedesktop.org/hadess/power-profiles-daemon" +SRC_URI="https://gitlab.freedesktop.org/hadess/${PN}/-/archive/${PV}/${PN}-${PV}.tar.gz" + +LICENSE="GPL-3+" +SLOT="0" +IUSE="doc" + +KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~riscv ~x86" + +BDEPEND=">=dev-libs/libgudev-234 + >=sys-auth/polkit-0.114 + sys-power/upower + dev-util/umockdev + dev-python/python-dbusmock +" +DEPEND="${BDEPEND}" + +src_configure() { + local emesonargs=( + $(meson_use doc gtk_doc) + -Dsystemdsystemunitdir=$(systemd_get_systemunitdir) + ) + meson_src_configure +} + +src_install() { + meson_src_install + + exeinto /etc/init.d/ + newexe "${FILESDIR}/power-profiles-daemon.initd" power-profiles-daemon + + exeinto /etc/conf.d/ + newexe "${FILESDIR}/power-profiles-daemon.confd" power-profiles-daemon + + exeinto /usr/lib/tmpfiles.d/ + newexe "${FILESDIR}/power-profiles-daemon.tmpfiles" power-profiles-daemon.conf +} + +pkg_postinst() { + ewarn "Don't forget to enable \"${PN}\" service, by runnning:" + ewarn "rc-update add ${PN} default && rc-service ${PN} start" +} diff --git a/sys-power/power-profiles-daemon/power-profiles-daemon-0.12.ebuild b/sys-power/power-profiles-daemon/power-profiles-daemon-0.12.ebuild new file mode 100644 index 0000000..9600602 --- /dev/null +++ b/sys-power/power-profiles-daemon/power-profiles-daemon-0.12.ebuild @@ -0,0 +1,50 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +inherit meson systemd + +DESCRIPTION="Makes power profiles handling available over D-Bus." +HOMEPAGE="https://gitlab.freedesktop.org/hadess/power-profiles-daemon" +SRC_URI="https://gitlab.freedesktop.org/hadess/${PN}/-/archive/${PV}/${PN}-${PV}.tar.gz" + +LICENSE="GPL-3+" +SLOT="0" +IUSE="doc" + +KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~riscv ~x86" + +BDEPEND=">=dev-libs/libgudev-234 + >=sys-auth/polkit-0.114 + sys-power/upower + dev-util/umockdev + dev-python/python-dbusmock +" +DEPEND="${BDEPEND}" + +src_configure() { + local emesonargs=( + $(meson_use doc gtk_doc) + -Dsystemdsystemunitdir=$(systemd_get_systemunitdir) + ) + meson_src_configure +} + +src_install() { + meson_src_install + + exeinto /etc/init.d/ + newexe "${FILESDIR}/power-profiles-daemon.initd" power-profiles-daemon + + exeinto /etc/conf.d/ + newexe "${FILESDIR}/power-profiles-daemon.confd" power-profiles-daemon + + exeinto /usr/lib/tmpfiles.d/ + newexe "${FILESDIR}/power-profiles-daemon.tmpfiles" power-profiles-daemon.conf +} + +pkg_postinst() { + ewarn "Don't forget to enable \"${PN}\" service, by runnning:" + ewarn "rc-update add ${PN} default && rc-service ${PN} start" +}