3115 Commits

Author SHA1 Message Date
end-4 df0c7bbbd6 Update rules.conf 2025-11-12 21:49:12 +01:00
end-4 7bfbf011d2 taskbar: middle click to launch new instance 2025-11-12 21:40:21 +01:00
end-4 945c6a0782 wbar: add tooltip and stuff 2025-11-12 21:38:30 +01:00
end-4 20cae142d7 fix widget button when on the left 2025-11-12 00:16:32 +01:00
end-4 20e1f0e0bb taskbar: window previews 2025-11-12 00:09:22 +01:00
end-4 a412688af2 add bg, taskbar items 2025-11-11 20:23:09 +01:00
end-4 dec65aea17 update hyprland config 2025-11-11 00:03:19 +01:00
end-4 cbcb8cf8e1 wbar: more interactions 2025-11-11 00:01:57 +01:00
end-4 fdcb95b8a4 wbar: add widgets, taskview, light theme 2025-11-10 23:41:15 +01:00
end-4 694eaccfbf add start and search icons 2025-11-10 22:48:04 +01:00
end-4 42919c59ec wbar: add volume and battery icons 2025-11-10 21:36:08 +01:00
end-4 58980959aa init waffles 2025-11-10 20:45:38 +01:00
clsty f98c422254 Comment hyprctl reload (#2427 #2200) 2025-11-10 21:20:48 +08:00
clsty 1cfeff8b10 Improve 3.files-legacy.sh 2025-11-10 21:14:23 +08:00
clsty 3cc68b29da Improve format in install-deps 2025-11-10 20:34:07 +08:00
clsty 3b212c454d Update setups.sh 2025-11-10 20:30:07 +08:00
clsty b5ddc36d5e Improve dist-determine.sh 2025-11-10 19:45:36 +08:00
Celestial.y 38586f0efc Re-add version lock for quickshell-git. (#2414) 2025-11-10 19:23:55 +08:00
clsty 0462ee5e56 Fix versionlock position 2025-11-10 19:18:31 +08:00
clsty 711fb48e37 Improve handle deprecated deps logic (#2425) 2025-11-10 18:32:54 +08:00
Celestial.y 6d4ea704d6 fix: Remove deprecated hyprland-qtutils package (#2424) 2025-11-10 16:16:27 +08:00
dancincomrade 39ed0e472a fix: remove deprecated hyprland-qtutils package as part of install script 2025-11-10 15:32:53 +08:00
Celestial.y a54a8d8daf Gentoo Updates (#2371) 2025-11-10 14:51:31 +08:00
jwihardi 80d62c438f Merge pull request #5 from jwihardi/gentoo-support
Gentoo support
2025-11-10 01:26:11 -05:00
jwihardi 61b89de945 deleted setup and modified .local chown 2025-11-10 01:23:28 -05:00
jwihardi c812e9c8af forgot backlash 2025-11-10 00:53:07 -05:00
Celestial.y d001bc1269 Add a TODO in 1-issue.yml 2025-11-10 11:25:18 +08:00
clsty 98d2c4f881 Introduce OS_GROUP_ID 2025-11-10 10:38:14 +08:00
jwihardi 4396079c28 added chown for .local 2025-11-09 20:47:27 -05:00
jwihardi e10ad1ed71 updated setup, don't need chown 2025-11-09 20:37:42 -05:00
clsty 051accbe2f Update dist-gentoo/README 2025-11-10 09:05:31 +08:00
clsty 74941d15bf Not use setups-selector but 2.setups.sh 2025-11-10 08:56:07 +08:00
jwihardi cf1ea9e3d9 updated useflags to not be live for hypr stuff 2025-11-09 19:01:36 -05:00
jwihardi 3dd1264a12 removed hyprland custom ebuilds - part 2 2025-11-09 19:00:12 -05:00
jwihardi dbb8d015e8 removed hyprland custom ebuilds 2025-11-09 18:57:56 -05:00
jwihardi 13892a01e1 added quickshell dependencies 2025-11-09 18:49:58 -05:00
end-4 fb7dbaa187 add missing dock loading extra condition 2025-11-09 23:33:39 +01:00
end-4 2c4668bcb0 move panel enable/disable to config 2025-11-09 23:31:51 +01:00
jwihardi d0e2c69de3 Merge branch 'end-4:main' into main 2025-11-09 17:16:12 -05:00
jwihardi 3a64eae028 added adw-gtk3 keyword 2025-11-09 17:15:35 -05:00
Celestial.y 284bb084c6 Update pkgrel in PKGBUILD 2025-11-10 01:49:49 +08:00
end-4 14c115f80a background: add option to only show clock when locked (#2387) 2025-11-09 13:57:29 +01:00
end-4 8b5a790d54 increase overlay clickthru opacity, disable cheatsheet split btns 2025-11-09 13:14:25 +01:00
end-4 e6a19a6afb format 2025-11-09 13:13:47 +01:00
end-4 781af1d420 fix some unqualified access 2025-11-09 13:13:43 +01:00
end-4 baa3c2a773 overlay: add kurukuru 2025-11-09 12:58:48 +01:00
end-4 8f4190a939 overlay: refractor widget background 2025-11-09 12:58:10 +01:00
end-4 696ff4298f BooruImage: refractor image downloader proc 2025-11-09 12:57:05 +01:00
end-4 f2462eb1b4 overlay: add battery level 2025-11-09 11:12:18 +01:00
end-4 53768a6885 qs: move panels into modules/ii 2025-11-09 08:58:56 +01:00
ririko6z 5db16e6245 Merge branch 'end-4:main' into fedora 2025-11-09 13:58:35 +08:00
Elysia dda0a228cf Re-add version lock. 2025-11-09 13:47:41 +08:00
Celestial.y f678a55e6a fix: Change quickshell-git and hyprland-qt-support to local builds. (#2412) 2025-11-09 13:31:21 +08:00
Elysia b322af7051 Fixed a minor issue 2025-11-09 13:07:35 +08:00
Elysia 7236d2f50b revision. 2025-11-09 12:39:16 +08:00
Elysia 87f5bc5870 Change hyprland-qt-support to local build 2025-11-09 12:33:38 +08:00
Elysia 3187239175 Change quickshell-git to local build 2025-11-09 12:33:17 +08:00
jwihardi 09fd61c71d added roboto-flex dependency 2025-11-08 23:07:51 -05:00
jwihardi c1f84c77dd roboto-flex font 2025-11-08 22:22:32 -05:00
jwihardi 3f242fa298 Merge branch 'end-4:main' into main 2025-11-08 22:18:05 -05:00
clsty c7ac7b5b43 Improve deps-selector 2025-11-09 09:31:15 +08:00
Celestial.y 688a36af58 Improve issue template 2025-11-09 08:33:41 +08:00
Celestial.y 10e1509d5d fix fedora install-deps crashing on hyprland-qt-support step (#2406) 2025-11-09 07:38:43 +08:00
end-4 fc2e51ebbc cheatsheet: use w11 icon for super key by default 2025-11-09 00:05:12 +01:00
end-4 1433fb5412 fix weird volume dialog spacing 2025-11-09 00:00:49 +01:00
end-4 b383635fa8 overlay: fix weird fade 2025-11-08 23:53:51 +01:00
end-4 788c01c242 overlay: make widgets resizable 2025-11-08 23:50:21 +01:00
Jacky b965b50009 fix fedora install-deps crashing on hyprland-qt-support step
fix a missing v function invocation that leads to a crash if the hyprland-qt-support package is already installed
2025-11-08 23:19:20 +01:00
clsty 241f33fb2f Post-PR revision on dist-fedora 2025-11-09 02:24:36 +08:00
clsty f9bc4b1608 Fix dist-fedora setups.sh from modify repo 2025-11-09 02:15:02 +08:00
Celestial.y 0091fce2c1 Provide Fedora support (#2393) 2025-11-09 02:00:50 +08:00
Elysia cf43479530 Dynamically control the version of quickshell. 2025-11-09 01:29:48 +08:00
end-4 d74e385f84 fix undefined warning 2025-11-08 17:26:37 +01:00
end-4 d292a85a5e wallpaper selector: fix file:// being passed to magick script 2025-11-08 17:01:54 +01:00
end-4 3b1d8fd262 make volume device selection use a combobox 2025-11-08 16:48:00 +01:00
end-4 769ed3bf71 fix clock alignment in lock screen (fix #2399) 2025-11-08 14:04:16 +01:00
Celestial.y d10ac9cc74 Update comment 2025-11-08 20:15:46 +08:00
end-4 4bf31544e7 Turkish language support (#2396) 2025-11-08 09:42:42 +01:00
ririko6z 03a149c10e Merge branch 'end-4:main' into fedora 2025-11-08 13:47:13 +08:00
Elysia 5ec8cca5d5 Update README.md 2025-11-08 13:40:02 +08:00
Elysia 44c8de82c7 Adjust the code structure. 2025-11-08 13:39:25 +08:00
Elysia b08a545ece Use a locally built RPM instead of directly modifying it. 2025-11-08 10:48:23 +08:00
Pico 42b9c7c854 added Turkish language support 2025-11-08 03:48:28 +03:00
end-4 994985ecae overlay: recorder: make open folder button work with custom path 2025-11-07 22:13:56 +01:00
end-4 229c9d5e78 overlay: adjust titlebar spacing 2025-11-07 21:50:13 +01:00
end-4 ae52e28afb overlay: adjust default crosshair position 2025-11-07 21:35:50 +01:00
end-4 758d40fc8b overlay: adjust volume mixer padding 2025-11-07 21:33:54 +01:00
jwihardi 601cb3ffbe Merge branch 'end-4:main' into main 2025-11-07 15:32:13 -05:00
jwihardi 9aa869af77 updated hyprland to not use live ebuild 2025-11-07 15:31:48 -05:00
end-4 1d07260fd0 add kb focus border for group buttons 2025-11-07 21:24:37 +01:00
jwihardi fe06c1891f added qt unmasks and keywords 2025-11-07 15:21:22 -05:00
end-4 26f2a9f3fd fix more null warnings 2025-11-07 21:11:11 +01:00
end-4 1cc04e118f overlay: hide some unnecessary buttons 2025-11-07 21:10:21 +01:00
end-4 87181585aa overlay: add config option for clickthrough widget opacity 2025-11-07 21:09:39 +01:00
end-4 a831d393c1 fix some undefined warnings 2025-11-07 21:08:30 +01:00
end-4 1845e59090 Feature (Overlay): MangoHud Fps Limiter widget (#2388) 2025-11-07 21:06:55 +01:00
end-4 3fe8377309 make timer restart instead of start 2025-11-07 21:06:31 +01:00
end-4 20b3d2498e overlay: add delay to focus grab 2025-11-07 21:05:59 +01:00
end-4 917fae6d4f overlay: fps limiter: adjust default position 2025-11-07 20:54:23 +01:00
end-4 a91fe7db30 overlay: fps limiter: use enums for states 2025-11-07 20:49:48 +01:00
end-4 daa4dd7b0f overlay: fps limiter: fix weird container and button size 2025-11-07 20:33:54 +01:00
end-4 cd952729f4 overlay: adjust titlebar-content gap 2025-11-07 18:45:42 +01:00
end-4 843025bc64 overlay: make volume mixer has both output and input 2025-11-07 18:33:32 +01:00
reakjra 40368432e8 Merge branch 'main' into featOverlay/MangoHud-Fps-Limiter 2025-11-07 18:30:42 +01:00
end-4 2c88a71eed overlay: make widgets have proper round corners when pinned 2025-11-07 18:21:59 +01:00
Celestial.y 082f12084d Fix #2200 2025-11-07 23:59:20 +08:00
reakjra 23b471edc2 Fix non-sensical logic, timers and animations. 2025-11-07 16:34:29 +01:00
reakjra e50ea627e8 Fix non-sensical logic, timers and animations. 2025-11-07 16:28:45 +01:00
Celestial.y fd8f569477 Add comment (#2220) 2025-11-07 22:27:44 +08:00
end-4 1766375348 fix weird max cpu freq 2025-11-07 14:00:17 +01:00
Elysia 1a58f1258a Provide Fedora support 2025-11-07 20:40:12 +08:00
end-4 0f867df271 overlay: better default positions 2025-11-07 13:02:34 +01:00
end-4 a27a6deddf overlay: add resource monitor widget 2025-11-07 12:56:44 +01:00
end-4 e5e85db75d refractor secondary tab bar 2025-11-07 12:56:08 +01:00
end-4 96cda9e6dd Customizable keybind display options to Cheatsheet (#2338) 2025-11-07 09:52:25 +01:00
jwihardi fe3c502459 updated ebuilds + licenses 2025-11-07 02:08:40 -05:00
jwihardi e2799414dd Merge branch 'end-4:main' into main 2025-11-07 01:28:10 -05:00
jwihardi fa08f972d6 use new ebuilds 2025-11-07 01:27:45 -05:00
Madjid Taha b06a7ce58e fix merge 2025-11-07 02:42:51 +01:00
clsty a0c5940a94 Use "Han chars" 2025-11-07 06:08:46 +08:00
end-4 3365719a49 tray menu: fix weird popin anim origin point 2025-11-06 23:07:50 +01:00
end-4 6afe810d69 batterypopup: move health to below energy rate 2025-11-06 23:04:42 +01:00
end-4 bf70be7f4a overlay: add recorder widget 2025-11-06 23:02:21 +01:00
end-4 1a4b4b8bef use ipc calls more for compatibility 2025-11-06 22:59:09 +01:00
reakjra 7f49daf422 undo personal edits by mistake 2025-11-06 22:44:40 +01:00
reakjra f4c32f89f2 Added proposed fixes and implemented some animations+error text 2025-11-06 22:41:14 +01:00
end-4 2807bed255 Save paths for screen recording and screenshots (#2354) 2025-11-06 21:56:13 +01:00
end-4 e5e598853f japanese borrows chinese chars... 2025-11-06 21:49:03 +01:00
vaguesyntax 47aa8232f7 fixes 2025-11-06 23:39:32 +03:00
end-4 06c51553ba refractor bar tooltips 2025-11-06 21:35:31 +01:00
end-4 281646ef0c Add battery health to battery popup (#2355) 2025-11-06 21:15:04 +01:00
end-4 2f1c66570f Change battery health icon from 'healing' to 'heart_check' 2025-11-06 21:14:51 +01:00
reakjra 60144ca3de Feature (Overlay): MangoHud Fps Limiter widget 2025-11-06 14:23:13 +01:00
Madjid Taha a0131e5bf8 fix: use end-4 copy in InterfaceConfig 2025-11-06 12:33:29 +01:00
Madjid Taha 4afaa7cc7e Merge branch 'main' into keybinds-settings 2025-11-06 12:30:05 +01:00
end-4 ad9f25c346 weather widget: make number and icon further apart 2025-11-06 11:08:14 +01:00
end-4 6be3fe0c65 overlay: add option for zoom anim and darkening surface 2025-11-06 10:55:33 +01:00
end-4 3bebabd95e settings: extend japenis/roman ws numbers 2025-11-06 10:54:00 +01:00
end-4 6e9f2c14ce clarify overlay widget instructions a bit 2025-11-06 10:38:35 +01:00
end-4 4f68e9e61a add overlay 2025-11-06 10:29:59 +01:00
end-4 56a7e8cbdd right sidebar: refractor volume mixer dialog content 2025-11-06 10:25:45 +01:00
clsty 25a63b593d Fix gh action 2025-11-06 16:56:22 +08:00
clsty 32af8bf257 Fix gh action 2025-11-06 16:49:54 +08:00
end-4 cd0d49032a readme: add warning for noobs 2025-11-05 15:37:44 +01:00
clsty 11f7adc643 Update swaylock color in vianix/hypridle.conf 2025-11-05 21:12:16 +08:00
clsty 6d6fa42857 Move ar/conf.d to ar/fonts.conf (#2384) 2025-11-05 19:34:56 +08:00
clsty d14d170016 Update dist-nix/README 2025-11-05 19:34:03 +08:00
clsty bd04346f16 Enable fontconfig in home.nix (#2384) 2025-11-05 19:31:35 +08:00
end-4 46bd7c785a Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-11-05 12:23:50 +01:00
end-4 520068e523 rename font config file (#2384) 2025-11-05 12:23:44 +01:00
clsty 902c8327d3 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-11-05 19:19:14 +08:00
clsty d497e00474 Update dist-nix/README 2025-11-05 19:18:47 +08:00
end-4 b5e1bcf3be Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-11-05 12:13:53 +01:00
end-4 923841cb56 region selector: add selection padding to target regions 2025-11-05 12:13:46 +01:00
end-4 6ca5175bb0 silent some stupid prints 2025-11-05 12:13:13 +01:00
clsty 9aa6d03f87 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-11-05 18:51:27 +08:00
clsty eff52332b5 Update dist-nix/README 2025-11-05 18:51:09 +08:00
end-4 bf376c8aaa make clock closer to quote 2025-11-05 11:46:52 +01:00
end-4 64f6081b14 config: move quote settings to clock widget subsection 2025-11-05 10:23:20 +01:00
end-4 b3f81f350c reduce persistent low battery warnings 2025-11-05 10:16:08 +01:00
end-4 025a819b63 scale up bg widgets when dragging 2025-11-05 10:15:21 +01:00
end-4 2667751a1c add settings entries for bg widgets 2025-11-05 10:15:06 +01:00
end-4 b1007f2ded make abstractwidget's cursor shape more accurate 2025-11-05 10:14:36 +01:00
end-4 aca19d6903 adjust weather widget size 2025-11-05 10:14:17 +01:00
end-4 52dced17a3 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-11-05 08:52:18 +01:00
clsty a1606c9c23 Update comment 2025-11-05 13:47:09 +08:00
jwihardi 9249034fa6 Merge branch 'end-4:main' into main 2025-11-05 00:06:43 -05:00
jwihardi 1924111d6b added some font ebuilds 2025-11-05 00:06:08 -05:00
clsty 8214e2d052 Update dist-nix/install-deps.sh 2025-11-05 12:17:43 +08:00
clsty 564fd54cdb Update dist-nix (improve install via system PM) 2025-11-05 11:51:47 +08:00
clsty a92bd67957 Update flake.lock 2025-11-05 10:44:48 +08:00
clsty 22469dc5f2 Update dist-nix (use unstable nixpkgs) 2025-11-05 10:40:08 +08:00
clsty 5f4f8980f0 Move Qt deps into Quickshell PKGBUILD 2025-11-05 10:24:21 +08:00
clsty e24630b9be Use qt6 and NixGL wrapper for quickshell 2025-11-05 08:40:05 +08:00
clsty 51076dda88 Update TODO 2025-11-05 07:55:22 +08:00
end-4 37244dc0f7 background: add weather widget
Co-Authored-By: Vague Syntax <173799252+vaguesyntax@users.noreply.github.com>
2025-11-05 00:44:22 +01:00
end-4 c82a2e835b move weather icons to Icons
Co-Authored-By: Vague Syntax <173799252+vaguesyntax@users.noreply.github.com>
2025-11-05 00:43:19 +01:00
end-4 8a35609b0d refractor StyledDropShadow 2025-11-05 00:41:44 +01:00
end-4 1f208125bf remove clock scale option (it has never been good) 2025-11-05 00:41:28 +01:00
end-4 ba6fba447a fix some undefined warnings 2025-11-05 00:40:34 +01:00
clsty c19766c887 Updpate flake.lock 2025-11-05 07:31:04 +08:00
end-4 0e7422c335 make bg clock draggable 2025-11-05 00:07:38 +01:00
end-4 67695c8edb Update OverviewWidget.qml 2025-11-04 22:52:48 +01:00
Madjid Taha ede86dc7a7 fix(cheatsheet): change config keys 2025-11-04 20:55:34 +01:00
Madjid Taha a28945f3ec fix: remove warning unqualified access 2025-11-04 17:51:20 +01:00
Madjid Taha 80275c5adf Merge branch 'end-4:main' into keybinds-settings 2025-11-04 17:21:27 +01:00
EinBowser 31f2184dc6 Removed settings and configs for battery health 2025-11-04 15:58:01 +01:00
end-4 9d830767c7 lock: fix wrong password shake fricks up text field placement (#2368) 2025-11-04 15:10:55 +01:00
end-4 9471223a76 nuke primarytab 2025-11-04 15:08:08 +01:00
end-4 c2942afe8e make regionselection kb focus ondemand 2025-11-04 15:07:44 +01:00
end-4 d8adcce5fb fix(lock): extra checks for fingerprint (#2370) 2025-11-04 15:06:25 +01:00
end-4 b9a7fa4d0d Try kebab over underscores for app icons (#2361) 2025-11-04 15:05:32 +01:00
end-4 7f8265c9e6 auto color scheme: dont use "content" 2025-11-04 14:47:14 +01:00
EinBowser c1ff57c3d0 Don't display when unsupported 2025-11-04 14:20:23 +01:00
clsty 4cad276963 Try fix Hyprland 2025-11-04 21:10:56 +08:00
clsty 5a4b4e6d3c Fix VIANIX 2025-11-04 20:58:46 +08:00
clsty 7440f78069 Update TODO 2025-11-04 20:54:14 +08:00
clsty 38cd1a7169 Update dist-nix 2025-11-04 20:47:35 +08:00
clsty 4443b736d8 Add pkg-config for nix 2025-11-04 15:57:44 +08:00
clsty d509a8777b Update home.nix 2025-11-04 15:47:57 +08:00
clsty 27754e5d03 Update flake.lock 2025-11-04 15:34:41 +08:00
clsty fbb284ae00 Update message in dist-nix 2025-11-04 15:30:54 +08:00
clsty 9bbabc3079 Tweak order of deps in PKGBUILD 2025-11-04 15:23:41 +08:00
clsty 5a3abbe45a Remove non-needed deps in dist-nix 2025-11-04 15:10:03 +08:00
clsty e5283cac5c Remove non-needed deps from dist-arch 2025-11-04 14:59:08 +08:00
clsty eb55f2533d Update dist-nix 2025-11-04 14:54:12 +08:00
jwihardi 352e459d82 Merge pull request #4 from jwihardi/songrec
Songrec
2025-11-04 01:23:29 -05:00
jwihardi 90a4e2128b fixed spacing 2025-11-04 01:20:03 -05:00
jwihardi c79a3e6309 Merge branch 'end-4:main' into songrec 2025-11-04 01:18:17 -05:00
jwihardi a6f1560bce added songrec 2025-11-04 01:17:33 -05:00
clsty a60f917f59 Apply NixGL to quickshell 2025-11-04 13:48:09 +08:00
clsty 0f93784b8a Fix quickshell in dist-nix 2025-11-04 12:40:38 +08:00
clsty 5af7420129 Update dist-nix 2025-11-04 12:33:48 +08:00
clsty 17d2d32bf1 Update dist-nix 2025-11-04 11:45:34 +08:00
clsty 7534509caa Support custom os-release 2025-11-04 11:33:54 +08:00
clsty 76db90af1b Update flake.nix 2025-11-04 11:15:53 +08:00
clsty b4b15a2808 Update home.nix 2025-11-04 10:22:28 +08:00
0blivi0nis f2055d128e fix(lock): extra checks for fingerprint 2025-11-03 17:04:39 -08:00
clsty 534ef6fd7c Add ii_check_PKGBUILD_version() in diagnose 2025-11-04 08:59:40 +08:00
clsty 4cb2c6589d Update home.nix 2025-11-04 07:36:45 +08:00
end-4 f23e9e5da9 antiflashbang: add dedicated toggle, make disabling also restore brightness 2025-11-03 21:48:26 +01:00
end-4 22fb48cd0a overview: add allow not centering icons 2025-11-03 21:36:12 +01:00
end-4 3ae87c8a67 cheatsheet: make more compact 2025-11-03 21:28:35 +01:00
end-4 5d773090eb sidebar: make quick toggle behave more similar to on android 2025-11-03 21:22:05 +01:00
EinBowser c0d64c4630 Forgot to delete unnecessary import 2025-11-03 20:55:17 +01:00
EinBowser a323e32a42 Removed helper script and made workaround in qml 2025-11-03 20:53:40 +01:00
end-4 1703cb24d1 fix left sidebar weird color when detached and transparency enabled 2025-11-03 20:33:03 +01:00
end-4 35ce444c23 right sidebar: fix no alt action toggle not very readable when enabled 2025-11-03 20:08:53 +01:00
clsty 8b2f1c054c Merge remote-tracking branch 'refs/remotes/origin/main' 2025-11-04 01:49:06 +08:00
clsty 56c43aa1e6 Update dist-nix 2025-11-04 01:48:46 +08:00
end-4 2cd705950f readme: update left sidebar screenshot 2025-11-03 18:47:48 +01:00
end-4 467b84d3e2 left sidebar: make content containerized 2025-11-03 18:30:11 +01:00
end-4 4270d2fe56 region selector: make mode selection animated 2025-11-03 18:27:47 +01:00
end-4 519de4f5ba cheatsheet: use toolbar tabbar 2025-11-03 18:11:17 +01:00
end-4 90a6efecbb fix toolbar tabbar undefined warnings 2025-11-03 18:10:39 +01:00
clsty 27e3fd5e13 Remove install-agsv1(); Update home.nix 2025-11-04 00:59:15 +08:00
clsty e55d70fa62 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-11-04 00:45:19 +08:00
clsty b873a1f033 Update home.nix 2025-11-04 00:45:00 +08:00
end-4 0f0bc9d318 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-11-03 17:00:34 +01:00
end-4 087a736d1a left sidebar: toolbar-style tabs 2025-11-03 17:00:28 +01:00
clsty 97fbec551f Tweak indents in PKGBUILDs 2025-11-03 23:58:51 +08:00
end-4 7c974b7fb4 wallpaper selector: adjust quick dir button appearance 2025-11-03 16:55:16 +01:00
end-4 4f712116c2 adjust IconAndTextToolbarButton spacing 2025-11-03 16:54:47 +01:00
end-4 83ce5f3fea refractor animated index pair in workspaces 2025-11-03 16:54:23 +01:00
end-4 7f4a626a83 background: make digital clock quote not italic 2025-11-03 16:54:05 +01:00
clsty 47810c95da Tweak geoclue for via-nix 2025-11-03 23:48:07 +08:00
clsty bd14c73f9b Add vianix-warning() 2025-11-03 20:38:49 +08:00
clsty f368382765 vianix: Install fish instead of zsh 2025-11-03 20:25:23 +08:00
end-4 efd44c421b Limit booru calls for tags to 10 (#2362) 2025-11-03 13:11:27 +01:00
clsty d429d55d16 Prepare for --via-nix fallback to swaylock 2025-11-03 19:58:35 +08:00
André Zanghelini e3fc712e11 Limit booru calls for tags to 10 2025-11-03 01:38:41 -03:00
André Zanghelini f5b495969b try kebab over underscores for app icons 2025-11-03 01:03:58 -03:00
end-4 1ee08fca51 keyringstorage: properly handle keyring fetching (#2108)
- if auto lock enabled, don't do anything and wait for lock password
- not try to overwrite and don't consider loaded when unlocking fails
- retry unlock and re fetch on demand (ai request)
2025-11-02 23:20:01 +01:00
end-4 525108dd95 fix weird blur xray on media controls 2025-11-02 21:49:27 +01:00
end-4 d005f9204c make volume inc keybind more idiot proof 2025-11-02 19:46:31 +01:00
Madjid Taha 6237e117aa Merge branch 'end-4:main' into keybinds-settings 2025-11-02 17:28:40 +01:00
Madjid Taha 0c29167057 try something for the nyx-4 feedback 2025-11-02 17:23:31 +01:00
end-4 e28550b53f add missing animations to android toggles 2025-11-02 08:59:33 +01:00
end-4 c43e163a56 adjust font axes 2025-11-02 08:59:19 +01:00
clsty 31f40ae9ee Update diagnose 2025-11-02 13:21:56 +08:00
end-4 b8051ce2cf make bg clock color match pixel more 2025-11-02 01:07:42 +01:00
end-4 09c637914d use (tweaked) roboto flex for shell text 2025-11-02 00:57:50 +01:00
Madjid Taha 7e283404f3 Merge branch 'end-4:main' into keybinds-settings 2025-11-02 00:40:59 +01:00
EinBowser 8a20824266 Disabled by default 2025-11-01 23:32:08 +01:00
EinBowser 0e63e698f2 Wrong position and forgot an import 2025-11-01 23:26:36 +01:00
EinBowser c2bb57f0bc Merge branch 'end-4:main' into main 2025-11-01 22:50:21 +01:00
EinBowser 6676d5844b changed the script to the right name, added some info and removed unnecesary debug 2025-11-01 22:22:58 +01:00
EinBowser ca7d6c8ae0 Added config toggle to settings 2025-11-01 22:11:39 +01:00
EinBowser b267b74e8b Added battery health and made it configurable 2025-11-01 20:50:39 +01:00
end-4 dcc14a565d adjust urgent notif color 2025-11-01 20:16:22 +01:00
end-4 f96e84ff4a make polkit dialog icon more readable 2025-11-01 20:13:46 +01:00
end-4 41e9c00fa8 fix weird popup blur xray 2025-11-01 20:11:53 +01:00
end-4 85e3fd5e36 fix weird polkit layer anim 2025-11-01 20:11:38 +01:00
end-4 daf7d2c9dc overview: animate search area 2025-11-01 18:43:02 +01:00
end-4 f663837c4e overview: fix focus func conflict with default prop name 2025-11-01 18:32:02 +01:00
end-4 77d9b93887 overview: more rounding 2025-11-01 18:28:25 +01:00
end-4 816d2b8a76 overview: make search highlight more vibrant 2025-11-01 18:27:57 +01:00
Madjid Taha f40cf790af Merge branch 'end-4:main' into keybinds-settings 2025-11-01 16:07:39 +01:00
Vague Syntax 8e1a3d26b1 Update dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml
Co-authored-by: Madjid Taha <1833954+madjidtaha@users.noreply.github.com>
2025-11-01 17:56:38 +03:00
vaguesyntax a240329f22 fix: initialize recording path setting properly 2025-11-01 16:18:02 +03:00
vaguesyntax 6afa6d2142 remove reduntant code 2025-11-01 16:04:04 +03:00
vaguesyntax 0c587415ea tweaks in settings/config 2025-11-01 16:00:32 +03:00
vaguesyntax ace8802480 add screenshot location 2025-11-01 15:55:46 +03:00
Celestial.y 7e1637b810 Fix image path in README.md 2025-11-01 20:47:32 +08:00
vaguesyntax 0fabedb0c4 tweaks in script 2025-11-01 14:41:29 +03:00
vaguesyntax e567f06cef initial commit of record-location 2025-11-01 14:38:16 +03:00
end-4 bf87ed69ce new default wallpaper 2025-11-01 11:40:31 +01:00
end-4 7cb0e4e039 change dark mode button icon to be less confusing 2025-11-01 11:39:36 +01:00
Madjid Taha 510f1b2188 Merge branch 'end-4:main' into keybinds-settings 2025-11-01 04:19:18 +01:00
clsty 1bea1e8c91 Update comment 2025-11-01 10:35:33 +08:00
clsty 9c89099cf1 Update comment in files-exp 2025-11-01 10:18:52 +08:00
clsty efae444942 Update files-exp 2025-11-01 10:16:45 +08:00
clsty 3536e54b50 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-11-01 10:00:35 +08:00
clsty 17984c812f Update files-exp; Rename 3.files.yaml to 3.files-exp.yaml 2025-11-01 09:52:34 +08:00
Celestial.y 09ad926642 Update comment 2025-11-01 09:46:27 +08:00
clsty e3549e639e Update comment 2025-11-01 09:38:47 +08:00
clsty b421691734 Update comment 2025-11-01 09:22:03 +08:00
clsty 835c113416 Move README.md into .github 2025-11-01 08:09:51 +08:00
clsty 2e807806ba Merge remote-tracking branch 'refs/remotes/origin/main' 2025-11-01 01:25:02 +08:00
clsty 2c21eccac3 Update showhelp 2025-11-01 01:22:52 +08:00
end-4 f302da1275 live light/dark switching for gtk4 2025-10-31 18:17:58 +01:00
clsty 82ce9b866f Update showhelp 2025-11-01 01:09:42 +08:00
clsty df23d79e04 Fix outdate detect 2025-11-01 00:47:00 +08:00
clsty 43aae4ee56 Minor update about git_submodule() 2025-10-31 23:07:35 +08:00
clsty 73be5c5f0a Improve message for backup configs 2025-10-31 22:42:16 +08:00
clsty 02c71e9310 Fix submodule update detect logic 2025-10-31 22:40:43 +08:00
clsty f041272302 Detect cmds in checkdeps 2025-10-31 22:38:00 +08:00
Madjid Taha aeb1955947 end-4 feedback 2025-10-31 14:49:07 +01:00
Madjid Taha a0332cb0df add reference to nerdfonts symbol cheat sheet 2025-10-31 14:49:07 +01:00
Madjid Taha 79df7bbeef add google (assistant, chrome, android) keys 2025-10-31 14:49:07 +01:00
Madjid Taha af64052e33 remove super directly override 2025-10-31 14:49:07 +01:00
Madjid Taha fc479c3582 clean some values 2025-10-31 14:49:07 +01:00
Madjid Taha 886e16a1cf add comment and bring back some value 2025-10-31 14:49:07 +01:00
Madjid Taha 367b1b9499 fix keySubstitutions 2025-10-31 14:49:07 +01:00
Madjid Taha c61da40f70 new symbol map 2025-10-31 14:49:07 +01:00
Madjid Taha 90cc63e57a checkbox on tooltip 2025-10-31 14:49:07 +01:00
Madjid Taha fc17f23533 fix typo 2025-10-31 14:49:07 +01:00
Madjid Taha 69fc9d9b35 fix comment pixelSize key 2025-10-31 14:49:07 +01:00
Madjid Taha 533156e0d0 cheatsheet add font size setting and macos like shortcut 2025-10-31 14:49:07 +01:00
Madjid Taha 8c125cccb1 add other symbols 2025-10-31 14:49:07 +01:00
Madjid Taha 3da64f6bc5 fix useMouseSymbol boolean typo 2025-10-31 14:49:07 +01:00
Madjid Taha daa671c6a5 feat: add custom super key icon, mac symbol for mods keys and icon for function keys 2025-10-31 14:49:07 +01:00
end-4 71eb88016e overview: correct💢 the search field's height 2025-10-31 12:13:02 +01:00
end-4 c45166387b Improve music recognition script source management (#2344) 2025-10-31 12:03:47 +01:00
end-4 f4dffe7f37 Merge branch 'main' into patch-2 2025-10-31 11:28:45 +01:00
end-4 df69162f78 deps: add songrec 2025-10-31 11:23:34 +01:00
end-4 e14c9b61d5 fix music recognition script 2025-10-31 10:10:25 +01:00
end-4 b1cc6bd19b overview: fix search bar blur 2025-10-31 09:19:33 +01:00
Celestial.y e02b505ae5 Update feature request template 2025-10-31 13:18:34 +08:00
Celestial.y 6aad5a9581 Update issue template 2025-10-31 13:17:35 +08:00
Yosuke Nishiyama 4b33a10779 Improve music recognition script source management
Refactor source type handling and validation checks.
2025-10-31 04:55:56 +00:00
Celestial.y 6ec202da9e Update command from ags to qs
Can't belive it existed till now and no one ever noticed that.
2025-10-31 09:30:43 +08:00
clsty 54cf1cf821 Update quickshell version for Gentoo 2025-10-31 09:15:42 +08:00
clsty d36966e2d7 Still deprecate install.sh and update.sh anyway; Tidier structure 2025-10-31 09:11:03 +08:00
clsty f01a2a06b5 Fix 3.files-exp.sh; Improve structure 2025-10-31 08:47:41 +08:00
clsty f866ef1fd7 Improve backup functions; Minor fix for checkdeps 2025-10-31 08:30:41 +08:00
end-4 480966f978 overview: add music recognition button to search bar 2025-10-30 23:08:30 +01:00
end-4 b3f06049be add more notif icon 2025-10-30 23:07:27 +01:00
end-4 7887805550 format 2025-10-30 23:07:09 +01:00
end-4 dbd12d3e92 overview: fancier search bar 2025-10-30 22:20:06 +01:00
end-4 db79ecd636 polkit: make sec to dismiss work properly 2025-10-30 22:17:56 +01:00
end-4 9da8cc0cea update quickshell version for polkit 2025-10-30 19:38:26 +01:00
end-4 f9c7bbbe01 quickshell polkit agent 2025-10-30 19:37:28 +01:00
end-4 81116598cb sidebar: ai: make loading indicator transition smoother, disable text fade by default 2025-10-30 18:17:57 +01:00
end-4 46c803c9ce sidebar: add loading indicator for ai 2025-10-30 18:13:27 +01:00
end-4 93567a68e8 Weather settings in settings app (#2337) 2025-10-30 17:23:17 +01:00
clsty 2294653431 Add deps to dist-nix 2025-10-30 23:34:36 +08:00
vaguesyntax aae3add0c9 change settings text 2025-10-30 18:25:48 +03:00
vaguesyntax b690cd6335 Merge branch 'main' into weather-settings 2025-10-30 18:13:49 +03:00
vaguesyntax 487c0fc916 initial commit of weather settings 2025-10-30 18:10:37 +03:00
end-4 0551c010b5 fix clock hands rotating in the wrong direction 2025-10-30 16:04:55 +01:00
end-4 d645286744 lock: add setting to toggle new shape password chars 2025-10-30 15:56:17 +01:00
end-4 f3e674684e Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-30 15:55:29 +01:00
end-4 fd72cd5e22 add config option to use old sine wave cookie clock 2025-10-30 15:45:26 +01:00
clsty e8d2f8c476 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-10-30 22:43:14 +08:00
clsty e7e25cd25b Update showhelp() 2025-10-30 22:42:56 +08:00
Celestial.y d7750c099b fix(audio): Replace pulseaudio with pipewire-pulseaudio on Arch Linux (#2336) 2025-10-30 22:30:56 +08:00
clsty b74019a83b Merge remote-tracking branch 'refs/remotes/origin/main' 2025-10-30 22:29:11 +08:00
dancincomrade f81f4925a9 chore(audio): increment pkgrel by 1 due to new deps added to PKGBUILD 2025-10-30 22:29:11 +08:00
clsty df307d3d45 Update dist-nix 2025-10-30 22:28:31 +08:00
end-4 a122d6e905 uhh more round 2025-10-30 15:27:14 +01:00
end-4 a97b7706d8 make cookie clock more round 2025-10-30 15:23:58 +01:00
clsty e622928d9d Update dist-nix 2025-10-30 22:18:42 +08:00
clsty fceda9bd35 Rename var 2025-10-30 22:09:09 +08:00
dancincomrade 0bd22f89a7 fix: replace pulseaudio with pipewire-pulseaudio 2025-10-30 22:04:15 +08:00
end-4 1b996e37a7 adjust clock appearance 2025-10-30 12:38:30 +01:00
end-4 403344e120 make materialcookie use rounded polygons 2025-10-30 12:24:10 +01:00
end-4 a200951b75 format 2025-10-30 12:23:45 +01:00
end-4 5c71c53787 make region selector use materialshape instead of materialcookie 2025-10-30 11:42:54 +01:00
end-4 40b1e8297f lock: fix weird hiding anim with floating windows 2025-10-30 11:24:41 +01:00
end-4 dfbbe3fcca lock: make window hiding anim work with floating windows 2025-10-30 11:07:57 +01:00
end-4 b484e3311c use new QtCore import instead of Qt.labs.platform 2025-10-30 11:07:33 +01:00
end-4 287172cd5d update shapes submodule 2025-10-30 11:07:20 +01:00
end-4 5ef979db79 Small animation for quickshell lock (#2304) 2025-10-30 10:02:05 +01:00
end-4 af2dcc8533 Merge branch 'main' into main 2025-10-30 10:00:39 +01:00
end-4 06514ed7b7 lock: simplify shake anim impl 2025-10-30 09:58:52 +01:00
Celestial.y c7bc853ab3 Update nix install-deps.sh 2025-10-30 16:55:44 +08:00
end-4 3f20ab758c feat(lock): add fingerprint support (#2308) 2025-10-30 09:05:49 +01:00
end-4 e3db8372a7 lock: remove useless comment, declare fingerprint check proc running directly 2025-10-30 09:04:58 +01:00
end-4 175379dfdb locksurface: adjust fingerprint icon size/spacing 2025-10-30 09:03:11 +01:00
clsty ae87646e40 Update submodule in exp-update (#2334) 2025-10-30 15:45:49 +08:00
clsty b0f09b20d4 Fix message format 2025-10-30 13:27:26 +08:00
clsty f10bbacf7b Update checkdeps 2025-10-30 12:58:24 +08:00
clsty f50a3fe686 Update checkdeps 2025-10-30 12:57:01 +08:00
clsty bdc55dd082 Update checkdeps 2025-10-30 12:52:16 +08:00
clsty 86a10e9af5 Update checkdeps 2025-10-30 12:50:17 +08:00
clsty e5934c3eed Update checkdeps 2025-10-30 12:47:06 +08:00
clsty dabd8dc136 Update checkdeps 2025-10-30 12:44:27 +08:00
clsty 5509e21759 Update checkdeps 2025-10-30 12:37:05 +08:00
clsty f324310355 Update checkdeps 2025-10-30 12:33:34 +08:00
clsty 8b25e2b037 Update checkdeps 2025-10-30 12:27:19 +08:00
clsty 634fb09d2e Update checkdeps 2025-10-30 12:25:15 +08:00
clsty 0ac39d4356 Add subcmd checkdeps 2025-10-30 12:15:21 +08:00
clsty 60a0dcfdcf No more prompt about how to use ii on AGS 2025-10-30 11:57:58 +08:00
Celestial.y 6551d7cc5e Gentoo added go-yq (#2332) 2025-10-30 11:02:44 +08:00
jwihardi 4859acb700 Merge branch 'end-4:main' into main 2025-10-29 22:43:59 -04:00
jwihardi 34c46910b2 updated version number
wups, removed revision 1
2025-10-29 22:42:23 -04:00
jwihardi d51ce6a46f gentoo added yq-go 2025-10-29 22:35:39 -04:00
clsty bd8daf4015 Update backup logic in 3.files-exp.sh 2025-10-30 09:00:11 +08:00
clsty 649be3741c Add go-yq as dependency 2025-10-30 08:59:33 +08:00
end-4 fcc2ee3551 ai: cleaner message block delegate, add regen button 2025-10-30 00:40:23 +01:00
end-4 128808a56d styledswitch: fix wrong easing type 2025-10-30 00:03:31 +01:00
end-4 714895976f primarytabbar: use synchronizer to simplify bindings 2025-10-30 00:03:18 +01:00
Celestial.y 9fe68c5a38 Add YAML-based file installation system (issue #2137) (#2329) 2025-10-30 06:49:41 +08:00
end-4 a3a62f9826 make vscode theming work with some not-vs-vscode 2025-10-29 23:21:13 +01:00
end-4 389fd5e42c update material shapes for less weird spinny 2025-10-29 23:05:50 +01:00
end-4 947a13556a media controls: make rounding consistent with other panels 2025-10-29 23:05:32 +01:00
end-4 ee1fbf72cc vscode theming with Material Code extension (#2146) 2025-10-29 22:06:53 +01:00
Matt Van Harn 06775806d5 Add YAML-based file installation system (issue #2137)
- Replace hardcoded Bash logic with declarative YAML configuration
- Implement user preference wizard for shell/terminal/keybindings
- Add conditional file copying based on user preferences
- Support multiple sync modes: sync, soft, hard, hard-backup, soft-backup, skip, skip-if-exists
- Implement MD5 hash comparison for idempotent backups
- Add fontconfig fontset support via II_FONTSET_NAME
- Complete coverage of all config directories and files from original script

This is an experimental feature enabled via --exp-files flag.
2025-10-29 15:53:01 -04:00
end-4 961d5e7721 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-29 20:31:22 +01:00
end-4 727227cf8b add option to not animate digital bg clock (closes #2055) 2025-10-29 20:31:14 +01:00
end-4 cead3c87ea fix: prevent volumeChanged recursion (#2320) (#2323) 2025-10-29 20:21:17 +01:00
clsty c550a792b8 Improve backup functions 2025-10-30 00:42:13 +08:00
clsty cc1e5e4636 Improve backup_clashing_targets() 2025-10-29 23:21:31 +08:00
end-4 e279e4d972 make switches more bouncy 2025-10-29 15:59:15 +01:00
end-4 eb6fca6697 fix binding loop in Anime.qml 2025-10-29 15:17:23 +01:00
clsty 7476655302 Fix firstrun logic 2025-10-29 21:52:58 +08:00
雷家兴 8eb50a8917 fix: correctly resume from suspend by waiting pipewire resume (#2320) 2025-10-29 19:26:22 +08:00
end-4 d835d8bc30 adjust button wiggle anim 2025-10-29 12:05:38 +01:00
end-4 981e3be9b0 adjust secondary tab rounding 2025-10-29 12:05:21 +01:00
end-4 db3d8ddfc2 sidebar: corner triggers open only when reaching thru vertical edge 2025-10-29 11:53:12 +01:00
end-4 f5c421ab99 pageplaceholder: rotate less 2025-10-29 11:24:59 +01:00
end-4 4ad001fd9e make notif empty placeholder icon wrapped 2025-10-29 11:24:20 +01:00
end-4 05f3e52f55 make notifs and page placeholder use new material shapes 2025-10-29 11:17:03 +01:00
end-4 8b10ec2cfb sidebar: anime: fix loading indicator showing when navigating w/ keys 2025-10-29 11:04:00 +01:00
clsty 7b278aeff7 Update help 2025-10-29 17:50:12 +08:00
clsty d5e9b20aec Update help 2025-10-29 17:49:28 +08:00
clsty e9c3eca68a Update 3.files.sh about warning_rsync() 2025-10-29 17:44:32 +08:00
Celestial.y 41a328fbf0 Prepend Noto Sans Arabic in fontconfig (#2307) 2025-10-29 17:34:30 +08:00
clsty e1a8ba09f1 Move arabic fontconfig into dots-extra/fontsets/ar 2025-10-29 17:31:01 +08:00
end-4 c565dc1a7e Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-29 10:24:18 +01:00
end-4 ede90eb282 sidebar: anime: pull to load more 2025-10-29 10:24:11 +01:00
clsty f95165185c Implement --fontset (#2307) 2025-10-29 17:23:26 +08:00
end-4 26361718a7 background: only opaque when wallpaper safety triggered 2025-10-29 10:23:14 +01:00
clsty 41cf490681 Update online script url 2025-10-29 17:01:45 +08:00
clsty 44e384a256 Add --core option 2025-10-29 16:09:35 +08:00
clsty 21276f4d1e Improve order of inst scripts 2025-10-29 15:39:18 +08:00
end-4 43e8c85295 Changes with new submodule (#2322) 2025-10-29 08:24:43 +01:00
clsty 4672138b00 Add auto_get_git_submodule() 2025-10-29 08:15:47 +08:00
end-4 b8f115ef10 Merge branch 'Sighthesia-main' 2025-10-28 23:35:26 +01:00
end-4 574cbecf18 Merge branch 'main' of https://github.com/Sighthesia/dots-hyprland into Sighthesia-main 2025-10-28 23:33:56 +01:00
end-4 97b3f7ec55 settings: make right-clicking config file button copy path (#2112) 2025-10-28 22:48:08 +01:00
end-4 7982f43a62 lock: freaking fancy password chars 2025-10-28 22:10:04 +01:00
end-4 fc32ce56d0 booru response: less stupid layout.fillwidth 2025-10-28 22:08:19 +01:00
end-4 6c6a4edf59 shapes submodule 2025-10-28 20:41:04 +01:00
end-4 44da20ed4a settings: reorder servicesconfig sections to be alphabetical 2025-10-28 09:14:08 +01:00
end-4 4f8de83ff4 Music recognition toggle (like Shazam) with SongRec (#2301) 2025-10-28 09:09:26 +01:00
end-4 066971e720 music recognition: adjust message and icon 2025-10-28 09:02:19 +01:00
end-4 107dc8cc24 music recognition: move tmp path to a cleaner place 2025-10-28 08:57:51 +01:00
end-4 7b42efd37a rename music recognition script to be consistent w/ other scripts 2025-10-28 08:52:58 +01:00
end-4 9df78087f0 music recognition: add different icon for microphone source 2025-10-28 08:51:18 +01:00
end-4 06d12fb8ec music recognition: add check for songrec command existence 2025-10-28 08:48:57 +01:00
end-4 08d1a2dfd6 buttongroup: fix childrencount accessing from children 2025-10-27 22:44:33 +01:00
vaguesyntax 035e51b36e add interval to settings, update the script (it was not working as intented) 2025-10-27 20:39:45 +03:00
vaguesyntax 901aa820e5 fix config and icons 2025-10-27 19:33:17 +03:00
end-4 c1a5641ff5 fix wrong minimum brightness (#2310) 2025-10-27 17:32:26 +01:00
end-4 957a63d04a make screenshot to clipboard and file actually copy to clipboard (#2311) 2025-10-27 17:14:59 +01:00
clsty 43960b3a60 Fix outdate_detect() 2025-10-27 23:38:28 +08:00
end-4 8d7e4bdd0d lock: fix duplicate hyprlock spawning 2025-10-27 09:22:19 +01:00
0blivi0nis 9610baf903 🐛 fix(lock): remove duplicate connection, only start if configured, stop on unlock 2025-10-26 23:05:45 -07:00
Celestial.y 52011a7d80 Smart-live-rebuild added to Gentoo (#2309) 2025-10-27 11:10:18 +08:00
jwihardi 6be1437ecc added smart-live-rebuild 2025-10-26 23:05:00 -04:00
z0 cc49b4c921 Updated conf.d 2025-10-27 02:32:40 +03:00
0blivi0nis 3aa1d5f1ed feat(lock): add fingerprint support
Credit to @wooze-pao for providing the required code in #2162
2025-10-26 14:50:50 -07:00
z0 991f113e4e prepend font only if lang is ar 2025-10-27 00:40:27 +03:00
z0 04963a616d remove binding=strong from arabic font prepend 2025-10-27 00:35:23 +03:00
z0 839ca74bf1 Prepend Noto Sans Arabic in fontconfig 2025-10-26 22:00:35 +03:00
Celestial.y 437b2020b7 Update 3.files.sh 2025-10-27 01:09:30 +08:00
Celestial.y 4712931850 Update case in setup 2025-10-26 23:36:40 +08:00
clsty e56af1adc6 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-10-26 23:14:46 +08:00
clsty 7f245e2896 Rearrange sdata/subcmd; add --skip-backup 2025-10-26 23:13:49 +08:00
end-4 4fd5ba5630 add super+shift+r for region record
makes sense cuz other stuff with region selector use super+shift
2025-10-26 15:49:26 +01:00
end-4 7c5740a39b use quickshell region selector for recording 2025-10-26 15:45:07 +01:00
end-4 53998cc51a region selector: fix fab button color 2025-10-26 15:44:48 +01:00
Trung Coder 3faa20a29b Small animation for quickshell lock 2025-10-26 21:22:08 +07:00
clsty 57a2e5aba4 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-10-26 21:55:32 +08:00
clsty ad01fdad4e Improve message about deprecate install.sh and update.sh 2025-10-26 21:54:28 +08:00
Celestial.y 2893dc33b6 Update sdata/README.md 2025-10-26 21:41:53 +08:00
clsty 5a846cdec5 Move sdist/ID to sdata/dist-ID 2025-10-26 21:27:41 +08:00
Celestial.y c13ba5f25e Bump pkgrel from 1 to 2 in PKGBUILD 2025-10-26 21:01:12 +08:00
vaguesyntax 28e956e55c togglable monitor-source 2025-10-26 16:00:49 +03:00
vaguesyntax a05b041d69 fixes and youtube button 2025-10-26 14:12:04 +03:00
vaguesyntax 496225ab9d refactor code 2025-10-26 14:04:52 +03:00
Celestial.y 254b9471e4 Change backup path in environment-variables.sh 2025-10-26 18:40:23 +08:00
vaguesyntax b137feac16 fix: recognized notif not getting pushed 2025-10-26 12:24:35 +03:00
vaguesyntax cf159f6112 some typos 2025-10-26 03:45:43 +03:00
vaguesyntax 60f055f07d initial commit of musicRecognition 2025-10-26 02:46:39 +03:00
end-4 5dd0fe2761 adjust fab icon size and region selector fab color 2025-10-25 10:02:36 +02:00
end-4 43fe3874dd sidebar: make notif delete icon more intuitive 2025-10-25 09:26:07 +02:00
clsty ddf97f79d0 Fix -s for exp-update 2025-10-25 10:12:53 +08:00
clsty 5a050be3de Fix path in exp-update-old.sh 2025-10-25 08:43:41 +08:00
clsty d8aa0de443 Bring back old update.sh (#2284) 2025-10-25 08:11:42 +08:00
clsty 7662e4f904 Update exp-update-old.sh 2025-10-25 07:29:52 +08:00
clsty b0d64d00b6 (WIP) Bring back old update.sh (#2284) 2025-10-25 07:23:19 +08:00
end-4 9dd8f32595 make notif action buttons larger 2025-10-25 00:13:52 +02:00
end-4 99dd0a4e2e make notif status row less weird 2025-10-25 00:11:17 +02:00
end-4 531411315e region selector: remove auto fullscreen ocr, make close btn fab
ocr-ing the whole screen slow and messy. it's better to just go with the regular flow of selecting a region
2025-10-24 23:45:08 +02:00
end-4 e6eb53796d fix calendar occasionally get placed at funny position 2025-10-24 18:42:10 +02:00
end-4 a3ced86214 don't create homework folder before it's necessary (#2264) 2025-10-24 17:37:34 +02:00
end-4 435ff32904 sidebar: use friendlier name for idle inhibitor toggle 2025-10-24 17:37:14 +02:00
clsty e1270836d0 Update sdist/nix/README.md 2025-10-24 22:10:19 +08:00
end-4 93f8d0990f right sidebar: fix unused quick toggles being movable 2025-10-24 15:11:27 +02:00
end-4 b23a2d4f2c region selector: fix dismiss button 2025-10-24 13:10:18 +02:00
end-4 d031087972 ocr: use all available langs 2025-10-24 11:39:21 +02:00
end-4 cdf24a1c19 region selector: fix circle dragging being forced into a target region 2025-10-24 11:24:47 +02:00
end-4 e857d538fb region selector: make circle selection not amogus large 2025-10-24 10:29:48 +02:00
end-4 3bd699c9e6 use quickshell region selector for ocr 2025-10-24 00:26:47 +02:00
end-4 6f756f48cb settings: add roman ws number preset 2025-10-23 23:41:56 +02:00
end-4 b14a5b3dd9 settings: add ws number map presets 2025-10-23 23:32:11 +02:00
end-4 5f23f6caa3 brightness: adjust antiflashbang delays, indicate nightlight on osd 2025-10-23 19:29:37 +02:00
end-4 d05ae5231c add fallback script for google lens keybind 2025-10-23 19:07:18 +02:00
end-4 07d3eea1d1 workspace_action.sh: format 2025-10-23 19:06:39 +02:00
end-4 23830f3454 work safety: disabled by default, add toggle to settings app 2025-10-23 16:47:06 +02:00
end-4 24ae5d327e notif groups: expand on right press instead of release 2025-10-23 16:46:51 +02:00
end-4 7b9454b101 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-23 09:45:16 +02:00
end-4 b976ba17d5 region selector: cleanup after image search 2025-10-23 09:45:05 +02:00
clsty 9c803164e1 Remove .gitattributes 2025-10-23 15:33:16 +08:00
end-4 b9592b30af Show passive items in the system tray (#2251) 2025-10-23 09:26:00 +02:00
end-4 a536e1600d make night light color temp slider more intuitive 2025-10-23 09:19:07 +02:00
end-4 6267e54ad7 brightness: animate change for laptop screens, prevent pitch black w/ anti flashbang 2025-10-23 09:00:52 +02:00
end-4 11b337b189 anti flashbang: pass image directly to magick thru stdio, more triggers 2025-10-23 08:59:59 +02:00
Yosuke Nishiyama 20d34eb622 change name to "filterPassive" 2025-10-22 23:28:04 +01:00
Yosuke Nishiyama 416df97b64 Merge branch 'end-4:main' into patch-1 2025-10-22 23:26:44 +01:00
end-4 b3cabb788b anti flashbang: clean up when done 2025-10-23 00:22:35 +02:00
end-4 c620c11ba8 region selector: lower aim lines opacity 2025-10-23 00:06:23 +02:00
end-4 7515f77846 region selector: add option to show/hide coord aim lines 2025-10-23 00:05:19 +02:00
end-4 b35ef90916 add anti flashbang
could be improve with smooth fading
2025-10-22 23:56:50 +02:00
end-4 a4d2a720d0 fix deprecated Connections syntax 2025-10-22 23:55:39 +02:00
clsty 8141e15bd9 Add subcmds; Not skip backup unless input y/n 2025-10-23 05:20:22 +08:00
Celestial.y 064488a9c4 Not overwrite other things under quickshell 2025-10-23 04:36:40 +08:00
end-4 bb08c61b76 sidebar: night light dialog 2025-10-22 22:16:58 +02:00
end-4 6ed9c9869e styledslider: make marks with any range 2025-10-22 22:16:45 +02:00
end-4 586d7d4f9b sidebar: unfuck non-default quick toggles configurations 2025-10-22 22:15:26 +02:00
end-4 0ac96e02ab brightness service: more edging 2025-10-22 22:13:23 +02:00
end-4 63be9874f4 systeminfo: add gentoo 2025-10-22 17:46:41 +02:00
end-4 c1393ce7c7 region selector: animate icon on mode change 2025-10-22 17:46:30 +02:00
end-4 973d0c0c07 make region selector more readable in light theme 2025-10-22 09:22:58 +02:00
clsty c4f81e7027 Update quickshell version (gentoo) 2025-10-22 08:25:26 +08:00
end-4 ed0289df3b adjust screenshot regions opacity 2025-10-22 01:46:52 +02:00
end-4 7e4cbaf5df revamp region selector 2025-10-22 01:43:13 +02:00
end-4 bce8b6f9a8 make sidebar classic toggle button icons have size consistent with toolbar 2025-10-22 01:28:11 +02:00
end-4 0718546167 refractor icon toolbar buttons 2025-10-22 01:27:29 +02:00
end-4 8e222eb40d update qs version 2025-10-21 23:05:01 +02:00
end-4 fddb7ecc05 remove redundant imports 2025-10-21 22:58:26 +02:00
end-4 b5ae6f01eb Refactor import to be compatible with new version of quickshell (#2263) 2025-10-21 22:56:44 +02:00
Filip Janus ecd7a225e9 fix bar module reference 2025-10-21 22:43:54 +02:00
Filip Janus f2e4508cfc refactor import to be compatible with new version of quickshell 2025-10-21 22:36:56 +02:00
end-4 4031925e11 fix "no active player" popup positioning for vertical bar 2025-10-21 20:49:42 +02:00
end-4 a99f6cac5e sidebar: fix weird anim on toggle buttons 2025-10-21 20:10:52 +02:00
end-4 d5bccd9bb1 hide code: entries from cheatsheet for zoom keybinds 2025-10-21 17:51:55 +02:00
end-4 94102cec97 fix kill dialog not writing "always" properly (#2232) 2025-10-21 17:43:15 +02:00
end-4 778620c312 translation?service?:safer?access??? 2025-10-21 16:40:53 +02:00
end-4 c50a505cdb fix screenshot button 2025-10-21 16:06:16 +02:00
end-4 1830aeba18 make left sidebar padding consistent with right sidebar 2025-10-21 13:27:15 +02:00
end-4 1ba6b761f0 allow corner hover open for horizontal bar 2025-10-21 13:22:55 +02:00
clsty b1921b7847 Update message 2025-10-21 15:42:35 +08:00
clsty f37fa1b071 Finish adding auto-close-issue.yml 2025-10-21 15:25:45 +08:00
clsty a79201ebd7 Improve auto-close-issue.yml 2025-10-21 15:24:06 +08:00
clsty b557586a62 Try to fix auto-close-issue.yml 2025-10-21 15:13:12 +08:00
clsty 1842ab790e Try to fix auto-close-issue.yml 2025-10-21 15:04:10 +08:00
clsty e8937e2030 Try to fix auto-close-issue.yml 2025-10-21 15:01:16 +08:00
clsty 2ddfc77b66 Try to fix auto-close-issue.yml 2025-10-21 14:58:15 +08:00
clsty 00526116cc Try to fix auto-close-issue.yml 2025-10-21 14:53:43 +08:00
clsty 1c2bfb7991 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-10-21 14:51:46 +08:00
clsty fa52acad27 Add auto-close-issue workflow (WIP) 2025-10-21 14:49:09 +08:00
Celestial.y 18c11899cb Update package-installers.sh 2025-10-21 13:40:03 +08:00
clsty 3cd323cb1a Add --skip-quickshell for install-files.sh 2025-10-21 09:42:29 +08:00
Celestial.y 09c894db0a Gentoo Typo (#2257) 2025-10-21 09:28:50 +08:00
jwihardi 3f030805d1 gui-misc -> app-misc 2025-10-20 21:15:35 -04:00
Celestial.y e96be21850 Gentoo Quickshell Fix (#2256) 2025-10-21 09:10:44 +08:00
jwihardi 9242b93558 quickshell, widgets, install, useflag (breakpad), keywords - updated 2025-10-20 20:35:43 -04:00
jwihardi 4de08c438b Delete sdist/gentoo/illogical-impulse-quickshell-git/quickshell-9999.ebuild 2025-10-20 19:16:27 -04:00
jwihardi 576311f7b2 Merge branch 'end-4:main' into quickshell-fix 2025-10-20 19:16:01 -04:00
jwihardi bf96099e46 fixed package name 2025-10-20 19:14:38 -04:00
jwihardi 854edba825 added live quickshell ebuild with specific commit 2025-10-20 18:42:59 -04:00
end-4 fe3e5de518 sidebar: quick toggles: larger icon size when 1 cell wide 2025-10-20 23:12:58 +02:00
end-4 d5b1e9f40c sidebar: quick toggles: smoother size change 2025-10-20 22:56:33 +02:00
end-4 54fe878580 right sidebar: containerize top row elements 2025-10-20 22:25:23 +02:00
end-4 075a21a9db make google lens tool use normal region selection by default 2025-10-20 22:00:08 +02:00
end-4 cc605e24d9 region selector: fix target regions 2025-10-20 21:09:27 +02:00
end-4 4ea7401190 circle to search 2025-10-20 21:03:03 +02:00
Yosuke Nishiyama 3b4525413a typo 2025-10-20 18:43:17 +01:00
Yosuke Nishiyama 8bf59faf66 add config option for smartTray 2025-10-20 18:38:45 +01:00
Yosuke Nishiyama 54b4dd7818 Merge branch 'end-4:main' into patch-1 2025-10-20 18:33:38 +01:00
end-4 21b3cca54a hyprland: update keybinds+rules for previous commit 2025-10-20 13:13:54 +02:00
end-4 af65c39c87 make screen snip built into the shell so it's faster (#2113) 2025-10-20 13:13:01 +02:00
end-4 1d51cc3388 keybinds: make office keybind match windows, allow record when locked 2025-10-20 09:43:25 +02:00
Yosuke Nishiyama b6c1cd504e Show passive items in the system tray 2025-10-19 23:31:05 +01:00
end-4 ba0f2248d8 make notif items also draggable to left 2025-10-20 00:20:06 +02:00
end-4 96605fb0fe make notifs dismissable in both directions 2025-10-20 00:15:27 +02:00
end-4 991abd4c1c update default quick toggles 2025-10-20 00:03:15 +02:00
end-4 fec23cab8d right sidebar: move audio controls to dialogs 2025-10-19 23:58:45 +02:00
end-4 0fe7bdc5b5 feat: sound alerts for battery and pomodoro (#2223) 2025-10-19 21:37:25 +02:00
end-4 65557dfb3d fix sound plays every time low and charge state changes
instead of just when it goes to low
2025-10-19 21:37:10 +02:00
end-4 ad907a72a1 Merge branch 'fix-scaling' of https://github.com/sola-contrib/dots-hyprland 2025-10-19 21:20:57 +02:00
end-4 c65aea86c6 qs: use more neutral default pallete 2025-10-19 21:17:23 +02:00
end-4 76dd63a326 feat: Add screen recording button and config toggle (#2219) 2025-10-19 20:53:48 +02:00
end-4 8798b4e826 settings: make bar screen record util button toggle name shorter 2025-10-19 20:53:23 +02:00
end-4 7b1fa1246f bar: record util button off by default 2025-10-19 20:51:46 +02:00
end-4 f3e4773811 utilbuttons: record button: allow region selection 2025-10-19 20:51:05 +02:00
end-4 233b4c78ab settings: add api key note for ai translation 2025-10-19 13:11:02 +02:00
end-4 f81d316ad4 roundcorner: use switch fallthrough for fewer dupe returns 2025-10-19 10:29:24 +02:00
end-4 f123e90392 resourcePopup: fix unqualified access 2025-10-19 10:27:20 +02:00
clsty d0607c789f Add -f for makepkg 2025-10-19 16:15:32 +08:00
clsty 85278ea147 Ask once instead of 3 times for backup 2025-10-19 15:44:44 +08:00
clsty 9cbe0f38f9 Update comment in PKGBUILD 2025-10-19 14:32:38 +08:00
clsty 6bcb20ee4c Pin commit for quickshell-git (#2238) 2025-10-19 14:28:53 +08:00
clsty ca104160b0 Update showhelp 2025-10-19 11:53:34 +08:00
clsty bc13baa5a9 Update showhelp_global() 2025-10-19 11:32:22 +08:00
clsty 2014a030d6 Deprecate install.sh in favor of setup
Still decide to deprecate install.sh cuz TAB completion can not be done
without intrusive and automatic method, so just use ./setup instead.
2025-10-19 11:22:24 +08:00
clsty f673cae32b Update diagnose 2025-10-19 10:29:06 +08:00
clsty f5d09d569c Update comment 2025-10-19 09:52:11 +08:00
clsty 94749c1c69 Update comment 2025-10-19 09:35:46 +08:00
clsty 9c216036ec Update message 2025-10-19 09:33:53 +08:00
clsty 7e8750f79b Fix subcmd exp-uninstall --help 2025-10-19 09:06:18 +08:00
clsty 8ca46aecdd Using ./setup install instead of ./install.sh 2025-10-19 08:44:12 +08:00
clsty 0e6779fafc Fixes for install scripts 2025-10-19 06:59:33 +08:00
Celestial.y acde0218b3 Update the update script (#2220) 2025-10-19 06:54:23 +08:00
clsty b8a1955ab9 Update showfun() 2025-10-19 06:53:23 +08:00
Bishoy Ehab e49426c027 Fix a UI issue 2025-10-19 00:55:15 +03:00
Bishoy Ehab 00d547362b Remove the smoke-test 2025-10-19 00:49:04 +03:00
Bishoy Ehab cce6e821c2 Maybe fix the smoke-test 2025-10-19 00:48:03 +03:00
Bishoy Ehab a48ebfc4c1 Fixed the test and update script 2025-10-19 00:40:00 +03:00
Bishoy Ehab b23bdb0188 Test 2025-10-19 00:07:54 +03:00
Bishoy Ehab 69b92b57aa Update the update, update tester, functions scripts 2025-10-18 23:33:25 +03:00
end-4 84d692feef Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-18 22:12:49 +02:00
end-4 6834d41f4b sidebar: quick toggles: fix weird anim on startup 2025-10-18 22:12:40 +02:00
end-4 9fad405064 readme: update "some widgets" screenshot 2025-10-18 22:06:58 +02:00
end-4 a8ddbb5d2d sidebar: quick toggles: add missing tooltips 2025-10-18 21:54:13 +02:00
Bishoy Ehab 1fd328f90a Test the changes that have been made 2025-10-18 22:53:52 +03:00
end-4 6779fa90a5 sidebar: make status text of some toggles make more sense 2025-10-18 21:42:23 +02:00
end-4 45d6bfa3fb sidebar: quick toggles: fix iilegal default 2025-10-18 21:42:03 +02:00
end-4 5d1a9b1e9c sidebar: android-style quick toggles & sliders (#2217)
Co-Authored-By: Vague Syntax <173799252+vaguesyntax@users.noreply.github.com>
2025-10-18 19:07:10 +02:00
end-4 77ae119d32 fix gemini clock theming (forgor mkdir) 2025-10-18 09:58:59 +02:00
Bishoy Ehab 0facd08fa9 Merge branch 'end-4:main' into main 2025-10-17 21:33:50 +03:00
clsty 0ccdc47034 Improve/Fix showhelp 2025-10-18 01:24:26 +08:00
clsty 7c21ec0c5a Rename scripts, move into sdata/step 2025-10-18 00:54:58 +08:00
clsty 731beb0f7c Better integration; introduce subcommand 2025-10-18 00:38:49 +08:00
end-4 9a170a3c5b fix settings app cant change time format 2025-10-17 18:04:37 +02:00
end-4 f93d629acb sidebar: add scroll to bottom button 2025-10-17 18:00:11 +02:00
Bishoy Ehab eede0e3c34 Merge branch 'end-4:main' into main 2025-10-17 16:27:20 +03:00
Bishoy Ehab f4f97be46d Remove a useless condition 2025-10-17 16:16:39 +03:00
Bishoy Ehab 3bea2a314e Fix: Suppress /dev/tty error in safe_read 2025-10-17 14:50:26 +03:00
Bishoy Ehab 4d20de926c Fix: Prevent script exit in while-read loop 2025-10-17 14:48:16 +03:00
Bishoy Ehab b307b4ed95 Return the old update script 2025-10-17 14:35:32 +03:00
Bishoy Ehab 653cba4d4e Test 2025-10-17 14:33:37 +03:00
Bishoy Ehab adb93e382f Test 2025-10-17 14:32:56 +03:00
Bishoy Ehab b2938ef678 Test 2025-10-17 14:32:46 +03:00
Bishoy Ehab 809c8806d0 Test 2025-10-17 14:31:54 +03:00
Bishoy Ehab d809c2e789 Test 2025-10-17 14:30:03 +03:00
Bishoy Ehab ca2d073775 Maybe something fixed? 2025-10-17 14:13:16 +03:00
Bishoy Ehab 4038c437c6 Merge branch 'main' of https://github.com/BeshoyEhab/dots-hyprland 2025-10-17 13:54:42 +03:00
Bishoy Ehab 12011fd0c8 Enhance the logic for pass the args to update script 2025-10-17 13:54:02 +03:00
Bishoy Ehab 528ae04711 Update install script to pass the update args 2025-10-17 13:44:23 +03:00
Celestial.y 7612a3f742 Use local var for args_includes 2025-10-17 18:35:12 +08:00
Bishoy Ehab 2272b94531 Update the update and options and install to correctly pass the args to update script 2025-10-17 13:21:32 +03:00
Celestial.y 21d628b598 Try to fix backup 2025-10-17 17:49:20 +08:00
Bishoy Ehab ab0049ec5c Integrate update script into install.sh 2025-10-17 12:16:55 +03:00
Bishoy Ehab ac394784e3 Merge branch 'end-4:main' into main 2025-10-17 12:10:20 +03:00
end-4 943a72ce12 Fix escape keybind notification for virtual machines (#2222) 2025-10-17 07:05:23 +02:00
Celestial.y 927d9b0f85 Fix diagnose 2025-10-17 11:33:03 +08:00
Celestial.y 7454087c88 Fix backup function typo 2025-10-17 11:15:56 +08:00
0blivi0nis 37fd19fc9a feat: sound alerts for battery and pomodoro 2025-10-16 19:03:14 -07:00
Alvin aa90e75c59 Fix escape keybind notification for virtual machines 2025-10-16 21:13:35 -04:00
Bishoy Ehab 7b090c2e2a Fix some issues in the test_update script 2025-10-17 01:14:45 +03:00
Bishoy Ehab 1a4a8d87fc Update the test script 2025-10-17 00:20:28 +03:00
Bishoy Ehab fbd0644942 Fix some security issues and remove non-used function 2025-10-17 00:16:09 +03:00
Bishoy Ehab 4eb4f635e7 Add test_update sctipt 2025-10-16 23:52:34 +03:00
Bishoy Ehab 60d6bfae9f Update the Warning message 2025-10-16 23:43:33 +03:00
Bishoy Ehab 009345c5f6 Fix the local used outside a function issue 2025-10-16 23:38:18 +03:00
Bishoy Ehab 00d4d368df Enhance the update script 2025-10-16 23:35:27 +03:00
Cleboost 5fda1cdc61 fix: Invoke record script via bash -c with ~ expansion 2025-10-16 22:07:29 +02:00
Cleboost 91955ef66c Add screen recording button and config toggle 2025-10-16 22:02:00 +02:00
Celestial.y 89585f8121 Updata uv/README.md 2025-10-16 22:22:08 +08:00
end-4 449df7f161 background: fix(??) bg clock paralax (??) 2025-10-16 11:52:14 +02:00
end-4 a5170c51b3 sidebar: add option for hover open at end of hover region 2025-10-16 09:59:36 +02:00
end-4 20bda361a3 Fix bad keyboard layout if variant name has commas (#2186) 2025-10-16 09:38:37 +02:00
end-4 ca7ae4e1e8 Fix Booru pending query not dismissing when fetch fails (#2207) 2025-10-16 09:31:53 +02:00
end-4 6f08589265 adjust bg clock parallax factor 2025-10-16 09:21:25 +02:00
end-4 ac5c902569 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-16 09:20:46 +02:00
end-4 731b5cccad fix bg clock parallax 2025-10-16 09:20:11 +02:00
end-4 fd1e82bd8e Delete items in clipboard history with Shift+Del (#2199) 2025-10-16 09:12:51 +02:00
end-4 2140eff9af add qs and qt version check to diagnosis script 2025-10-16 09:01:58 +02:00
André Zanghelini 6f97bb2635 Allow OSK keyboard for German and Russian variants 2025-10-16 03:58:52 -03:00
André Zanghelini fd0b5f4377 Fix bad keyboard layout if variant name has commas 2025-10-16 03:58:52 -03:00
André Zanghelini c5bd1d6bc0 Shift+Del to delete item in clipboard history 2025-10-16 03:58:16 -03:00
André Zanghelini 40ba90df27 Drop running booru fetch and alert on fetch error 2025-10-16 03:57:43 -03:00
clsty 450a1493fe Update STY_ vars 2025-10-16 12:14:54 +08:00
Celestial.y 3b1f9aa41e Fix syntax error in if statement (#2214) 2025-10-16 11:43:50 +08:00
TheBITLINK aka BIT e993671d02 Fix syntax error in if statement 2025-10-16 00:32:57 -03:00
clsty b36758a155 Rename revision number for ebuilds (#2211) 2025-10-16 11:06:01 +08:00
clsty 14a46622c3 Fix naming 2025-10-16 10:31:13 +08:00
clsty 9aea0f1034 Update prompt 2025-10-16 10:20:06 +08:00
clsty 8e87a7aa99 Improve backup_configs, only backup clashing ones (#1863) 2025-10-16 10:12:38 +08:00
Celestial.y 4d31886e4a Update sdist/arch/README.md 2025-10-16 08:41:41 +08:00
Celestial.y 4886f87afa Fix path in .gitignore 2025-10-16 08:00:30 +08:00
Celestial.y 923b22a75a Fix path in CONTRIBUTING.md 2025-10-16 07:59:56 +08:00
clsty 610ac47289 Fix path in update.sh 2025-10-16 07:47:32 +08:00
clsty de28b8d314 Fix permission 2025-10-16 07:46:06 +08:00
clsty 7c50f6c8d0 Fix 3.install-files.sh 2025-10-16 07:41:22 +08:00
clsty 8b493e091d Rearrange for tidier structure (#2212) 2025-10-16 07:19:55 +08:00
end-4 13065d7e5a settings: add toggle for wallpaper selector use system file picker 2025-10-15 19:27:14 +02:00
clsty 3f7d6759c1 Update gentoo/outdate-detect-mode to AUTO 2025-10-15 19:15:37 +08:00
end-4 a4be03cd5f enable icon fill anim again 2025-10-15 13:06:41 +02:00
end-4 44d5994248 screenshot: dont put region size in the region 2025-10-15 10:11:24 +02:00
Celestial.y d8b6d52a85 dist-gentoo updates (#2155) 2025-10-15 15:39:16 +08:00
jwihardi e0e6054f2f Clean up blank lines in install-deps.sh
Removed unnecessary blank lines in install-deps.sh.
2025-10-15 00:03:28 -04:00
jwihardi eeed0c0b1a Merge branch 'end-4:main' into main 2025-10-15 00:01:17 -04:00
jwihardi 5fbdea2cae Merge pull request #2 from jwihardi/symbols
Symbols
2025-10-15 00:00:44 -04:00
jwihardi 393944a8a7 Update README with Hyprland known issues
Added troubleshooting steps for Hyprland emerging issues.
2025-10-14 23:58:53 -04:00
jwihardi a442e2be91 added another initial print 2025-10-14 23:48:32 -04:00
jwihardi 18398e1b93 fonts-themes was an r1 build? Why? 2025-10-14 23:43:02 -04:00
jwihardi 1b08584ced fonts now installs symbols and space grotesk 2025-10-14 23:42:23 -04:00
end-4 20a3da8a19 left sidebar: more animated placeholders 2025-10-14 23:52:46 +02:00
end-4 1dd4c4a109 ai-generated ui translations 2025-10-14 18:50:01 +02:00
end-4 a228c54dd5 remove debug print 2025-10-14 18:48:26 +02:00
end-4 125d3c0a4d translations: update en_US keys 2025-10-14 17:56:50 +02:00
end-4 c9f5397821 translation tools: add -y/--yes flag 2025-10-14 12:22:16 +02:00
end-4 57a5c0f743 move translations into quickshell folder 2025-10-14 12:02:33 +02:00
end-4 8dc31cc790 background: make clock have slightly different parallax movement 2025-10-14 11:58:37 +02:00
end-4 fd1d74ada1 refractor gemini-categorize-wallpaper.sh 2025-10-14 10:19:09 +02:00
end-4 28756860aa cookie clock: fix bubble date's bubbles being the same 2025-10-14 09:29:41 +02:00
end-4 5929533d78 cookie clock: fix jagged rotating date 2025-10-14 09:28:42 +02:00
end-4 395baf1509 Don't scroll when deleting clipboard history items (#2198) 2025-10-14 09:22:14 +02:00
end-4 b4d89b66f5 Fix command key formatting in SearchWidget.qml 2025-10-14 09:21:18 +02:00
André Zanghelini e9f803b8a5 Don't scroll when deleting clipboard history items 2025-10-14 01:34:38 -03:00
clsty 8b25dca1dc Update install scripts 2025-10-14 12:23:10 +08:00
clsty 514363247a Update 1.install-deps-selector.sh 2025-10-14 12:13:28 +08:00
jwihardi 354a415e73 Merge pull request #1 from jwihardi/clean-testing
Clean testing
2025-10-13 23:03:27 -04:00
jwihardi 4df5de3122 Merge branch 'main' into clean-testing 2025-10-13 23:02:47 -04:00
jwihardi e5815974b1 Update ebuild to remove local material symbols font
Removed installation of material symbols font to local user directory.
2025-10-13 23:01:55 -04:00
jwihardi 2ff8e8fa67 Merge branch 'end-4:main' into main 2025-10-13 23:01:27 -04:00
clsty dd7038adf2 Use README.md instead of comment.(#1061) 2025-10-14 10:54:25 +08:00
clsty 39d25107bd Update comment (#1061) 2025-10-14 10:49:14 +08:00
jwihardi 2c671578ae added material-design symbols 2025-10-13 22:37:45 -04:00
jwihardi 76680ba86c chowns not needed usually 2025-10-13 21:34:47 -04:00
jwihardi 4d83c5a8f9 fixed i2c group detection 2025-10-13 21:12:43 -04:00
jwihardi 274a857dff added python:3.12 2025-10-13 20:58:28 -04:00
clsty c891c9a921 Update dist-*/README.md; Update comment 2025-10-14 08:34:54 +08:00
jwihardi 247a8e0cca Merge branch 'end-4:main' into clean-testing 2025-10-13 18:51:39 -04:00
jwihardi 15c0ab6279 Merge branch 'end-4:main' into main 2025-10-13 18:50:47 -04:00
jwihardi 5c7c21fdf1 fixed typo 2025-10-13 18:49:44 -04:00
jwihardi 14348306e2 updated guru to match main 2025-10-13 18:49:05 -04:00
jwihardi 02cc4c1aa2 moved additional useflags to another file 2025-10-13 18:45:51 -04:00
jwihardi 1aadbfc019 Update README.md with known issues for Hyprland
Added known issues section for Hyprland installation.
2025-10-13 18:05:35 -04:00
end-4 b53e657091 move Translation to services folder 2025-10-13 23:42:34 +02:00
end-4 74967cbac8 crosshair: fix wrong ipc handler target name 2025-10-13 23:42:22 +02:00
end-4 a139451a9b readme: update first screenshot 2025-10-13 21:39:04 +02:00
end-4 7708372922 make vm submap keybind more friendly for eroges
prevents ctrl skip
2025-10-13 21:13:58 +02:00
jwihardi 09146ec176 added more use flags 2025-10-13 15:13:00 -04:00
jwihardi 3abadb666e added gtkmm use flag 2025-10-13 15:11:15 -04:00
end-4 be164a823d fix notif unread indicator showing even when sidebar is open 2025-10-13 20:57:13 +02:00
end-4 d5dda1722a update wallpapers service to use venv wrapped thumbgen (#2143) 2025-10-13 20:19:12 +02:00
end-4 28ea9a7861 wrap thumbgen in venv script, add missing deactivates (#2143) 2025-10-13 20:16:39 +02:00
jwihardi ec87635e8e Fix useflag for dev-libs/qcoro 2025-10-13 13:58:33 -04:00
jwihardi 48219fbd95 Add freetype and harfbuzz use flags 2025-10-13 13:52:42 -04:00
jwihardi 33b5202a5d Add VLC and qcoro use flags 2025-10-13 13:47:46 -04:00
jwihardi 141fa55869 Merge branch 'end-4:main' into clean-testing 2025-10-13 13:36:57 -04:00
jwihardi 2a2e2da879 Merge branch 'end-4:main' into main 2025-10-13 13:36:45 -04:00
end-4 73bd73d910 cookie clock: adjust space preset 2025-10-13 19:33:09 +02:00
end-4 9d733fcff5 Fix dominant color from least_busy_region as BGR (#2187) 2025-10-13 17:56:31 +02:00
end-4 307c543d8d Add more status in the network icon (#2154) 2025-10-13 17:52:43 +02:00
end-4 5ffd1c85d3 Fix: Preserve chronological order of clipboard history (#2190) 2025-10-13 17:46:16 +02:00
end-4 f771d47526 update he_HE translation (#2189) 2025-10-13 17:43:44 +02:00
end-4 50e73d4a3a set config read/write delay to 0 where delay is unnecessary 2025-10-13 17:35:08 +02:00
end-4 6cc96d094d update work safety file keyword list 2025-10-13 17:29:33 +02:00
TheAnnoying dc149d2636 Update he_HE.json 2025-10-13 17:40:05 +03:00
TheAnnoying 6a9fd04989 Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:37:29 +03:00
TheAnnoying 7c01257cdd Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:37:19 +03:00
TheAnnoying fa99a0b3c8 Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:37:13 +03:00
TheAnnoying cec8dc991c Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:37:07 +03:00
TheAnnoying 2b78225114 Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:37:01 +03:00
TheAnnoying 2ffec8014a Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:36:56 +03:00
TheAnnoying 30f2db1e4d Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:36:50 +03:00
TheAnnoying 1b44b27142 Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:36:44 +03:00
TheAnnoying badc1249c0 Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:36:38 +03:00
TheAnnoying 8621b3f6ff Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:36:30 +03:00
TheAnnoying e67d8e9c81 Update .config/quickshell/translations/he_HE.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-13 17:36:22 +03:00
ew 769ad73737 Handle empty search in fuzzyQuery function
Add check for empty search string in fuzzyQuery function.
2025-10-13 22:33:08 +08:00
TheAnnoying afb14409c2 chore: string syncing and translation 2025-10-13 17:08:17 +03:00
end-4 971aaf3b98 cookie clock: fix shadow not including date bubbles 2025-10-13 15:19:14 +02:00
end-4 2d2145a780 bg clock: fix cursed bubble date 2025-10-13 15:11:58 +02:00
end-4 28078910a2 adjust abstract wallpaper clock style 2025-10-13 15:11:34 +02:00
end-4 6235e6e665 settings: fix untranslatable text 2025-10-13 15:00:50 +02:00
end-4 5bf63bc36c adjust stupid config rw delay 2025-10-13 15:00:31 +02:00
end-4 02192368d2 add option to use hyprlock instead of quickshell 2025-10-13 12:16:42 +02:00
end-4 b0cfcaff3d anime: fix anchors in layout 2025-10-13 12:13:37 +02:00
end-4 d208b07a94 config: lower read/write timer interval 2025-10-13 11:56:48 +02:00
end-4 e715478310 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-13 11:24:04 +02:00
end-4 5dedbf91e0 add gemini powered clock styling 2025-10-13 11:24:02 +02:00
clsty 64e04ae15b Update CONTRIBUTING.md 2025-10-13 13:40:33 +08:00
clsty 573105d269 Add TODO in diagnose 2025-10-13 13:32:52 +08:00
André Zanghelini 8fc6a4b349 Fix dominant color from least_busy_region as BGR 2025-10-13 02:10:40 -03:00
jwihardi c6c76be8f9 Fix formatting in README.md for clarity 2025-10-13 00:54:19 -04:00
jwihardi 1cd15ffa53 Fix formatting and wording in known issues section 2025-10-13 00:53:07 -04:00
jwihardi eb9c3f7867 Fix typo in README regarding Hyprland ebuild 2025-10-13 00:46:00 -04:00
jwihardi a369409930 Update README with known issues for Hyprland
Add known issues section for Hyprland installation.
2025-10-13 00:45:36 -04:00
jwihardi ad6788f67a Add sonnet USE flag for kde-frameworks
Add sonnet USE flag for kde-frameworks.
2025-10-13 00:35:53 -04:00
jwihardi 28de204036 Fix typo in kde-frameworks/kconfig entry 2025-10-12 23:46:35 -04:00
jwihardi cf5bfb16bd Add new use flags for kde-frameworks and app-crypt 2025-10-12 23:44:50 -04:00
jwihardi 5642d379a5 Add xmlto with text use flag
Added 'app-text/xmlto' with 'text' use flag.
2025-10-12 23:36:23 -04:00
jwihardi e33992ecf8 Update keywords 2025-10-12 23:34:14 -04:00
jwihardi fa85e0cc68 Add brightnessctl and update libxkbcommon keyword 2025-10-12 23:27:37 -04:00
jwihardi 42ee8d9ca4 Update README with use flags and service recommendations
Clarify recommended use flags and dot-files setup instructions.
2025-10-12 23:26:51 -04:00
clsty d521e014fd Update README.md 2025-10-13 11:16:42 +08:00
jwihardi 43545bce41 Merge branch 'end-4:main' into main 2025-10-12 23:11:33 -04:00
end-4 78723402ee refractor bar unread notif indicator, add count option in settings 2025-10-12 23:35:59 +02:00
jwihardi 9698974ad7 Merge branch 'end-4:main' into main 2025-10-12 17:16:03 -04:00
end-4 6f138677a8 settings: allow larger bg clock cookie side # range 2025-10-12 22:17:19 +02:00
end-4 9161044860 adjust critical notif cookie 2025-10-12 22:17:01 +02:00
end-4 30e804acd8 settings: fix inconsistent content section text color 2025-10-12 20:35:57 +02:00
end-4 40fe0bebcf prevent empty sidebar 2025-10-12 20:17:31 +02:00
end-4 4f25572d1d make critical notif icon more readable 2025-10-12 20:17:12 +02:00
end-4 81cc35702d sidebar: add option to disable translator tab 2025-10-12 19:53:42 +02:00
end-4 cd3ed42b6d make symbols on left sidebar wrapped with a pentagon 2025-10-12 18:43:59 +02:00
end-4 4637b82471 make urgen notifs have cookie shape 2025-10-12 18:34:20 +02:00
clsty e1d77c0c3e Add --sudoloop for yay (#823) 2025-10-12 23:08:51 +08:00
end-4 bc688792cb make tray context menu animate faster 2025-10-12 16:31:52 +02:00
end-4 36b33ba4f1 make some buttons trigger on mouse down to feel faster 2025-10-12 16:30:41 +02:00
end-4 edde61a46c bg clock: make second hand anim more continuous 2025-10-12 16:27:32 +02:00
end-4 aa1fcd7eb9 ai chat: fix message not fade in until the end when there's code blocks 2025-10-12 14:17:54 +02:00
end-4 3f59e2078a ai: fade in: prevent random monospaced text 2025-10-12 13:13:43 +02:00
end-4 c2edd26598 ai chat: adjust msg header style 2025-10-12 13:13:25 +02:00
end-4 a0ceed9586 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-12 12:58:05 +02:00
end-4 a6e360c1db ai: fade in response 2025-10-12 12:58:03 +02:00
end-4 79b49bd57e fix material theme loader connections warning 2025-10-12 12:56:13 +02:00
end-4 0c1b7abe36 add Qt.callLater() to sidebar scroll to bottom (#2183) 2025-10-12 10:51:17 +02:00
end-4 6d39b63a74 bg clock: dont enable hour marks by default 2025-10-12 10:26:30 +02:00
end-4 438b2aac65 Unread notification count on bar (#2153) 2025-10-12 10:24:17 +02:00
end-4 3ffc25d5d8 add option to show/hide unread notif count 2025-10-12 10:23:34 +02:00
end-4 3b689f8a66 notif indicator: fix readability 2025-10-12 10:06:23 +02:00
end-4 2b62a5a0cc make notif indicator only show unread 2025-10-12 10:03:12 +02:00
end-4 7e46145df1 fix opening right sidebar with mouse not dismissing notifs 2025-10-12 09:59:29 +02:00
end-4 9655549739 Use thumbnail or wallpaper for Appearance (#2129) 2025-10-12 09:48:05 +02:00
end-4 57a3d1369b Appearance.qml: refractor wallpaperIsVideo check 2025-10-12 09:47:18 +02:00
end-4 2ae7a519d0 Hide Bluetooth widgets for systems without Bluetooth (#2167) 2025-10-12 09:43:10 +02:00
Woozepao 9165c6b706 Fix Jetbrain IDEs lose focus/rerendering problem (#2179) 2025-10-12 09:34:31 +02:00
jwihardi 7818864fac Merge branch 'end-4:main' into main 2025-10-12 00:59:16 -04:00
clsty 3f577f1088 Rename ex-files to exp-files 2025-10-12 10:22:05 +08:00
clsty 546435db6d Add --ex-files (#2137) 2025-10-12 10:20:44 +08:00
jwihardi c6f64a3acb added additional use flags 2025-10-11 21:13:45 -04:00
jwihardi c6b7652c6e added another warning and changed warning prints 2025-10-11 20:38:13 -04:00
jwihardi bfebd69568 Merge branch 'end-4:main' into clean-testing 2025-10-11 20:18:53 -04:00
jwihardi 3fb46f9604 Merge branch 'end-4:main' into main 2025-10-11 20:14:29 -04:00
end-4 17384f5761 Improve cookie clock style (#2117) 2025-10-11 18:18:00 +02:00
end-4 5a5328b1cb settings: cookie clock: fix wrong name/icon 2025-10-11 18:16:02 +02:00
end-4 edc83764c4 cookie clock: remove useless vars, adjust settings icons 2025-10-11 18:14:57 +02:00
end-4 1f5527164c settings: rearrange cookie clock settings 2025-10-11 17:58:24 +02:00
end-4 af5a7964d0 cookie clock: adjust colors and terminology 2025-10-11 17:52:08 +02:00
end-4 41c2814610 cookie clock: cleaner date indicator, adjust colors 2025-10-11 17:40:24 +02:00
end-4 c197f6eab2 bg clock: fix am pm parsing for 1 digit hours 2025-10-11 16:57:26 +02:00
end-4 410da66834 cookie clock: put hands in loaders 2025-10-11 16:55:20 +02:00
end-4 eb6a0e38f7 Include keypad numbers for keybinds with numbers (#2170) 2025-10-11 16:49:50 +02:00
Celestial.y 8e90c2898a Update post-installation link in install script 2025-10-11 22:23:02 +08:00
André Zanghelini 4074741187 Allow zoom with keypad 2025-10-11 10:49:41 -03:00
André Zanghelini 01bcab4af1 Allow keypad numbers for keybinds with numbers 2025-10-11 10:42:18 -03:00
end-4 6c5cc98016 make volume protection message translatable (#2164) 2025-10-11 15:24:36 +02:00
Ricardo Subtil b39618cd89 Disable Bluetooth buttons for systems without Bluetooth 2025-10-11 14:16:14 +01:00
end-4 22316b4684 fix anchor in layout 2025-10-11 11:50:34 +02:00
end-4 1e7e3a84c6 put time column in loader, use fewer Behaviors 2025-10-11 11:47:36 +02:00
end-4 872e0762b6 time column: fix am pm spacing 2025-10-11 11:22:55 +02:00
end-4 61fec4b53d background clock: hour marks: put in loader, reduce behavior spam 2025-10-11 11:20:15 +02:00
end-4 8e7b012c4c fix am pm matching 2025-10-11 11:18:32 +02:00
end-4 7ae53ac364 rename dateIndicator folder 2025-10-11 10:55:35 +02:00
end-4 c519505296 refractor MinuteMarks 2025-10-11 10:46:36 +02:00
end-4 a9b60c1d1b adjust quote style 2025-10-11 09:42:22 +02:00
end-4 22108934ff remove redundant DateIndicator 2025-10-11 09:27:28 +02:00
end-4 c93f8eafea Merge branch 'main' of https://github.com/darksignal7/dots-hyprland 2025-10-11 09:21:53 +02:00
end-4 856cfd3ebb hourhand: parameterize hand length 2025-10-11 09:20:42 +02:00
end-4 bccb516223 screen corner interaction: fix not working for vertical bar 2025-10-11 00:37:50 +02:00
end-4 53717588f9 screen corner interaction: make not unnecessarily enabled 2025-10-11 00:27:51 +02:00
end-4 4258d94d00 media controls: fix cover wrong after switching track, make not rely on cascade 2025-10-11 00:22:16 +02:00
end-4 01f8631663 disallow volume over 200% 2025-10-11 00:03:18 +02:00
end-4 393d90d3f7 fix colors not applied properly on first run 2025-10-10 23:58:45 +02:00
end-4 bd90e2c19e bar: fix tray overflow menu showing when empty 2025-10-10 23:47:27 +02:00
end-4 fe19cea6c9 search: add prefix for app search 2025-10-10 23:33:21 +02:00
jwihardi 56ab7f212e verbose is cringe, ask not needed 2025-10-10 17:15:24 -04:00
jwihardi 5179611c64 Merge branch 'end-4:main' into clean-testing 2025-10-10 17:14:18 -04:00
jwihardi 0c930294f1 Merge branch 'end-4:main' into main 2025-10-10 17:14:11 -04:00
end-4 8541dd3178 hyprland: use raw keycodes for ws binds so they work for funny kb layouts (#2157) 2025-10-10 23:08:39 +02:00
end-4 7e9a07838e hyprland: add note for raw keycode workspace binds 2025-10-10 23:06:44 +02:00
Celestial.y 7f2d1702ca Update comment in dist-update-notification.yml 2025-10-10 23:38:51 +08:00
Celestial.y b4b461d815 Update CONTRIBUTING.md 2025-10-10 22:46:28 +08:00
jwihardi bc75157b9f guru is correctly detected 2025-10-10 10:44:12 -04:00
jwihardi 67465045bb Merge branch 'end-4:main' into main 2025-10-10 10:31:07 -04:00
jwihardi 5dbfe00207 Merge branch 'end-4:main' into clean-testing 2025-10-10 10:30:38 -04:00
Celestial.y 38ac1723f6 Update 1-issue.yml 2025-10-10 22:16:16 +08:00
jwihardi af3ef1efde remove opencv useflags (invalid) 2025-10-10 10:06:32 -04:00
Hugo Vigne 3fba370e87 Update keybinds with code:... bindings for workspace navigation
Fixes https://github.com/end-4/dots-hyprland/issues/1705

Some keyboard layouts such as Azerty and Bépo defaults to symbols for the digits row, contrary to Qwerty-based layouts. Pressing Shift allows typing the actual digits instead of symbols.

Unfortunately, this breaks Workspace navigation in Hyprland configurations unless using keycodes for binding the digits row (1, 2, 3...0).

This commit does exactly that. It was tested with three keyboards, each time with 2 layouts: Azerty (French) / Qwerty (US).
The physical keyboards were:
- Asus Strix Scope II 96 Wireless
- Keychron Q3 HE QMK (ISO layout)
- The keyboard integrated in the Lenovo Thinkpad P16s Gen3 laptop.
2025-10-10 12:02:05 +02:00
jwihardi a28b1b5aa2 removed invalid atom 2025-10-10 02:34:07 -04:00
jwihardi aec5ef442e libxkmcommon needs to be unmasked for hyprland ebuild 2025-10-10 01:22:45 -04:00
jwihardi c907512cf0 Merge branch 'end-4:main' into main 2025-10-10 01:03:32 -04:00
jwihardi b87190993f added imagemagick 2025-10-10 01:03:22 -04:00
André Zanghelini 2d7cacbefb Add more status in the network icon 2025-10-10 00:17:06 -03:00
André Zanghelini 63e81369c2 Show notification indicator on "tray" 2025-10-09 23:08:25 -03:00
end-4 6f9bc17d57 deps: add imagemagick 2025-10-09 22:12:09 +02:00
Gwendolyn Page 7bd1810852 add Qt.callLater() around function calls to prevent leak 2025-10-09 13:54:49 -05:00
clsty 433fe1449a Update message 2025-10-10 01:12:05 +08:00
clsty b6566ec67b Update gentoo ebuild version 2025-10-10 00:58:08 +08:00
clsty b67b0baa1b Fix workflow 2025-10-10 00:55:18 +08:00
clsty 73e6d627bc Fix workflow 2025-10-10 00:43:21 +08:00
clsty e4ace3c416 Fix workflow 2025-10-10 00:40:54 +08:00
clsty b58c86cdd6 Fix workflow 2025-10-10 00:35:22 +08:00
clsty 9ff93169df Add dump github context workflow 2025-10-10 00:28:23 +08:00
clsty 44cdb3a52e Fix workflow 2025-10-10 00:23:07 +08:00
clsty 3d7fbba014 Fix workflow 2025-10-10 00:17:10 +08:00
end-4 ce1a397a7c wifi menu: fix double clicking always showing password prompt 2025-10-09 18:10:02 +02:00
clsty fa7da189fc Test commit on dist-arch 2025-10-09 23:32:03 +08:00
clsty 582fffda1b Fix workflow 2025-10-09 23:12:49 +08:00
darksignal7 3bf6f7ca09 fix: hide cookie quote on digital (am i blind or smthn?) 2025-10-09 17:45:04 +03:00
clsty 0a7c549125 Test commit on dist-arch 2025-10-09 22:42:33 +08:00
clsty 3bb510e910 Fix workflow 2025-10-09 22:39:40 +08:00
clsty 75a84f6ed1 Use DISCUSSION_NODE_ID 2025-10-09 22:28:41 +08:00
clsty a7aadd7439 Fix JSON parsing problem 2025-10-09 22:22:59 +08:00
clsty 1e90434c18 Fix curl no url 2025-10-09 22:21:17 +08:00
clsty d718f023cd Get notification node id first 2025-10-09 22:18:11 +08:00
darksignal7 28b47b25ea fix: hide cookie quote on lock screen 2025-10-09 17:06:41 +03:00
clsty 2bf933a3e1 Test commit on dist-arch 2025-10-09 21:53:22 +08:00
Celestial.y 24a548cd97 Update discussion ID in dist-update-notification.yml 2025-10-09 21:51:46 +08:00
Celestial.y ce307391a8 Test commit on dist-arch 2025-10-09 21:48:27 +08:00
Celestial.y 7abc7c07af Update GitHub Actions to use GraphQL for comments 2025-10-09 21:47:13 +08:00
Celestial.y d8c49a3d04 Test commit on dist-arch 2025-10-09 21:45:07 +08:00
Celestial.y 064bb51d7a Test commit on dist-arch 2025-10-09 21:31:19 +08:00
Celestial.y b74e36ca60 Try to fix workflow 2025-10-09 21:30:43 +08:00
Celestial.y 3e344a3de0 Test commit on dist-arch 2025-10-09 21:26:46 +08:00
Celestial.y b19cc90fd3 Refactor GitHub Actions workflow for discussion comments 2025-10-09 21:26:03 +08:00
clsty eff8d56ef5 Test commit on dist-arch 2025-10-09 21:18:11 +08:00
clsty a0825e7774 Add workflow notify dist-arch update 2025-10-09 21:17:42 +08:00
Celestial.y 765e370bd5 Update dist-gentoo rm opencv 2025-10-09 19:49:53 +08:00
Celestial.y 8469a07f4f Update dist-gentoo rm opencv 2025-10-09 19:48:33 +08:00
Celestial.y fcf4646928 Update scriptdata/uv/README.md
I hope this is the last commit for this file recently.
2025-10-09 19:43:31 +08:00
Celestial.y f5bbb1747c Update scriptdata/uv/README.md 2025-10-09 19:29:17 +08:00
Celestial.y 1868bffbef Update scriptdata/uv/README.md 2025-10-09 19:24:24 +08:00
jwihardi eb5c6796ae Delete dist-gentoo/illogical-impulse-hyprland/things 2025-10-08 18:32:44 -04:00
darksignal7 a35d128bb5 fix: cookie quote shadow color 2025-10-08 23:45:00 +03:00
darksignal7 74787f8927 center the cookie quote correctly 2025-10-08 23:34:32 +03:00
darksignal7 64455b594b add cookie quote again (you can revert this if you dont want) 2025-10-08 23:30:21 +03:00
darksignal7 aa064fb6c5 fix: 'bubble' date indicator start animation not working 2025-10-08 22:21:50 +03:00
darksignal7 70f3a25798 add animation to 'rect' date style 2025-10-08 21:16:14 +03:00
darksignal7 19230db8b7 fix 'rect' date z layer problem 2025-10-08 20:30:30 +03:00
darksignal7 4fb7f7c1e7 'rect' date respects 'numbers' dial style position 2025-10-08 20:10:21 +03:00
jwihardi 0b20dda56e Merge branch 'end-4:main' into main 2025-10-08 12:05:34 -04:00
darksignal7 5c29ac8d1e 'rotating' date also respects timeIndicators 2025-10-08 19:05:34 +03:00
darksignal7 eeed075be2 make 'numbers' dial and 'rotating' date respect each other on position 2025-10-08 19:00:21 +03:00
darksignal7 6c23d482dd refactor 'rotating' date indicator with repeater/text 2025-10-08 18:53:45 +03:00
Celestial.y b2a7b191cf Update scriptdata/uv/README.md 2025-10-08 23:00:10 +08:00
Celestial.y 95c3cf2c90 Update scriptdata/uv/README.md 2025-10-08 22:55:04 +08:00
Celestial.y 26dc81fc6d Update scriptdata/uv/README.md 2025-10-08 22:51:59 +08:00
Celestial.y 26bab59886 Fix example in scriptdata/uv/README.md 2025-10-08 22:43:15 +08:00
Celestial.y c412090dbc Update scriptdata/uv/README.md 2025-10-08 22:25:47 +08:00
end-4 a4c2bf31c7 use python venv for opencv python scripts (#2143) 2025-10-08 10:01:20 +02:00
jwihardi 5d15ccae9f typo in keywords 2025-10-08 01:43:31 -04:00
jwihardi 63f1954c2a ensure eselect-repository installed and updated checking if guru is enablede 2025-10-07 21:29:58 -04:00
clsty 1fc4b88784 Update comment 2025-10-08 05:56:05 +08:00
clsty aa9b1c3331 Fix weird character causing git take it as binary 2025-10-08 05:53:41 +08:00
Celestial.y 458b086468 Update 1.install-deps-selector.sh 2025-10-08 04:17:15 +08:00
jwihardi 75762e8ddd cp needed sudo 2025-10-07 16:16:03 -04:00
jwihardi 58dbdd5189 fixed typos in useflags 2025-10-07 15:50:47 -04:00
jwihardi 0d3d38a032 updated useflags 2025-10-07 15:43:21 -04:00
darksignal7 68ea59328e change 'rotating' dateStyle radius, fix bubble dateStyle 2025-10-07 21:46:40 +03:00
darksignal7 f74a4f056e refractor each date indicator to a new file 2025-10-07 20:13:37 +03:00
end-4 d70e5c396f date indicator: put each style in a loader 2025-10-07 17:43:37 +02:00
end-4 c70b8f7aa2 fix unqualified access in HourHand 2025-10-07 17:33:18 +02:00
end-4 737dd01c8d make MinuteHand not rely on cascading 2025-10-07 17:31:07 +02:00
end-4 945deafa63 MinuteMarks: resolve some unqualified access 2025-10-07 17:30:43 +02:00
end-4 a77b7f7b66 make MinuteMarks not rely on cascading 2025-10-07 17:24:22 +02:00
end-4 e86a0e23bb remove weird transparency 2025-10-07 16:59:06 +02:00
Celestial.y 6218ffabca Add importance of venv to uv/README.md 2025-10-07 22:42:03 +08:00
Celestial.y 4de3c5e587 Update README.md
This also fixes net::ERR_CONNECTION_RESET for the area blocking github.io
2025-10-07 17:28:12 +08:00
end-4 7dc448938a readme: remove "wiki down" notice 2025-10-07 09:38:54 +02:00
end-4 1c30330faf hyprland: remove fcitx5 exec (#2141) 2025-10-07 09:27:33 +02:00
end-4 40d36c2468 hyprland: env: remove input method env vars (#2141) 2025-10-07 09:23:01 +02:00
end-4 d60113bab9 move fcitx5 config to extras (#2141) 2025-10-07 09:02:08 +02:00
end-4 71a19a86f8 readme: show installation steps with manual cloning 2025-10-07 08:52:39 +02:00
clsty 5385a4834a Use venv for python script 2025-10-07 14:51:45 +08:00
clsty 91b55ad2af Increment rN for dist-gentoo 2025-10-07 14:32:10 +08:00
clsty b1428b34c1 Rm kde-material-you-colors-main from dist-gentoo 2025-10-07 14:25:54 +08:00
Celestial.y 3a5b0af81d Remove kde-material-you-colors from deps-info.md 2025-10-07 13:45:03 +08:00
Celestial.y 1f1a9a0b13 Update scriptdata/uv/README.md 2025-10-07 13:44:21 +08:00
Celestial.y 83c9f98d0a Fix typo 2025-10-07 13:42:27 +08:00
Celestial.y c8f8c85c6e Update scriptdata/uv/README.md 2025-10-07 13:41:51 +08:00
Celestial.y 0c14112d60 Update scriptdata/uv/README.md 2025-10-07 13:22:36 +08:00
Celestial.y aa15572c68 Add README for Python package management
Added instructions for managing Python packages and using virtual environments.
2025-10-07 13:16:11 +08:00
clsty b16e171619 Use uv to install kde-material-you-colors instead
(#1533)
2025-10-07 10:57:46 +08:00
Celestial.y a23551c7f2 Add deps-info.md 2025-10-07 09:57:17 +08:00
clsty 95c2947d4a Add comment. 2025-10-07 08:25:00 +08:00
clsty a87e4ff449 Not backup Steam
This is far from perfect because ideally it should only backup the
possible overwritten destinations.
2025-10-07 08:07:52 +08:00
clsty 8fac9fe67e Add link to commit history online 2025-10-07 07:11:14 +08:00
clsty eafaf78c12 Add warning_rsync() for #2133 2025-10-07 06:59:01 +08:00
end-4 66e40128f8 contributing: add some notes about code 2025-10-06 22:42:10 +02:00
darksignal7 cf303380b6 remove 'rotating' animation (it was ugly imo) 2025-10-06 23:07:55 +03:00
darksignal7 4b6b27a8fd add animation to 'rotating' date style 2025-10-06 23:05:03 +03:00
darksignal7 48f054c809 change classic minuteHand anim 2025-10-06 22:50:46 +03:00
darksignal7 10e25fcd03 fix z layer on timeColumn 2025-10-06 22:24:49 +03:00
darksignal7 35dadbb7c4 add animation to stroke hour hand 2025-10-06 19:53:17 +03:00
darksignal7 29bb41aff0 fix hourHand color (again) 2025-10-06 19:47:09 +03:00
darksignal7 28e6da1bbc fix hourHand color 2025-10-06 19:35:11 +03:00
darksignal7 b9a92507d1 fix right bubble show month number 2025-10-06 19:30:09 +03:00
darksignal7 fc8985b242 animate date bubbles with MaterialCookie on constantlyRotate 2025-10-06 19:25:46 +03:00
darksignal7 924a01bca6 fix the animation when changing clock's side count 2025-10-06 19:01:53 +03:00
darksignal7 fac79c8a7d Dont deselect certain date indicators when selecting specific date styles 2025-10-06 18:48:40 +03:00
darksignal7 0e89e8dcc2 make rotating date indicator rotate with secondHand 2025-10-06 18:41:45 +03:00
darksignal7 594dc64824 change rect date animation and background color 2025-10-06 18:32:02 +03:00
end-4 79ec382b7f osk: fix close button making it not openable again 2025-10-06 16:22:43 +02:00
darksignal7 1ec94aa2a6 make constantlyRotate, rotate in clockwise 2025-10-06 17:08:15 +03:00
darksignal7 70a5343d60 revert back bubble colors 2025-10-06 17:04:58 +03:00
end-4 d88da39fe9 cheatsheet: fix misaligned keybind description 2025-10-06 14:43:26 +02:00
end-4 5f369a511a keybinds: add submap to disable keybinds for vms 2025-10-06 14:37:24 +02:00
Celestial.y afac62e788 Update dist-gentoo/README.md 2025-10-06 19:16:55 +08:00
Celestial.y e4533cc03f Update dist-gentoo/README.md 2025-10-06 19:07:31 +08:00
clsty ee9c4baa9d Remove manual installation from README
No one should actually use it,
considering how complex dist-arch/ is.
2025-10-06 17:16:54 +08:00
end-4 27c36530cb date indicator: use expressive font for bubble date 2025-10-06 10:26:07 +02:00
end-4 a5b80c1c73 there must be a space before { 😭💢 2025-10-06 10:15:46 +02:00
end-4 d6e9e9f2a5 less weird no text selection buttons 2025-10-06 10:09:19 +02:00
end-4 122c1f8e37 make TimeColumn not rely on autocascade, rename centerGlow -> hourMarks 2025-10-06 10:09:06 +02:00
end-4 07a3edf020 move more stuff out of cookie clock file 2025-10-06 09:31:39 +02:00
clsty 299fd4f107 Minor updates about information 2025-10-06 10:01:17 +08:00
clsty 1ae989c0c0 Update dist-gentoo 2025-10-06 07:34:55 +08:00
Celestial.y 4d9323800b Gentoo Install (#2116) 2025-10-06 07:26:25 +08:00
jwihardi e935976c91 Update README to include author information 2025-10-05 18:35:49 -04:00
jwihardi 319680e7cc updated init system error message 2025-10-05 18:33:57 -04:00
jwihardi aa40185058 Update README with tty1 service start instructions
Added instructions for starting services after logging into tty1 using Fish shell.
2025-10-05 18:29:46 -04:00
jwihardi d0e0716221 fixed typo 2025-10-05 18:13:54 -04:00
jwihardi 62e6641480 Create README.md for Gentoo dot-files
Added README.md with installation and setup instructions for Gentoo dot-files.
2025-10-05 18:08:40 -04:00
jwihardi 6c25cc6a78 Merge branch 'end-4:main' into main 2025-10-05 17:43:30 -04:00
jwihardi ec3ac73def added GCC warning print 2025-10-05 17:42:19 -04:00
end-4 9b547d6ece bg clock: move date indicator to new file 2025-10-05 22:20:44 +02:00
end-4 ce1f149547 Merge branch 'main' of https://github.com/darksignal7/dots-hyprland 2025-10-05 21:59:58 +02:00
end-4 394d992b19 bg clock: make number column not look goofy 2025-10-05 21:59:54 +02:00
end-4 b8b3b7993b refractor second hand to new file 2025-10-05 21:59:16 +02:00
darksignal7 915877eba6 fix readability (i hope) 2025-10-05 22:50:55 +03:00
end-4 7dda10629a background clock: refractor hour hand and minute hand to new file 2025-10-05 21:38:03 +02:00
end-4 fc5a5d7f63 fix not being able to use dial dots with date 2025-10-05 21:32:06 +02:00
darksignal7 d2ff23813d fix constantlyRotate breaking side ring count 2025-10-05 22:15:36 +03:00
end-4 06840c6c84 settings: fix weird hidden text of clock indicator 2025-10-05 21:13:26 +02:00
end-4 fda70b0aef add second precision option to settings, make cookie clock use DateTime.clock 2025-10-05 21:02:01 +02:00
end-4 7b13ddcbfc remove quote from cookie clock 2025-10-05 20:49:48 +02:00
end-4 741af0fc43 Merge branch 'main' of https://github.com/darksignal7/dots-hyprland 2025-10-05 20:47:51 +02:00
end-4 abf9b6c5e4 Merge branch 'main' of https://github.com/darksignal7/dots-hyprland 2025-10-05 20:47:26 +02:00
darksignal7 56361dda86 using font in appearance 2025-10-05 21:45:10 +03:00
end-4 d276e7b568 settings: remove redundant enableds 2025-10-05 20:43:13 +02:00
darksignal7 5af0fe35df change the place of the showQuote 2025-10-05 21:40:56 +03:00
darksignal7 94fb563a15 fix weird gaps and indents in InterfaceConfig 2025-10-05 21:39:51 +03:00
end-4 865e8575b2 Revert "remove visible's in config"
This reverts commit 20e1fa935a.
2025-10-05 20:37:15 +02:00
darksignal7 d95147712b readd visible's correctly 2025-10-05 21:36:42 +03:00
darksignal7 20e1fa935a remove visible's in config 2025-10-05 21:34:33 +03:00
darksignal7 f885351464 remove animatedSides, use frameAnimation 2025-10-05 21:33:19 +03:00
darksignal7 33fdc1cdc7 set showQuote false by default 2025-10-05 21:27:01 +03:00
end-4 9d39417142 rename waveAnimation to constantlyRotate, disable by default 2025-10-05 20:19:36 +02:00
end-4 96ed90e2cc add time second precision config option 2025-10-05 20:14:57 +02:00
darksignal7 f99c390a76 fix note being visible on digital clock 2025-10-05 20:57:08 +03:00
darksignal7 fba3a54f82 add a note to date styles 2025-10-05 20:51:02 +03:00
darksignal7 fedeb47dbc make bubble date style work with others 2025-10-05 20:46:28 +03:00
darksignal7 79ac51a1ca add new date style (bubble) 2025-10-05 20:35:24 +03:00
darksignal7 02631da9f1 add hiding animation to hands 2025-10-05 20:07:03 +03:00
darksignal7 692172d57b new classic hand style , settings layout change (are there any better ways?) 2025-10-05 20:02:20 +03:00
darksignal7 8bd4bbe7ea add ability to hide minute and hour hand 2025-10-05 19:24:29 +03:00
zoe chen 0d93f90c62 Use thumbnail or wallpaper for Appearance 2025-10-05 23:51:34 +08:00
darksignal7 3f9459a07e fix centerGlow animation 2025-10-05 17:19:49 +03:00
darksignal7 19d063c3e9 fix second dot/hand animation 2025-10-05 17:17:21 +03:00
darksignal7 7f8a5315c4 make code more readable 2025-10-05 17:10:59 +03:00
darksignal7 0f7f7d997b seperate waveAnimation from the materialCookie component 2025-10-05 16:49:47 +03:00
darksignal7 ab54a24434 make center glow active on full dial style 2025-10-05 16:43:13 +03:00
darksignal7 77901659e5 add a lil animation when changing hour hand style 2025-10-05 16:39:25 +03:00
darksignal7 b3f74b6c1c change date color 2025-10-05 16:22:12 +03:00
darksignal7 7eb5fa8d8e add hour hand style 2025-10-05 16:17:37 +03:00
darksignal7 a90e2132e3 add new dial style 2025-10-05 15:57:01 +03:00
darksignal7 60b0db7120 lil tweaks 2025-10-05 14:13:13 +03:00
darksignal7 af538950a8 a lil font change 2025-10-05 13:49:39 +03:00
darksignal7 5787e95c51 add new date style and bunch of new animations 2025-10-05 13:38:53 +03:00
Sighthesia 3b3be4b6cb fix error option name 2025-10-05 17:52:23 +08:00
Sighthesia c1fa902189 bar: change shadow to configurable 2025-10-05 17:48:01 +08:00
Sighthesia 31706e2724 config: add floatSytleShadow option 2025-10-05 17:42:25 +08:00
end-4 21d6bcc63e Brightness: brightnessctl target backlight class 2025-10-05 10:27:20 +02:00
end-4 c4ad1a7127 Translation : update zh_CN and en_US (#2124) 2025-10-05 09:51:06 +02:00
clsty 17984344ee Use arg_excludes for rsync 2025-10-05 10:26:43 +08:00
clsty 035a58e7c5 Update comment 2025-10-05 10:05:29 +08:00
Woozepao 646e33e59f Update .config/quickshell/translations/zh_CN.json
Co-authored-by: Celestial.y <celestial.y@outlook.com>
2025-10-04 19:30:19 -05:00
Woozepao 68ddfb0f02 Update .config/quickshell/translations/zh_CN.json
Co-authored-by: Celestial.y <celestial.y@outlook.com>
2025-10-04 19:30:13 -05:00
darksignal7 cd3b8b5bab add icon to date 2025-10-05 03:13:48 +03:00
darksignal7 da88fd4267 minor tweaks 2025-10-05 03:08:39 +03:00
darksignal7 29413fdc8e hide settings when digital clock is selected 2025-10-05 02:24:36 +03:00
darksignal7 c643d26bce add date to clock 2025-10-05 01:55:39 +03:00
woozepao 69d4f32933 update zh_CN.json 2025-10-04 17:52:13 -05:00
woozepao 26154a6cdb update en_US.json 2025-10-04 17:51:57 -05:00
woozepao 7b22553f09 change qsTr to Translation.tr. support translation 2025-10-04 17:51:24 -05:00
darksignal7 9726f0f586 change settings layout, add option for minuteHand and more.. 2025-10-05 01:40:07 +03:00
darksignal7 25f6f09d22 typo fix 2025-10-04 19:54:04 +03:00
darksignal7 3e6a68b472 fix multiline quote 2025-10-04 19:50:51 +03:00
end-4 60e18c4854 hyprland: remove window cycle keybind
interferes with my vm when i don't capture keys
2025-10-04 17:33:10 +02:00
darksignal7 f7633dd61f add secondDot , fix settings layout little more 2025-10-04 18:13:06 +03:00
darksignal7 ae74354140 fixed bad settings layout, still could be better though 2025-10-04 17:48:19 +03:00
darksignal7 b0987b224d added center glow , wave animation etc. 2025-10-04 17:28:30 +03:00
clsty 5ecae9662f Add --skip-allgreeting 2025-10-04 22:26:40 +08:00
darksignal7 0f29869a76 change settings layout a little 2025-10-04 14:58:32 +03:00
darksignal7 67dd730666 add icons to settings 2025-10-04 14:36:30 +03:00
darksignal7 ccaa13fa21 add animation to cookie clock quote 2025-10-04 14:20:02 +03:00
Vague Syntax ff795b1373 Merge branch 'main' into main 2025-10-04 13:58:36 +03:00
end-4 81287e9eb5 settings: more icons 2025-10-04 12:54:34 +02:00
darksignal7 26b9d8193c add settings for clock, add quote for cookie clock, make quote editable from settings 2025-10-04 13:47:40 +03:00
end-4 81bdb352aa overview: fix dragging z index (#2068) 2025-10-04 12:27:16 +02:00
end-4 2ae8530c83 Set background opacity when using live wallpaper (#2114) 2025-10-04 10:30:38 +02:00
end-4 476755fc18 settings: add toggles for lock screen security options 2025-10-04 09:55:57 +02:00
jwihardi 4247495cf4 added init system error message 2025-10-03 21:34:29 -04:00
jwihardi b6eada070a Merge branch 'end-4:main' into main 2025-10-03 21:33:10 -04:00
darksignal7 2399600169 minimize settings 2025-10-04 01:09:25 +03:00
jwihardi db9877beae Delete dist-gentoo/keywords-user 2025-10-03 16:04:02 -04:00
darksignal7 43f1d5c53e finalize simpler cookie clock 2025-10-03 22:38:20 +03:00
jwihardi 4a31d538c6 added liveebuilds 2025-10-03 14:40:51 -04:00
zoe chen 23dd7baf35 Set background opacity when using live wallpaper
It was causing thumbnail to display over mpvpaper
2025-10-04 01:43:32 +08:00
darksignal7 a8e1f3ef4c added simpler cookie clock style 2025-10-03 19:19:21 +03:00
jwihardi cd622e9f81 added gentoo install 2025-10-02 22:43:39 -04:00
end-4 71f7d45084 feat: add hebrew language support (#2099) 2025-10-03 01:06:30 +02:00
end-4 0f586fe49e Update auto-Hypr.fish (#2106) 2025-10-03 01:04:42 +02:00
end-4 42913816ce lock: add option to require password for poweroff/reboot (#2085) 2025-10-03 01:02:03 +02:00
end-4 027f9a1793 hyprlandxkbindicator: don't reference the button out of nowhere 2025-10-03 00:50:35 +02:00
Jojo 8bc2cf335b lock: add reboot button (#2086)
* lock: added reboot button

* lock: reorder reboot/shutdown buttons

---------

Co-authored-by: end-4 <97237370+end-4@users.noreply.github.com>
2025-10-02 23:39:20 +02:00
jwihardi 626c71a942 Merge branch 'end-4:main' into main 2025-10-02 17:06:46 -04:00
Khyretos 58b9c4f1d6 Update auto-Hypr.fish
Autologin fix for fish
2025-10-02 20:52:48 +02:00
Sighthesia 24163dfa4a bar: fix float bar tint loss 2025-10-03 01:34:51 +08:00
clsty e3d596e034 Add TODO in comment 2025-10-03 00:30:18 +08:00
clsty cd48f45462 Del chmod +x in update.sh targeting scriptdata
Although I am not the one creating update.sh,
I am certain that giving execute permission for
scripts under scriptdata/ is wrong cuz
they are not for executing independently,
but for being sourced by other scripts.
2025-10-03 00:10:45 +08:00
clsty a0229e8132 Fix comment. 2025-10-03 00:03:41 +08:00
clsty be7ff94ae3 Fix comment 2025-10-02 23:56:38 +08:00
clsty 98ddce24ad Re-arrange scripts; fix comments in dist-nix 2025-10-02 23:51:59 +08:00
clsty b380a77a7d Add outdate detect logic for dist-<DISTRO-ID> 2025-10-02 20:56:43 +08:00
clsty 9f7a2d86cf No hash, just timestamp 2025-10-02 18:55:33 +08:00
clsty 343a7ef4fe Add git_unshallow and latest_commit_hash 2025-10-02 18:47:14 +08:00
clsty 88c3b0ba83 Remove old ags entries from .gitignore 2025-10-02 16:48:45 +08:00
clsty 918997acfa Rearrange install scripts.
This commit is a preparation for detection about
whether a dist-<DISTRO_ID>/ folder is outdated.
2025-10-02 16:38:43 +08:00
jwihardi dd1fb111a5 updated the script and added unmask file 2025-10-01 22:12:17 -04:00
jwihardi 7124b69912 renamed gentoo-ebuild to gentoo-support 2025-10-01 19:56:55 -04:00
jwihardi 76bcca55d2 Merge branch 'end-4:main' into main 2025-10-01 19:55:06 -04:00
jwihardi 7fa2ffc14e added an installer and use flags 2025-10-01 19:54:04 -04:00
clsty 0ee141493f Improve message. 2025-10-02 07:39:15 +08:00
clsty 194b21c41e Improve message. 2025-10-02 07:26:59 +08:00
clsty 93634985e8 Fix $2100 2025-10-02 07:24:02 +08:00
clsty 6757dc2ca1 Fix $2101 2025-10-02 07:20:25 +08:00
clsty 3a888f9be4 Add pause(); distro specific also for setups 2025-10-02 07:13:51 +08:00
clsty 34c9cbeedb Tweaks for text and names 2025-10-02 05:54:35 +08:00
Ofek 97a2769002 Update translation for 'Silent' in Hebrew 2025-10-01 22:17:59 +03:00
clsty f87e6e2b6a Update message in install-deps.sh 2025-10-02 02:41:48 +08:00
clsty 7bd3f1e08d Update comment. 2025-10-02 02:31:44 +08:00
Ofek Almog aeb20a8949 feat: add hebrew language support 2025-10-01 21:30:44 +03:00
clsty 58e99403ad Add comment. 2025-10-02 02:24:11 +08:00
clsty 530987152c Fix message in uninstall.sh 2025-10-02 02:12:07 +08:00
clsty 4085b4a74a Improve dependency install process 2025-10-02 01:57:20 +08:00
clsty 852172a7ff Add distro and arch detect, add skip options 2025-10-02 00:35:33 +08:00
clsty 7aa1230553 Rename scripts for syntax highlighting 2025-10-01 21:49:46 +08:00
clsty a7097014a3 Quick fix syntax 2025-10-01 21:44:06 +08:00
clsty 9f711c20e0 Use variable to store color for script output 2025-10-01 21:40:06 +08:00
clsty 87c031b825 Rearrange install.sh to split Arch thingy apart 2025-10-01 20:44:25 +08:00
end-4 18e2f5dd7f Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-10-01 08:15:09 +02:00
end-4 d1b70185f1 styledtext: fix letter spacing (#2092) 2025-10-01 08:15:07 +02:00
end-4 254175c98e fix: ignore case (The latest Hyprland process name has changed) (#2087) 2025-10-01 06:36:55 +02:00
jwihardi e8e67912ec Merge branch 'end-4:main' into main 2025-09-30 19:35:49 -04:00
end-4 3c00805763 lock: also unlock keyring on unlock 2025-09-30 23:07:04 +02:00
end-4 599055b49f search: add /wipeclipboard action 2025-09-30 20:47:44 +02:00
end-4 82fa754497 ai: ctrl+v to attach file
note: only convenient with dolphin
2025-09-30 20:47:10 +02:00
cyclesw 9ec9cc0e25 fix: ignore case (The latest Hyprland process name has changed) 2025-10-01 01:36:57 +08:00
end-4 f52c9415c9 fix(brightness): prevent bus number collision for identical monitor m… (#2077) 2025-09-30 08:39:36 +02:00
end-4 27626ee59a ai: simplify auto scroll (#2080) 2025-09-30 07:58:54 +02:00
end-4 0b36e2a833 lock: do not autostart after crash 2025-09-30 07:45:10 +02:00
Kacper Piłsyk 1aa0e3fb47 fix(brightness): prevent bus number collision for identical monitor models 2025-09-29 23:27:28 +02:00
end-4 4a40ce5646 idle inhibitor: only remember toggled state within same session 2025-09-29 22:47:57 +02:00
end-4 6e126dc08d lock: option to launch on startup (#2076) 2025-09-29 22:21:09 +02:00
end-4 6201798ef5 ai: ctrl+shift+o to clear 2025-09-29 10:28:54 +02:00
end-4 ec3c09607d bar: fix misaligned items for horizontal floating mode (#2075) 2025-09-29 08:20:15 +02:00
Sola 2b104435dc fix overview scaling issue 2025-09-29 07:59:42 +08:00
end-4 83be5822b1 add random osu seasonal wallpaper button 2025-09-28 20:50:21 +02:00
end-4 0491bd993e overview: floating window position move 2025-09-28 20:48:59 +02:00
end-4 8713e94428 screenshot tool: make dark overlay clipped by selection, add selection size indicator 2025-09-28 18:44:05 +02:00
end-4 ccab724db2 screenshot tool: fix interactivity of floating windows being behind tiled 2025-09-28 18:16:14 +02:00
end-4 7876ab993a settings: remove unnecessary page check for anim 2025-09-28 18:05:31 +02:00
end-4 bd8e004795 osd: unify brightness and volume 2025-09-28 18:04:57 +02:00
end-4 01ab0f5ab9 cheatsheet: ptable: make elements not look weird when hovered 2025-09-28 16:57:32 +02:00
end-4 0728dba0cd cheatsheet: added element weight to periodic table (#2067) 2025-09-28 16:52:45 +02:00
end-4 3dd5e78b35 overview: force floating windows to be on top of tiling ones (#2068) 2025-09-28 16:43:43 +02:00
nrand 667afa6d64 cheatsheet: added element weight to periodic table 2025-09-28 15:25:59 +03:00
end-4 d24555a4d7 bar: workspaces: no more Layout 2025-09-28 14:25:52 +02:00
end-4 410971a228 scroll hint: no more Layout, add tooltip 2025-09-28 14:14:43 +02:00
end-4 b497c22d6b overview: fewer Layouts 2025-09-28 14:07:50 +02:00
end-4 de6969f561 bar: fix tooltip shadow cutoff, use fewer Layouts 2025-09-28 14:03:18 +02:00
end-4 0ce4260134 background: fewer Layouts 2025-09-28 13:53:27 +02:00
end-4 7237dd053d lock: use Rows instead of RowLayouts 2025-09-28 13:47:40 +02:00
end-4 0f6c076dda use more non-Layouts 2025-09-28 13:42:44 +02:00
end-4 b57e678dc9 notifications: fix ultra laggy expansion 2025-09-28 13:15:23 +02:00
end-4 6031bb4953 left sidebar: consider closed when floating window is closed 2025-09-28 12:05:42 +02:00
end-4 05dc53b396 use StyledImage in more places 2025-09-28 11:52:35 +02:00
end-4 e97f819a5c make night light auto still function after manual toggle (#2030) 2025-09-28 11:33:58 +02:00
end-4 28c37c08d2 make media control seekable (closes #1615) 2025-09-28 10:45:16 +02:00
end-4 f430b22884 fix shadow radius 2025-09-28 10:39:56 +02:00
end-4 cf4505635b toolbar: add make radius configurable 2025-09-28 08:39:59 +02:00
end-4 8ad0de63e1 Fix various issues of overview with multiple monitors setup (#1953) 2025-09-28 08:35:41 +02:00
end-4 8068ea95d5 truncate xkb variants to avoid text overflow (#2032) 2025-09-28 08:26:29 +02:00
end-4 44cbd025f4 correct indentation, remove unnecessary check 2025-09-28 08:25:48 +02:00
jwihardi ac76930dd1 Merge branch 'end-4:main' into main 2025-09-27 00:04:30 -04:00
jwihardi 3a653d9558 renamed folder 2025-09-26 20:03:31 -04:00
jwihardi ae50430527 added gentoo ebuild 2025-09-26 20:02:44 -04:00
end-4 83386bcdbf overviewwidget: fix undefined warning 2025-09-26 23:56:31 +02:00
end-4 1e175e4e82 work safety for clipboard images copied from browser 2025-09-26 23:56:13 +02:00
end-4 01815d04dc remove unused shaders 2025-09-26 23:05:34 +02:00
end-4 46ea6900b4 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-09-26 22:55:21 +02:00
end-4 6394fe049d notifications: prevent summaries from spilling 2025-09-26 22:55:14 +02:00
end-4 f324fc7c10 readme: push unsupported stuff down 2025-09-26 10:21:19 +02:00
end-4 434c383fcd remove deprecated label from ags version, its totally unsupported now 2025-09-26 09:49:49 +02:00
end-4 9eade626aa overview: fix large vertical tooltip padding 2025-09-25 09:49:22 +02:00
end-4 263299b97d SearchItem: fix undefined warnings 2025-09-24 09:25:36 +02:00
end-4 7e491ce7d8 settings: adjust min window size 2025-09-24 09:25:29 +02:00
end-4 6707487d3c background: fix clock movement jumping abruptly 2025-09-24 08:29:04 +02:00
end-4 0498d7ea98 overview: clearer numbers 2025-09-23 21:36:09 +02:00
end-4 fc9bda9f7f add scroll edge fade to some scrolled windows 2025-09-23 11:14:34 +02:00
end-4 2b47083c12 settings, welcome: change konachan btn icon, fix wallpaper desync 2025-09-23 11:14:00 +02:00
end-4 1f700f33b2 cookie clock: put color props to root 2025-09-23 11:13:18 +02:00
end-4 769dafb428 move adapted material scheme to new file 2025-09-23 11:13:00 +02:00
end-4 e3bc2e5d84 more wallpaper safety filters 2025-09-23 11:12:22 +02:00
end-4 f3120f1e0d background: fix cookie clock positioning when locked + wall safety 2025-09-22 21:54:15 +02:00
end-4 036d8b4852 lock: allow centering clock when not blurred 2025-09-22 21:50:25 +02:00
end-4 a67a8d746f background: add scale config option for clock 2025-09-22 21:04:31 +02:00
end-4 2237ec135c background: add cookie clock style 2025-09-22 20:25:46 +02:00
dodaars a238c33fd0 A simple function to slice keyboard variants to avoid overflow of text when using vertical bars
I added a function that slices keyboard variants to be at most 4 characters long to avoid text overflow, especially when you set the bar to be vertical.
2025-09-21 23:54:12 +02:00
end-4 b90cf14228 add random wallpaper keybind 2025-09-21 20:21:34 +02:00
end-4 7bbd1d2d52 fix(ai): Fix JSON injection vulnerability in primary-buffer-query.sh (#1973) 2025-09-21 20:04:15 +02:00
end-4 8aebbb1b51 feat(ai): Add auto-scroll functionality to AI chat (#1972) 2025-09-21 19:51:38 +02:00
end-4 df7504d4a2 remove useless ai comments 2025-09-21 19:51:15 +02:00
end-4 063399a6d6 settings: make crosshair code setting less misleading 2025-09-21 18:57:38 +02:00
end-4 9762a94138 notifications: make icon guesses less strict 2025-09-21 18:57:27 +02:00
end-4 800f5c7c64 background: fix locked text spacing when there is no quote 2025-09-21 13:59:20 +02:00
end-4 16995d2ae5 wallpaper safety 2025-09-21 12:08:09 +02:00
end-4 b4cced68f1 Change SCSS file path emacs theme thingy 2025-09-21 11:03:37 +02:00
end-4 9bb01bba30 update hyprland config for crosshair 2025-09-21 10:37:12 +02:00
end-4 cb3842f0bd implement crosshair 2025-09-21 10:33:25 +02:00
end-4 5d95d20a32 sidebarright: remove unused imports 2025-09-21 10:31:21 +02:00
end-4 b628ee0c3e fix hyprland xkb indicator cant unassign undefined warning 2025-09-21 10:31:10 +02:00
end-4 688bf0bef8 bar: refractor xkb layout indicator 2025-09-20 23:18:41 +02:00
end-4 06d6d3a9ca bar: adjust xkb layout indicator font size 2025-09-20 13:05:23 +02:00
end-4 bb4debb863 bar: fixed kb layout+variant display in top right (#2016) 2025-09-20 13:02:49 +02:00
end-4 5d1a3fe6a7 hyprland xkb layout indicator: fix weird placement on vertical bar 2025-09-20 13:02:18 +02:00
end-4 72b5d006ba vertical bar: make tray tooltips not cut off 2025-09-20 12:47:04 +02:00
end-4 d382358766 bar: tray: make action trigger on press 2025-09-20 12:40:58 +02:00
end-4 429cb50ff7 tooltips: use builtin text prop, fix crash (#1956) 2025-09-20 11:55:38 +02:00
end-4 3a01dad945 aloow configuration of notif timeout duration 2025-09-20 10:47:09 +02:00
end-4 b9ae5cafa0 brightness: delay setting for ddc monitors (#2022) 2025-09-20 10:37:24 +02:00
end-4 ed8e4b8766 move some files placed in the wrong folder 2025-09-20 10:11:35 +02:00
end-4 cecd47caea make filled symbols suck less 2025-09-20 10:08:02 +02:00
end-4 7711946cf5 bar: remove unused imports 2025-09-20 09:50:15 +02:00
end-4 074aebbe5d tray: fix checkbuttons' clickability in menus 2025-09-20 09:49:57 +02:00
end-4 8b78d05805 background: fix clock position 2025-09-20 09:49:34 +02:00
end-4 cf962a26f4 workspaces: fix some undefined thingy 2025-09-20 09:31:26 +02:00
end-4 14778696e9 custom system tray 2025-09-20 09:30:17 +02:00
nrand ed56d03c09 bar: actually fixed it (there was a typo oopsie) 2025-09-19 07:58:12 +03:00
end-4 f9d9df4bbf lock screen blur: fix center clock option, add settings app toggles 2025-09-18 14:07:21 +02:00
nrand 0859d75256 bar: fixed kb layout+variant display in top right 2025-09-18 15:03:41 +03:00
end-4 21303b24c8 welcome app: add tip for window close keybind 2025-09-18 08:18:10 +02:00
end-4 06965e7eed Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-09-18 08:13:07 +02:00
end-4 fc0b069ad2 media: progress update interval follows resources 2025-09-18 08:12:52 +02:00
end-4 b0b27d6842 feat(sideright): add Flatpak support for EasyEffects service and toggle (#2013) 2025-09-18 08:08:44 +02:00
end-4 47725ea4b5 bar: fix autohide's hover region not working on hyprland 0.51 (#1994) 2025-09-18 07:52:08 +02:00
0blivi0nis 103d349c5f feat(sideright): add Flatpak support for EasyEffects service and toggle 2025-09-17 23:49:45 +00:00
end-4 c41364fb16 lock: rename bg blur config option, no blur by default 2025-09-17 23:39:56 +02:00
end-4 b984d6794e wallpaper selector: fix thumbnail generation (#1978, #1902) 2025-09-17 11:35:42 +02:00
end-4 cf4aa1256d wallpaper selector: make quick dir icon filled when selected 2025-09-16 08:32:07 +02:00
end-4 4a6fcb4f4c wallpaper selector: hide Homework folder if not weeb, fix toolbar button alignment 2025-09-16 08:30:30 +02:00
end-4 426804304c wallpaper selector: add random button (#1997) 2025-09-16 08:22:47 +02:00
end-4 074f8ed902 wallpaper selector: allow making system picker the default 2025-09-15 21:52:58 +02:00
end-4 d3a1bd52c7 more readable terminal colors by default 2025-09-15 21:51:42 +02:00
end-4 a4103859cd lock: hide color overlay when unlocking in light mode 2025-09-15 08:32:04 +02:00
end-4 ed19b7b635 lock screen: blur effect, better anims 2025-09-14 22:53:55 +02:00
end-4 f21dd041ae add StyledBlurEffect 2025-09-14 22:46:35 +02:00
end-4 2de21b5f25 tray: hide "passive" items (#1987) 2025-09-14 21:05:17 +02:00
end-4 a547ae6cf9 hyprland dead edge problem: use old hyprland hotspot padding 2025-09-13 22:55:18 +02:00
end-4 c39901e95d icon guessing: add quickshell's heuristic lookup 2025-09-13 22:13:43 +02:00
end-4 4f0522d913 idle inhibitor: use quickshell instead of pythong script 2025-09-13 22:03:03 +02:00
end-4 b972d3fabe Translation : update zh_CN.json (#1975) 2025-09-13 09:33:07 +02:00
czn d6bef6b17d Translation : update zh_CN.json 2025-09-12 22:22:07 +08:00
czn 231100cbdc Translation : update zh_CN.json 2025-09-12 21:50:24 +08:00
end-4 9c8d71ca4d wallpaper selector: back/forward navigation 2025-09-12 08:09:12 +02:00
end-4 fcdc17dd93 dead pixel workaround: also for bottom edge 2025-09-12 08:08:39 +02:00
Gwendolyn Page a719ca684c fix(ai): Fix JSON injection vulnerability in primary-buffer-query.sh
- Fix critical JSON injection vulnerability by properly escaping clipboard content using jq
- Add content length limiting (2000 chars) to prevent overflow attacks
- Use proper JSON payload construction with jq to ensure safe API calls
- Add silent curl flag and error handling for reliability

This addresses a security issue where malicious clipboard content could break
out of JSON strings and potentially execute arbitrary code.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 17:49:10 -05:00
Gwendolyn Page e5033c3213 feat(ai): Add auto-scroll functionality to AI chat
- Add shouldAutoScroll property to track when user wants auto-scrolling
- Auto-scroll when user sends a message to see the response
- Auto-scroll during streaming when content height changes
- Auto-scroll when new messages are added to the conversation
- Stop auto-scroll when user manually scrolls up (preserves user intent)
- Resume auto-scroll when user scrolls back to bottom

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 17:20:28 -05:00
end-4 d37cf9e9c4 fix(brightness): use the monitor's max brightness instead of '100' (#1966) 2025-09-11 23:28:29 +02:00
end-4 d9688884e4 Rename maxBrightness to rawMaxBrightness
less confusing because `brightness` is percentage
2025-09-11 23:27:14 +02:00
end-4 2f369bbf3d fix setting brightness with brightnessctl 2025-09-11 23:25:06 +02:00
end-4 7f1b67d21c lock: hide battery display on desktops 2025-09-11 19:31:43 +02:00
end-4 6118589248 workaround for hyprland's 1px dead right edge 2025-09-11 15:48:44 +02:00
Emmmmllll 9a7f5c2def fix(brightness): use the monitor's max brightness instead of '100' 2025-09-11 14:26:38 +02:00
end-4 1999f17443 wallpaper selector: fix incorrect address bar 2025-09-11 10:03:34 +02:00
end-4 7e39f0a34f bar: make tray items pinned by default 2025-09-11 09:59:05 +02:00
end-4 fb9a726ba0 bluetooth dialog: sort names before mac addresses 2025-09-11 09:48:13 +02:00
end-4 ddc3f0e880 hyprland: add window move and overview gestures 2025-09-11 08:46:46 +02:00
end-4 d66b0891e7 hyprland: adapt new gesture config (#1892) 2025-09-11 07:48:48 +02:00
cupcat121 f1ba087bff fix wrong monitor data being passed to OverviewWindow 2025-09-11 00:29:44 +08:00
end-4 6cf5f2edc4 RoundCorner: remove unnecessary and not properly imported anim 2025-09-09 21:38:08 +02:00
end-4 f0570b0e20 fix kb layout anim in lock screen (#1942) 2025-09-09 20:34:49 +02:00
cupcat121 cd851afc8d remove TODO 2025-09-09 19:08:29 +08:00
cupcat121 532497f6bd fix out of index error in OverviewWindow monitorData 2025-09-09 14:14:34 +08:00
end-4 f648137a8e hyprland: not have redundant lid close suspend keybind bind (fixes #1929) 2025-09-08 23:27:00 +02:00
end-4 e9fd2f89fe StyledText: fix text being offset with rapid change (#1942) 2025-09-08 23:13:43 +02:00
end-4 5565911e2c battery: prevent auto suspend due to low bluetooth batt (#1882) 2025-09-08 23:07:52 +02:00
end-4 7337012280 background: no smoothing 2025-09-08 22:36:24 +02:00
end-4 e3f25e3bc4 Feat: Add option to enforce dark mode for the terminal (#1945) 2025-09-08 22:35:14 +02:00
cupcat121 9582a473c6 revert applycolor.sh and rewrite the main logic 2025-09-08 20:24:06 +08:00
cupcat121 22918e4b4a move config to terminalGenerationProps 2025-09-08 18:46:52 +08:00
cupcat121 0d567ea5dc Merge remote changes 703697e1 2025-09-08 18:01:59 +08:00
end-4 703697e1c4 settings & welcome: add icons to policies 2025-09-08 09:18:09 +02:00
end-4 0b89ed0d17 tray: use more descriptive text for tooltip and update on entry (#1906) 2025-09-08 09:13:05 +02:00
Moeta Yuko f3de317ddd tray: use more descriptive text for tooltip and update on entry
The systray id is intended for programmatic use rather than frontend
presentation. It is recommended to use the tooltipTitle and title
attributes when available, and these should be updated upon entry, as
their values may change dynamically.
2025-09-08 14:46:42 +08:00
end-4 cd7e60b7a1 hyprland: make snapping gap consistent with tiling gap 2025-09-08 08:40:18 +02:00
end-4 352a5bea5c Make window snap respect window gaps (#1950) 2025-09-08 08:37:09 +02:00
end-4 f33eaf6d0f settings: add advanced terminal color generation props 2025-09-07 22:53:18 +02:00
end-4 81ebf9cc11 settings: move some settings to new "general" tab 2025-09-07 22:33:41 +02:00
end-4 23f92e0a96 hyprland: more blur noise 2025-09-07 22:28:27 +02:00
kxrur e69f8ced88 make snap repsect window gaps 2025-09-07 13:31:05 -04:00
end-4 ba5b052ee8 readme: add note about availability of installation methods n stuff 2025-09-07 09:39:13 +02:00
end-4 b6e6997e7c Customize harmony values for colors from wallpaper (#1910) 2025-09-06 10:38:33 +02:00
end-4 c39507747b rename generationProps -> terminalGenerationProps, change default harmony to match script 2025-09-06 10:38:15 +02:00
end-4 c9f4390f0f Feature: Hide online models on local ai policy (#1784) 2025-09-06 10:20:08 +02:00
end-4 801cd2e855 only show konachan button and create homework folder when weeb 2025-09-06 09:44:46 +02:00
end-4 e9c73ebb71 readme: update ii-qs showcase 2025-09-06 09:23:03 +02:00
end-4 6af3a1b5a7 (vertical) bar: refractor workspaces 2025-09-06 08:44:39 +02:00
end-4 c86dbeb2b3 lock: key presses also reset inactivity timer 2025-09-06 08:44:25 +02:00
cupcat121 4ff6b2a30a update en_US translation 2025-09-06 12:21:07 +08:00
cupcat121 3310d2b431 update zh_CN translation 2025-09-06 12:07:20 +08:00
cupcat121 b53de43c95 add forced theming mode for terminal 2025-09-06 12:07:20 +08:00
cupcat121 ffb8e284b4 add config to force terminal theming mode 2025-09-06 12:07:19 +08:00
end-4 f593ad0f2c make selection buttons less weird with cjk 2025-09-05 23:34:50 +02:00
end-4 9114d5b2fe NavigationTabArray: fix undefined warning 2025-09-05 23:34:40 +02:00
end-4 5b47a20d49 scrollbar: add to stuff, adjust draggable spacing 2025-09-05 23:34:20 +02:00
end-4 b0acc5a68e translations: make language change happen live 2025-09-05 23:31:08 +02:00
end-4 d7382db669 ai: fix chat.json doesn't exist warning 2025-09-05 21:17:01 +02:00
end-4 f290192de4 disable earbang protection by default 2025-09-05 20:30:18 +02:00
end-4 8360d4d589 animate xkb layout indicator change 2025-09-05 14:54:21 +02:00
end-4 df56224df6 lock screen: add kb layout indicator 2025-09-05 13:07:44 +02:00
end-4 1a636ff8e9 clock tooltip: not show redundant time 2025-09-05 13:06:44 +02:00
end-4 4dcc1f340f lock: animate left pill appearance too 2025-09-05 08:08:43 +02:00
end-4 f199bc4256 lock screen: battery level 2025-09-05 08:05:52 +02:00
end-4 11e28286e1 lock: fix sleep button color 2025-09-05 07:53:37 +02:00
end-4 4c454d463a fish: move setups to interactive shell 2025-09-03 11:51:25 +02:00
end-4 80034d8658 background: add auto vertical parallax option 2025-09-02 19:57:17 +02:00
end-4 296afa96c6 wallpaper selector: dont cache thumbnails 2025-09-02 19:50:15 +02:00
end-4 9f69b8815a settings: more icons 2025-09-01 22:19:16 +02:00
end-4 cdc38f7e6e settings: redesign home page 2025-09-01 18:05:45 +02:00
end-4 fcb4e6cc85 bar: always show cpu usage by default 2025-09-01 18:05:14 +02:00
end-4 cb00f31f79 readme: no more ags support 2025-09-01 13:47:13 +02:00
end-4 84c65d32be add dolphin config 2025-09-01 11:17:53 +02:00
end-4 cc119bb596 add darkly config 2025-09-01 11:13:13 +02:00
end-4 88c9850073 settings: make pages fly up 2025-09-01 11:05:00 +02:00
end-4 75fcb9a990 welcome app: add tip for broken color changing 2025-09-01 10:51:10 +02:00
end-4 7121a4ae30 disable transparency by default (why was this even on...) 2025-09-01 08:39:10 +02:00
end-4 e636920c44 search: clipboard: nicer delete button, add copy button 2025-08-31 17:57:16 +02:00
end-4 e0cf3d0962 notifications: add group expand tip tooltip 2025-08-31 17:29:06 +02:00
end-4 53b6f5d8e8 add superpaste 2025-08-31 17:21:55 +02:00
Souyama 5acbfac255 terminals harmony pass into args 2025-08-31 19:59:52 +05:30
Souyama 82bb1175bd customize terminals harmony 2025-08-31 19:57:49 +05:30
end-4 f1b1589a7d use JetBrains Mono instead of SpaceMono for nerd font 2025-08-31 14:35:17 +02:00
end-4 0f4ff90f01 add setting to show/hide the clock in background (#1881) 2025-08-31 13:06:16 +07:00
end-4 43e0bcbf73 Merge branch 'main' into background-clock-setting 2025-08-31 13:05:04 +07:00
end-4 e26045ec73 background: clock size: safer access 2025-08-31 08:04:23 +02:00
end-4 2d52680bed make time correct after waking up from suspend (fixes #1905) 2025-08-31 07:56:12 +02:00
end-4 f42f526f93 fix more bluetooth warning 2025-08-31 07:54:46 +02:00
end-4 53b03af3e1 wifi menu: fix undefined warnings 2025-08-30 22:14:32 +02:00
end-4 32f8692f13 toolbar: adjust spacing 2025-08-30 22:10:47 +02:00
end-4 19c321e7ae wallpaper selector: progress indicator for thumbnail generation 2025-08-30 22:10:29 +02:00
end-4 021a49a72d wifi & bluetooth dialogs: indeterminate progressbar while scanning 2025-08-30 22:09:05 +02:00
end-4 eb0bad1af6 wallpapers: add fallback magick thumbnailer script 2025-08-30 17:47:37 +02:00
end-4 513d140ea2 wallpaper selector: paste directory/file to navigate 2025-08-30 16:39:13 +02:00
end-4 3e368141c7 bluetooth menu: round battery level 2025-08-30 15:54:11 +02:00
end-4 b59b7c1e47 bar: add workspace number mapping (#1886) 2025-08-30 20:03:16 +07:00
end-4 6a1acc819b workspace numbers: allow using nerd font 2025-08-30 15:01:59 +02:00
end-4 e5db36e21e workspace number mapping: rename config var, use list 2025-08-30 14:59:11 +02:00
end-4 d759bc274f bluetooth menu: right click to expand item 2025-08-30 14:34:32 +02:00
end-4 3290755fa8 wallpaper selector: correct search box placeholder 2025-08-30 09:28:11 +02:00
end-4 fd3455d3ec wallpaper selector use Toolbar for name filter 2025-08-30 09:09:05 +02:00
end-4 88355b2504 lock: use default pam config and start without password (#1891) 2025-08-30 13:52:25 +07:00
end-4 79f078653a bluetooth menu: stop scanning when closed, fix null warnings 2025-08-30 07:55:29 +02:00
end-4 a952ea02dc bluetooth menu 2025-08-30 07:51:18 +02:00
end-4 59abffb1c1 background: fix empty space between clock and lock text 2025-08-30 07:48:21 +02:00
Moeta Yuko d737139bee hyprland: adapt new gesture config 2025-08-29 16:08:55 +08:00
Moeta Yuko a1479a9b6c lock: use default pam config and start without password
Fixes #1800
2025-08-29 15:55:36 +08:00
kirisaki-vk 45894c3255 chore: use var instead of list 2025-08-29 09:51:08 +03:00
end-4 dcfdb2ecff Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-08-29 08:16:53 +02:00
end-4 ba7ed5be1c background: fix quote not working 2025-08-29 08:03:01 +02:00
end-4 307412e6ca fix: improve Japanese translations for clarity and consistency (#1889) 2025-08-29 12:40:01 +07:00
end-4 41e1e89696 sidebar: wifi menu: public wifi login page button 2025-08-29 07:29:14 +02:00
end-4 d239ab6b1f bluetooth: refractor and fix wrong icon 2025-08-29 12:06:01 +07:00
rain022 0905773d08 I've made a slight adjustment to the nuance.
It should be fine to merge now.
2025-08-29 05:43:18 +09:00
rain022 9ca80d352b fix: improve Japanese translations for clarity and consistency 2025-08-29 04:38:12 +09:00
end-4 b52440bcc1 media controls: outside click dismissal, no player placeholder 2025-08-28 18:17:11 +07:00
kirisaki-vk 28c9cacf68 bar: add workspace number mapping 2025-08-28 09:30:54 +03:00
hoovad 8199fdd2bf fix undefined error 2025-08-27 19:13:21 +02:00
end-4 f74ed76850 cheatsheet: use slide anim 2025-08-27 22:00:48 +07:00
end-4 5b301addd8 feat: add wallpaper selector menu (#1820) 2025-08-27 21:56:50 +07:00
end-4 1c1a141701 wallpaper selector: freedesktop spec-compliant thumbnail generation 2025-08-27 21:51:15 +07:00
end-4 e85f59db8c remove useless comments 2025-08-27 20:18:17 +07:00
end-4 fc69ca0599 sidebar: wifi dialog: esc to close 2025-08-27 20:13:46 +07:00
end-4 2ad304aaf2 config: rename "mantra" to "quote" 2025-08-27 20:13:19 +07:00
end-4 c1b56922aa sidebar: refractor wifi dialog to new file, make it dynamically loaded 2025-08-27 18:30:58 +07:00
end-4 8c737f2ca4 quickshell: fix some warnings 2025-08-27 17:59:35 +07:00
end-4 20d9561143 wifi menu 2025-08-27 17:52:23 +07:00
hoovad 1062ef9b49 move anchors to Loader, remove unnecessary visible and move setting 2025-08-27 06:04:13 +02:00
hoovad 2b54f64c8c use camelCase and unload instead of hiding 2025-08-27 05:30:15 +02:00
hoovad 5cd5a9d7e4 add setting to show/hide the clock in background 2025-08-27 05:01:42 +02:00
end-4 bb49747fd9 bluetooth: use quickshell's service 2025-08-26 21:50:37 +07:00
end-4 f38c7bffed network: implement toggling in service 2025-08-26 21:07:00 +07:00
end-4 813f02604e network: no more polling, fix sidebar toggle enabled state 2025-08-26 20:56:32 +07:00
end-4 c579dce2cf background: fix wallpaper being offscreen depending on aspect ratio 2025-08-26 19:52:21 +07:00
end-4 f6d9c2998b background: add back PreserveAspectCrop fillMode (#1879) 2025-08-26 19:20:31 +07:00
end-4 60c303b771 background: add padding for clock text in least busy region detection 2025-08-26 18:00:06 +07:00
end-4 79e7f262a7 lock screen: redesign password prompt 2025-08-26 17:59:37 +07:00
end-4 8f2863c02c background: fix blurry background when scaled 2025-08-26 15:29:20 +07:00
end-4 cd8cb03797 settings: prevent race condition of wallpaper zoom spinbox 2025-08-26 14:39:11 +07:00
end-4 9f4aa3f7e1 add corner scrolling for brightness/volume 2025-08-26 14:38:37 +07:00
end-4 eb2c9f2fe1 wallpaper selector: adjust size and item colors, fix address bar inconsistency 2025-08-26 13:58:29 +07:00
end-4 e7ffd2455a sidebars: open by hovering (or clicking) corners 2025-08-26 10:51:40 +07:00
end-4 63b7a3a36c bar: warning for high resource usage 2025-08-26 09:15:59 +07:00
end-4 376f2bfeb1 background: no flash when changing wallpaper 2025-08-26 09:08:01 +07:00
end-4 0a34b139f4 Update Chinese translation; add language toggle options in settings (#1869) 2025-08-26 09:05:51 +07:00
end-4 45d0a8e501 settings: language change notice: use proper rounding value, update chinese translation 2025-08-26 08:56:08 +07:00
end-4 485dd2952e settings: make language selection notice more material 2025-08-26 08:49:46 +07:00
end-4 a111b50e37 remove volume limit in keybind 2025-08-25 21:42:44 +07:00
end-4 b2d14ca101 wallpaper selector: thumbnail generation, fix xdg dir folder icons 2025-08-24 18:59:41 +07:00
end-4 f3ab3573c3 wallpaper selector: style the scrollbar 2025-08-24 16:39:50 +07:00
end-4 ef4ae4480f wallpaper selector: not reinvent MouseArea containsMouse 2025-08-24 16:12:37 +07:00
end-4 8277a2d942 wallpaper selector: fix dark mode 2025-08-24 14:25:39 +07:00
end-4 8bbf040100 wallpaper selector: show folders 2025-08-24 12:20:04 +07:00
月月 e6bb1a3fde translations: add setting language selection and related strings 2025-08-24 04:10:08 +08:00
月月 6df7482b3d translations:update zh_CN.json and en_US.json;
Add "Corner style" and Bar layout to translation
2025-08-24 02:28:33 +08:00
end-4 bdc0ade117 wallpaper selector: quick places 2025-08-23 23:16:18 +07:00
end-4 29a149b340 wallpaper selector: fix some key focus/fallthrough problems 2025-08-23 22:23:28 +07:00
end-4 80af866650 wallpaper selector: directory validation, common file browser keybinds 2025-08-23 22:11:41 +07:00
end-4 1237d9660e hyprland: add laptop lid switch close suspend 2025-08-23 21:56:51 +07:00
end-4 8e6582b801 wallpaper selector: add address bar 2025-08-23 21:06:36 +07:00
end-4 18ad260ce9 wallpaper service: simplify dir setting 2025-08-23 15:59:50 +07:00
end-4 c0933a3b20 wallpaper selector: make it slide from top 2025-08-23 15:59:30 +07:00
end-4 a116ae6ab5 wallpaper selector: nicer layout 2025-08-23 12:25:34 +07:00
end-4 0e2eea7555 wallpaper selector: unfuck grid placement 2025-08-23 10:13:52 +07:00
end-4 767e35851b wallpaper selector: move key handling to root 2025-08-23 09:36:43 +07:00
end-4 a25a3c186b wallpaper selector: add click outside to close 2025-08-22 22:47:21 +07:00
end-4 28256c0a72 wallpaper selector: add shadows 2025-08-22 22:03:41 +07:00
end-4 dac9ed2785 wallpaper selector: add shadows 2025-08-22 22:03:12 +07:00
end-4 9cc576b98d wallpaper selector: move content to a new file 2025-08-22 21:58:13 +07:00
end-4 87c95f7a7f sidebar: ai: add a border around attached image 2025-08-22 21:31:34 +07:00
end-4 4065142830 weather: make the °C not look ass, move "feels like" to popup 2025-08-22 20:54:15 +07:00
end-4 f56308b6e3 use nmtui for network management 2025-08-22 20:31:34 +07:00
end-4 bdbdf7cb83 sidebar: ai: esc to detach file 2025-08-22 20:30:51 +07:00
end-4 9a0f28c003 update.sh: update the warning (#1856) 2025-08-22 19:01:05 +07:00
end-4 2d2d93d5d8 hyprland: add nwg-displays support, make config portable 2025-08-22 18:34:21 +07:00
end-4 8c44dd6119 settings: make edit config button clearer 2025-08-22 18:20:09 +07:00
end-4 0cb1bc4ca5 install.sh: remove no longer true advantage of translations in ags ver 2025-08-22 18:10:12 +07:00
end-4 db83864d78 sidebar: ai: allow pasting image 2025-08-22 16:52:02 +07:00
end-4 63365c2109 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-08-22 16:51:42 +07:00
end-4 9bbc26dd70 settings app: allow volume limit over 100% 2025-08-22 16:51:39 +07:00
end-4 a383cfd125 translations: update Italian language file (#1861) 2025-08-22 10:10:40 +07:00
Salvo Giangreco 8bb9070d9a translations: update Italian language file
Signed-off-by: Salvo Giangreco <giangrecosalvo9@gmail.com>
2025-08-22 02:16:48 +02:00
end-4 690e934a46 ai: gemini: files 2025-08-21 22:53:11 +07:00
end-4 be1974a89e workspace_action.sh: make comments not weird 2025-08-21 09:53:30 +07:00
end-4 d21087b0d9 Feat: Improved Workspace_action.sh and added relative workspace support. (#1850) 2025-08-21 09:48:59 +07:00
end-4 22b1ad087c vertical bar: disable resource circprog anim 2025-08-21 09:26:58 +07:00
end-4 ce25675f73 search: allow hiding actions when the prefix is not that of them
Co-Authored-By: reakjra <85903730+reakjra@users.noreply.github.com>
2025-08-21 09:23:03 +07:00
end-4 955a7696f1 screenshot tool: don't show vertical bar layer hint 2025-08-21 08:25:49 +07:00
end-4 4cfacde337 tray: more flexible overflow menu 2025-08-21 08:25:28 +07:00
end-4 eafa8f02b6 bar: allow inverting tray item list's effect 2025-08-21 07:45:30 +07:00
end-4 1338b65aaa bar: tray overflow menu 2025-08-20 23:05:02 +07:00
end-4 7c8068b2bd background: add vertical parallax 2025-08-20 19:35:33 +07:00
end-4 75f749dbe0 fix screen lock not showing over fullscreen apps for real 2025-08-20 19:14:50 +07:00
ashmartin1810 58910f50e8 minor bug fix
minor bug fix
2025-08-20 16:48:19 +05:30
end-4 36eebffd10 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-08-20 17:47:36 +07:00
end-4 0e8e0e4b06 fix screen lock not showing over fullscreen apps 2025-08-20 17:47:27 +07:00
end-4 8524fb500f readme: make it clear that installation is for illogical-impulse quickshell 2025-08-20 06:47:58 +02:00
end-4 8fd1d9acef vertical bar: fix weird occupied ws highlight when toggling bar floating 2025-08-19 22:16:27 +07:00
end-4 c452dd3538 horizontal bar: fix oversized pills when floating + fix weather hover hitbox 2025-08-19 22:10:45 +07:00
end-4 222f083322 bar: weather: refresh on click 2025-08-19 22:02:07 +07:00
ashmartin1810 47527d7175 Feat: Improved Workspace_action.sh and added relative workspace support.
## Problem
The previous script didnt take into account for relative workspaces, and my previous pull request was... bad.
## Fix
Added smart branching to detect if the target is a literal number(1,2,90), or a relative number(+1, -20) or a string target.
## Bugs
None. ive been stress testing it since the last 2 days,
2025-08-19 20:30:00 +05:30
end-4 6f907f7961 search: add math, shell command, and web search prefixes (#1795) 2025-08-19 21:51:52 +07:00
end-4 891a226fdb notifications: hover prevents timeout 2025-08-19 21:15:59 +07:00
end-4 7cbc707308 bar: show ping icon when ai or booru finished responding 2025-08-19 21:02:17 +07:00
end-4 8d3a036b3b add slidefade text animation to some stuff 2025-08-19 18:09:07 +07:00
end-4 ee21139356 search: remove weird list anim 2025-08-19 18:01:02 +07:00
end-4 b37814e9fa Addresses improper env substitution for terminal launch (#1846) 2025-08-19 07:55:40 +07:00
Souyama 07cca33cb4 Update keybinds.conf
Escape terminal env for keybinds
2025-08-18 22:57:48 +05:30
end-4 980533052b wallpaper selector: remove some useless layout crap 2025-08-18 21:47:55 +07:00
end-4 8124f688da remove manual file:// construction 2025-08-18 21:35:01 +07:00
end-4 89e726b5a2 remove animations that aren't supposed to happen 2025-08-18 21:09:10 +07:00
end-4 42695d9253 Wallpapers: use Process::exec instead of setting command and setting running prop 2025-08-18 21:02:03 +07:00
end-4 28fe7817b4 wallpaper selector: add ipchandler alongside globalshortcut 2025-08-18 21:00:41 +07:00
end-4 6aa37e2529 wallpaper selector: dont cache images 2025-08-18 20:59:26 +07:00
end-4 2d8eb163e7 rename wallpaper overview to wallpaper selector 2025-08-18 20:55:54 +07:00
end-4 445b10d6f0 put wallpaper picker in loader and make it use real thumbnails 2025-08-18 20:41:44 +07:00
end-4 0a4dd832a3 vertical bar: not hide battery icon when full 2025-08-18 19:46:38 +07:00
end-4 8feee4e61a WallpaperOverview: make anims consistent 2025-08-18 18:27:54 +07:00
end-4 fe23017a97 WallpaperOverview: remove unnecessary Variants and Item 2025-08-18 18:25:23 +07:00
end-4 b01b52c8f8 wallpapers: show newer ones first 2025-08-18 18:24:41 +07:00
end-4 0f81d2cace make DockButton not rely on auto-cascaded dockRow.padding 2025-08-18 18:17:14 +07:00
end-4 d051246b7e dock: fix tiny button size 2025-08-18 18:13:49 +07:00
end-4 fd7f22ffba Last fix ru_RU.json (#1842) 2025-08-18 15:50:40 +07:00
relyadev c5c0cf001c Update ru_RU.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 08:25:26 +00:00
relyadev ab846062e4 Update ru_RU.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 08:25:14 +00:00
relyadev 172e77a6cf Update ru_RU.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 08:24:49 +00:00
relyadev 0998d8a0fc Update ru_RU.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-18 08:24:34 +00:00
end-4 71b82730ab config option to allow showing wallpaper when fullscreen 2025-08-18 15:04:04 +07:00
relyadev 6b597bf1fb Update ru_RU.json 2025-08-18 07:34:39 +00:00
end-4 5c431096ec force larger wallpaper picker size 2025-08-18 14:15:33 +07:00
end-4 e278bed251 add floating window rule for shell conflicts killer 2025-08-18 14:11:08 +07:00
end-4 efbcf5469b overview: remove pointless Item 2025-08-18 14:09:40 +07:00
end-4 de0a91619e Make KDE file dialogue always spawn in reasonable size (#1841) 2025-08-18 09:07:07 +02:00
fuggy 7be0c1a034 Make KDE file dialogue always spawn in reasonable size 2025-08-17 16:40:38 -05:00
sin 71e43d6e3d Merge branch 'end-4:main' into main 2025-08-17 17:01:47 +00:00
end-4 a77865379f Added micro text editor keybinds.conf (#1836) 2025-08-17 18:54:19 +02:00
end-4 e20cc9e80f more updates ru_RU.json (#1838) 2025-08-17 18:52:51 +02:00
end-4 c66c920cbe Add Japanese translation (#1839) 2025-08-17 18:52:08 +02:00
rain022 695dbee501 Add Japanese translation 2025-08-18 01:21:50 +09:00
relyadev de44a8d91e more updates ru_RU.json
"Performance Profile toggle": "Переключатель питания"
Didn't fit, changed
Translation became more logical
Almost the entire system is localized
2025-08-17 16:14:29 +00:00
end-4 de6ba1c82e wallpapers: add svg format 2025-08-17 22:54:40 +07:00
end-4 5b1124d658 correct wallpaper path capitalization 2025-08-17 21:50:12 +07:00
relyadev 122b16a720 Added micro text editor keybinds.conf 2025-08-17 14:41:20 +00:00
end-4 dfcf2eec57 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-08-17 21:34:27 +07:00
end-4 9a9a35d75e bar: corrected 💢 popup margins for vertical bar 2025-08-17 21:34:22 +07:00
end-4 ec89c9cdc8 Updated some incorrect words and added new ones to ru_RU.json (#1833) 2025-08-17 16:25:04 +02:00
relyadev e66ab2b2c9 Updated some incorrect words and added new ones to ru_RU.json 2025-08-17 12:16:52 +00:00
end-4 dc167bd25e previous commit but use $qsConfig instead of ii in hyprland config 2025-08-17 18:17:16 +07:00
end-4 680378e68f clipboard history: make updates happen immediately after change
Updates previously wouldn't trigger immediately because no focus = no clipboard grab
https://quickshell.org/docs/v0.2.0/types/Quickshell/Quickshell/#clipboardText
2025-08-17 18:15:01 +07:00
sin 190dbff98d feat(wallpaper selector): add search functionality 2025-08-17 10:51:51 +00:00
end-4 ff7aa46cda background: fix too close date placement for 12h clock 2025-08-17 15:48:33 +07:00
end-4 8c47d85927 background: fix mantra positioning 2025-08-17 15:47:20 +07:00
end-4 de99a3f114 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-08-17 15:40:01 +07:00
end-4 8b77aa151b bars: refractor corner areas' scrolling behavior 2025-08-17 15:39:58 +07:00
end-4 00461468c9 Add `mantra' beneath clock (#1828) 2025-08-17 06:22:20 +02:00
end-4 ad323f7885 remove redundant return 2025-08-17 06:21:23 +02:00
end-4 a50b673e07 disable touchpad scroll tweak by default 2025-08-17 07:31:07 +07:00
Nyx d1e66c4441 It's 9/11, where yo planes at?
Signed-off-by: Nyx <189459385+nyx-4@users.noreply.github.com>
2025-08-16 20:16:38 +05:00
end-4 7cc00b99a1 bar: make right clicking right side not skip current track (closes #1456) 2025-08-16 21:30:12 +07:00
end-4 c745615a2a prompt to kill kded6, mako, dunst (conflicting stuff) 2025-08-16 21:00:56 +07:00
Nyx 7aacac554d [Feature Request] Add `mantra' beneath clock
Signed-off-by: Nyx <189459385+nyx-4@users.noreply.github.com>
2025-08-16 18:25:52 +05:00
end-4 fcab19c392 make bottom/right bar slide anim not go across the screen 2025-08-16 19:20:17 +07:00
end-4 98e2bf53ed add slide rule for vertical bar 2025-08-16 19:19:15 +07:00
end-4 51310e632c fix media controls positioning for vertical bar 2025-08-16 14:47:01 +07:00
end-4 2a46b17958 vertical bar: add date 2025-08-16 11:55:27 +07:00
end-4 e189f0317f move StyledPopup to Bar 2025-08-16 11:54:50 +07:00
end-4 138684fcea vertical bar: add media progress 2025-08-16 08:51:07 +07:00
end-4 23af50a30d vertical bar: hide battery when not available 2025-08-16 08:38:58 +07:00
sinnayuh 28a6284968 feat(wallpaper selector): add wallpaper selector menu 2025-08-15 17:33:10 +01:00
end-4 ce114b33ff fix unresolved import and unsafe undefined access 2025-08-15 22:50:14 +07:00
end-4 d05c451294 bars: refractor bar groups 2025-08-15 22:49:43 +07:00
end-4 9fc0d26eb5 vertical bar 2025-08-15 22:17:27 +07:00
end-4 25a0c88670 bar: workspaces: not have overkill rounding 2025-08-15 22:12:31 +07:00
end-4 0d5d9a04f5 bar: battery indicator: remove useless RowLayout 2025-08-15 22:12:12 +07:00
end-4 f2ed0057bf bar: unify resource usage popups 2025-08-15 22:08:57 +07:00
end-4 661fcfd263 ai: add gpt 5 nano via gh models 2025-08-15 22:07:56 +07:00
end-4 dbed431085 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-08-15 17:46:07 +07:00
end-4 fb89ca98f6 BarContent: remove useless Item wrapping left/right sides 2025-08-15 17:46:02 +07:00
end-4 04bec463c7 night light: fix evaluation in midnight (#1815) 2025-08-15 14:27:57 +07:00
Moeta Yuko 25170f0d2c night light: fix evaluation in midnight 2025-08-15 10:18:01 +08:00
end-4 85a522ba14 bar: fix weird tooltip hover target 2025-08-14 21:11:40 +07:00
end-4 a28618ab78 appearance: add barGroupHeight 2025-08-14 19:57:40 +07:00
end-4 955a5ba7f2 bar: not repeat 32 (visual group height) 2025-08-14 15:47:18 +07:00
end-4 dbd23a6ea4 bar: fix weird center group spacing for non-borderless mode 2025-08-14 15:46:19 +07:00
end-4 df93057dd3 readme: fix the size badge color 2025-08-14 15:30:48 +07:00
end-4 3c2b6d4e7f less unsharpening, make bar resource indicators smaller 2025-08-13 17:19:14 +07:00
end-4 2f11e12c75 bar: not show 1px line when autohiding 2025-08-13 09:47:54 +07:00
end-4 2faf615b68 bar: make icon for cpu more readable 2025-08-12 23:54:30 +07:00
end-4 8bb2e0aa97 bar: media: fix progress value 2025-08-12 23:45:45 +07:00
end-4 b6e4a47329 ClippedFilledCircularProgress: not have the padding 2025-08-12 23:43:27 +07:00
end-4 08197fca23 bar: circular progresses: adjust colors, fix them being always at 65% 2025-08-12 23:40:53 +07:00
end-4 423fb90266 bar: make circular progresses of filled style 2025-08-12 23:38:33 +07:00
end-4 67d1d73845 ClippedProgressBar: add unsharpening to highlight 2025-08-12 23:37:09 +07:00
end-4 fa0531b975 background: wallpaper: no caching
https://doc.qt.io/qt-6/qml-qtquick-image.html#cache-prop
2025-08-12 23:36:11 +07:00
end-4 cb01563ba8 bar: make resource numbers have fixed width 2025-08-12 22:09:20 +07:00
end-4 4446259a0b bar: battery: remove unnecessary imports/props 2025-08-12 22:08:44 +07:00
end-4 a5eb2f0ae6 bar: battery: shamshung pill style 2025-08-12 21:40:29 +07:00
end-4 bf4a1097c1 bar: allow any custom icon on topleft corner 2025-08-12 18:26:47 +07:00
end-4 87ebc8761b bar workspaces: fix occupied indication when changing ws group and on init 2025-08-12 18:25:32 +07:00
end-4 4e87ce8f4b bar: battery indicator: use android battery icon 2025-08-12 18:24:53 +07:00
end-4 24d24c1f85 background: add missing raised style 2025-08-12 18:24:27 +07:00
end-4 c88d77e3f8 install script: update final message 2025-08-12 17:52:40 +07:00
end-4 553c42b82c background: comment debug stuff 2025-08-12 16:36:48 +07:00
end-4 3eb1dd3180 background: fix clock going out of the screen vertically 2025-08-12 16:24:45 +07:00
end-4 10b2cf2662 background: fix padding value for least busy region proc 2025-08-12 15:35:56 +07:00
end-4 545fd8b58a background: no more weird clock movement 2025-08-12 15:24:37 +07:00
end-4 2e31972c56 background: fix wrong wallpaper movable space calculation 2025-08-12 14:34:25 +07:00
end-4 d095cb7812 background: fix small wallpapers going off the screen 2025-08-12 11:20:02 +07:00
end-4 fc31d5fd2f fix weird mediacontrols positioning when bar autohides 2025-08-12 10:28:54 +07:00
end-4 d73ba14154 ServicesConfig now edits hyprlock.conf to change the clock format (#1797) 2025-08-12 09:45:09 +07:00
end-4 d8e09e80ff move hyprlock colors file, remove redundant hyprlock matugen template 2025-08-12 09:44:12 +07:00
end-4 211c4fb102 fix weird osd position when bar autohides 2025-08-11 22:46:28 +07:00
end-4 d448b76dd4 fix stuff not getting blurred when transparency is enabled 2025-08-11 22:42:14 +07:00
end-4 e8ebf5af73 bar tooltip: fix placement for autohide 2025-08-11 22:33:11 +07:00
end-4 459dab65ca feat(bar): unified popup handling (follow-up to #1771 and #1773) (#1776) 2025-08-11 22:10:52 +07:00
end-4 73304ef8d4 Merge branch 'main' into all-tooltips 2025-08-11 22:06:56 +07:00
end-4 aa025e4fac bar tooltips: refractor more 2025-08-11 22:05:19 +07:00
end-4 8eac9338fe bar tooltips: add border 2025-08-11 21:18:55 +07:00
end-4 b0deecc0aa bar tooltips: add shadow 2025-08-11 21:18:01 +07:00
end-4 af111a4be9 bar tooltips: format 2025-08-11 21:17:53 +07:00
end-4 6a8a9172b1 bar tooltips: refractor tooltip bg to StyledPopup 2025-08-11 20:33:01 +07:00
end-4 291b997972 bar tooltips: use correct color, add subhead text 2025-08-11 20:12:20 +07:00
end-4 70a5520f47 bar tooltips: adjust icons 2025-08-11 16:33:35 +07:00
end-4 e7397f824b bar tooltips: make em use tooltip color 2025-08-11 16:03:29 +07:00
end-4 0beee14cd8 bar: popups: fix and simplify positioning 2025-08-11 15:52:54 +07:00
end-4 9ba251ff30 Revert "use wl-clip-persist"
This reverts commit 7f1699663d.
2025-08-11 15:31:59 +07:00
end-4 5b24ac037f automatic transparency 2025-08-11 15:09:39 +07:00
end-4 ea70c354ad lock screen: fix incorrect password text 2025-08-11 15:07:47 +07:00
lunstia 1623b456ec Add variable and moved directory to correct one 2025-08-11 02:15:41 -04:00
lunstia 307959ba76 Edit matugen and hyprlock to separate the two 2025-08-11 00:31:22 -04:00
end-4 7f1699663d use wl-clip-persist
so clipboard content won't go away when the content source app is closed
2025-08-10 17:40:23 +07:00
end-4 252675d3ff notifications: smaller icon 2025-08-10 17:24:52 +07:00
end-4 84c45f2068 make scrolling accumulate properly 2025-08-10 16:44:29 +07:00
end-4 5873995e42 settings: add hiding and bottom position options 2025-08-10 16:44:21 +07:00
end-4 077922c667 fix wrong circular progress prop name 2025-08-10 16:15:29 +07:00
end-4 47dcb1523a Added pomodoro timer in sidebarRight, closes #1477 (#1761) 2025-08-10 16:13:03 +07:00
end-4 86f1e63ed2 stopwatch: clear laps on Start 2025-08-10 16:03:37 +07:00
end-4 709415a6b4 rename stuff 2025-08-10 16:02:00 +07:00
Celestial.y fa46485d57 translation: update zh_CN.json (#1762) 2025-08-10 16:51:24 +08:00
end-4 c2d5d2b61a pomodoro: remove unnecessary isLongBreak persistent state 2025-08-10 15:40:42 +07:00
Runze e39c1af5ae chore(bar): add WlrLayer.Overlay in StyledPopup and delete temperature translation 2025-08-10 02:51:54 +08:00
end-4 ca6463cae8 TimerService: not have stupid extra declaration 2025-08-09 22:58:55 +07:00
end-4 0e17b7a981 TimerService: add back emojis, make reset also reset isLongBreak 2025-08-09 22:55:40 +07:00
end-4 bcd1167d39 pomodoro: rename service to TimerService, better stopwatch layout 2025-08-09 22:48:40 +07:00
end-4 fbe17dc3e3 pomodoro: accept event on keybind cuz recommended by qt docs 2025-08-09 22:19:45 +07:00
end-4 b102e5c1a5 pomodoro: remove unnecessary event propagation prevention 2025-08-09 22:15:07 +07:00
end-4 df9a5e398e pomodoro: remove unused notificationTitle var, format 2025-08-09 22:11:06 +07:00
end-4 90fafa219a remove unnecessary qualified access 2025-08-09 22:09:07 +07:00
end-4 9e1b55a749 pomodoro: add cycle indicator, make long break work, fix reset button 2025-08-09 22:06:05 +07:00
end-4 4ca15a1fc3 pomodoro: make pause/resume less weird 2025-08-09 21:36:28 +07:00
end-4 5bf80dae4e pomodoro: move timers to service, specific button logic to widget 2025-08-09 19:45:26 +07:00
end-4 1f4568d22f pomodoro: rename more for consistency 2025-08-09 18:20:14 +07:00
end-4 903a975033 rename getPomodoroSecondsLeft -> pomodoroSecondsLeft 2025-08-09 16:31:03 +07:00
end-4 0ee9afba4f pomodoro: move tabs to their own files, adjust colors 2025-08-09 16:28:17 +07:00
Runze 9b5713d6b4 chore(bar): delete temperature and related reading logic 2025-08-09 14:08:39 +08:00
Runze 94176fad83 feat(bar): unify extraction to StyledPopup and add namespace 2025-08-09 14:02:56 +08:00
end-4 de759b5120 redesign stopwatch 2025-08-09 12:54:53 +07:00
end-4 9bc4ff16a7 make pomodoro timer persistent 2025-08-09 12:54:37 +07:00
end-4 814f6ced5f hide dupe keybind for one thing 2025-08-09 11:08:05 +07:00
end-4 91dae8ad85 pomodoro widget: use grid instead of row/col spam 2025-08-09 10:42:50 +07:00
end-4 fb4f8a86f4 lock screen: use quickshell, add hack for window refocus 2025-08-09 08:56:12 +07:00
end-4 e15d2fe82c easyeffects toggle: move logic to a service 2025-08-09 08:55:29 +07:00
end-4 4ede1c74e8 Run hyprctl directly in HyprlandData service (#1786) 2025-08-09 06:27:37 +07:00
Alvin 9d98396e33 Add missing commas 2025-08-08 14:15:07 -04:00
Alvin e43dcf5d4c run hyprctl directly 2025-08-08 14:11:06 -04:00
end-4 eac4ab3e3c enable faster touchpad scroll 2025-08-08 22:09:45 +07:00
end-4 d256d8fc35 add config option to use "normal" scroll behavior (#1782) 2025-08-08 22:08:50 +07:00
end-4 3157e99e04 keybinds: make super key binds work also with right super 2025-08-08 21:51:30 +07:00
Nyx 91fee0d6e9 Minor tweaks and better variables names
Signed-off-by: Nyx <189459385+nyx-4@users.noreply.github.com>
2025-08-08 19:51:03 +05:00
end-4 521061fc64 sidebar: volume mixer: adjust style 2025-08-08 21:37:32 +07:00
end-4 4328746df0 SecondaryTabButton: make ripple radial gradient 2025-08-08 21:36:45 +07:00
end-4 2b87d939bb make fade of ripple effect longer 2025-08-08 21:03:11 +07:00
end-4 39a88a6cd3 ButtonGroup: add uniformCellSizes 2025-08-08 21:02:45 +07:00
end-4 d0ad416e28 bar: adjust autohide super press show delay 2025-08-08 20:53:47 +07:00
end-4 61e4f59aa0 welcome app: more bar options, extra info on closing 2025-08-08 20:47:20 +07:00
end-4 db66b85e61 bar: move number showing logic from GlobalStates to Workspaces 2025-08-08 20:24:37 +07:00
end-4 66c810ead2 bar autohide: rename enabled -> enable for consistency 2025-08-08 20:12:50 +07:00
end-4 9824bb9c63 bar: add delay for autohide 2025-08-08 20:06:53 +07:00
end-4 f806e2c22c bar: add auto hide 2025-08-08 19:54:10 +07:00
end-4 3d408b18f7 background: add fade when switching 2025-08-08 18:31:52 +07:00
end-4 8aa776ae62 make bg image loading async 2025-08-08 18:02:10 +07:00
end-4 a15f3b8c65 overview: show windows on other monitors too 2025-08-08 17:55:52 +07:00
end-4 4df22c96d0 screen corners: fix visibility for multimonitor with varying fullscreen state 2025-08-08 17:52:19 +07:00
end-4 772df06fa5 booru: fix inconsistent download 2025-08-08 17:50:20 +07:00
Saint2999 e1b7336d5d Hide online model on local ai policy 2025-08-08 07:46:02 +03:00
end-4 d3a9d2ea5b Fix hiding background when fullscreen (#1775) 2025-08-08 10:35:55 +07:00
end-4 4914d9b638 Merge branch 'main' into main 2025-08-08 10:35:43 +07:00
end-4 1f8a7be34e quickshell: fix qml null safety and monitor property errors (#1770) 2025-08-08 00:01:31 +07:00
end-4 97bdfa54c0 Overrideable default terminal app (#1753) 2025-08-07 23:57:08 +07:00
end-4 64bb730dd1 touchpad: improve scroll speed handling for touchpad (#1781) 2025-08-07 23:46:39 +07:00
end-4 7013b459a3 adjust scrolling speed 2025-08-07 23:13:07 +07:00
end-4 a31733e2db move scrolling animation to styled components 2025-08-07 22:39:30 +07:00
end-4 199b23d14a add config options for scroll factors and threshold 2025-08-07 22:32:02 +07:00
end-4 f1c1ed833c use StyledListView for SelectionDialog 2025-08-07 22:31:19 +07:00
Souyama 0506917b87 launch_first_available.sh should skip empty cmds 2025-08-07 20:48:11 +05:30
end-4 4f40ba8e6e more intuitive power profiles icons 2025-08-07 22:01:05 +07:00
end-4 733a792610 ai: add usage metadata for openai and mistral 2025-08-07 21:53:37 +07:00
end-4 f581fd4821 config option to (not) filter duplicate media controls 2025-08-07 21:39:48 +07:00
Runze 86ddb61a3f fix(touchpad): differentiate scroll speed between touchpad and mouse wheel 2025-08-07 22:26:26 +08:00
lunstia 6c3451b912 Fix background not always hiding in fullscreen and other monitors hiding background when they're not supposed to 2025-08-07 00:16:26 -04:00
Runze 627c8562f7 fix(bar): prevent hover popup from appearing for hidden resource icons 2025-08-06 19:28:37 +08:00
Runze 061bb2abeb feat(bar): unify popup handling and improve layouts
- Unified popup handling in ClockWidget, Resource, BatteryPopup, and WeatherBar
  using PanelWindow + LazyLoader for consistent positioning and compositor animations.
- Replaced plain text with ColumnLayout and RowLayout where possible, adding
  MaterialSymbol icons for improved visual consistency with the overall desktop style.
- Added Translation.tr() for bilingual (Chinese/English) support to avoid hardcoded strings.
- Based on improvements from PR #1771 (mine) and PR #1773 (by @finjener), merged and refined into a more polished and practical solution.
2025-08-06 18:02:55 +08:00
lunstia 35e1dc95a5 Fix background hiding in fullscreen 2025-08-06 05:27:29 -04:00
finjener 1dc46fa104 feat(bar): add hover popups for system resources and upcoming todos
- Add detailed popups for memory, swap, and CPU resource icons
- Add todo integration popup for date/time widget
2025-08-06 15:30:49 +08:00
Runze 4161467356 use PanelWindow instead to show animation 2025-08-06 01:31:02 +08:00
finjener d70f81bfe4 Merge remote-tracking branch 'upstream/main' into quickshell-fixes 2025-08-05 18:17:02 +01:00
Nyx bfb7ccffb5 Reworked on Pomodoro's UI and added Stopwatch
Signed-off-by: Nyx <189459385+nyx-4@users.noreply.github.com>
2025-08-05 16:06:22 +05:00
Runze 3a6c032782 Added a small battery popup to show information 2025-08-05 17:21:36 +08:00
finjener d632111cf9 quickshell: fix qml null safety and monitor property errors 2025-08-04 23:03:00 +01:00
Nyx e4b761917a Polished the UI and added Persistent Config option.
Signed-off-by: Nyx <189459385+nyx-4@users.noreply.github.com>

Changelog:
Added Config.options.time.pomodoro options in Config.qml
Restructered the Pomodoro logic and added Long break
Used timestamp instead of naively counting down.
Major UI tweaks.
2025-08-03 20:36:29 +05:00
end-4 f8d162d995 RoundCorner: rewrite to use Shape instead of Canvas 2025-08-03 20:40:52 +07:00
end-4 0708070764 circular progress: use implicitSize instead of size
note: the credit is removed because the widget has been rewritten to use Shape instead of Canvas
2025-08-03 19:54:01 +07:00
end-4 87f7bc28a3 chores: remove unnecessary import, suppress init null warnings 2025-08-03 18:17:01 +07:00
end-4 3eb7d8ab58 background: remove unecessary Scope 2025-08-03 18:13:12 +07:00
end-4 71d0ac4c5e make circular progresses use shape instead of canvas 2025-08-03 18:12:44 +07:00
end-4 839593b11e add konsole konfig 2025-08-03 17:31:58 +07:00
end-4 13a0927900 bar: refractor bar content to new file 2025-08-03 16:52:39 +07:00
end-4 00984c599b settings: update keep right sidebar loaded note 2025-08-03 16:51:08 +07:00
end-4 34ca65a180 background: fix wrong anchor 2025-08-03 16:11:24 +07:00
月月 9df7129c6c translation: update zh_CN.json 2025-08-03 09:42:43 +08:00
Nyx 0b9717c2a5 Added pomodoro timer in sidebarRight, closes #1477
Signed-off-by: Nyx <189459385+nyx-4@users.noreply.github.com>
2025-08-02 22:17:56 +05:00
end-4 596ae72942 add config option to keep right sidebar loaded 2025-08-02 20:31:37 +07:00
end-4 88cc91b85a fix laggy search bar anim when overview is disabled 2025-08-02 20:09:18 +07:00
end-4 d4b8ded6c8 overview: allow disabling overview (showing search only) 2025-08-02 17:35:44 +07:00
end-4 86d2a03a0a settings: add monochromize/tint icons toggles 2025-08-02 16:56:19 +07:00
end-4 de1812bf91 sidebar: remove redundant coloroverlay, make uptime more brief 2025-08-02 16:55:56 +07:00
end-4 f36751ff6b sidebar: boorus: always download images manually 2025-08-02 16:01:46 +07:00
end-4 a9273fc225 ai: dont include tool instructions in system prompt 2025-08-02 16:00:24 +07:00
end-4 2a0b12112f i use nyarch btw 2025-08-02 15:45:24 +07:00
end-4 2aea02989f session: fix binding breakage on close (#1754) 2025-08-02 07:25:08 +07:00
Souyama 2b554cf286 Update env.conf
remote direct quotes
2025-08-02 00:28:47 +05:30
sansmoraxz dc2777703d update default terminal value 2025-08-01 22:47:01 +05:30
sansmoraxz 6ae03b545c terminal env var 2025-08-01 22:22:01 +05:30
end-4 8e366cfc84 translations: add ukrainian language file (#1748) 2025-08-01 22:56:27 +07:00
Beengoo 27c2c4fb92 Merge branch 'end-4:main' into main 2025-08-01 15:53:42 +03:00
Beengoo 83af589b27 Correcting localization errors 2025-08-01 15:44:47 +03:00
end-4 7a937833f3 background: parallax on whole workspace group 2025-08-01 08:16:19 +07:00
end-4 4110d2529c ai: dont replace . in ollama model name 2025-07-31 22:28:34 +07:00
Beengoo 1c6c165d78 Added Ukrainian Language 2025-07-31 17:17:48 +03:00
end-4 a5ffb0e021 media controls: actually detect if plasma browser integration is installed 2025-07-31 12:35:39 +07:00
end-4 a08a39b620 qs: handle toggles internally instead of relying on hyprctl dispatch global (#1745) 2025-07-31 12:35:16 +07:00
end-4 968e8195ef background: fix clock positioning 2025-07-30 12:33:55 +07:00
end-4 52ce2f5384 feat(background): show clock for video wallpapers. (#1719) 2025-07-30 07:30:15 +02:00
end-4 cb2d1bc444 Merge branch 'main' into videowall-add-clock 2025-07-30 07:30:05 +02:00
end-4 47b81faf3d Feature: Hyprlock layout indicator (#1718) 2025-07-30 07:15:33 +02:00
end-4 1483761e72 Feature: On-screen keyboard (osk) update on activeLayout event (#1717) 2025-07-30 07:11:05 +02:00
end-4 7f43665e3c Merge branch 'main' into osk-update-on-activelayout-event 2025-07-30 07:10:48 +02:00
end-4 01fcd653ad Fix: Init layout indicator with main keyboard and update on every activeLayout event (#1711) (#1716) 2025-07-30 06:57:40 +02:00
end-4 298e947740 background: hide when fullscreen 2025-07-30 09:46:55 +07:00
end-4 91c2014b7e ai: add mistral 2025-07-30 09:46:42 +07:00
end-4 3018ad16b1 translation: Update Russian translation file (again) (#1741) 2025-07-30 00:44:34 +02:00
Anton Epikhin 1172be241c Returned fade_on_empty for input field and moved layout indicator to bottom right 2025-07-29 22:02:25 +03:00
Vercixx c743b4ab88 Update ru_RU.json 2025-07-29 21:45:56 +03:00
end-4 f6ec718ced translation: Update Russian translation file (#1740) 2025-07-29 16:43:04 +02:00
Vercixx aa20027de4 translation: Update Russian translation file 2025-07-29 16:27:30 +03:00
end-4 e504cf11e1 starship: fix trailing newline (#1738) 2025-07-29 19:01:09 +07:00
end-4 a11e0a39d9 ai: adjust chat input indicator spacing 2025-07-29 16:42:18 +07:00
end-4 26531401b0 ai: allow custom models 2025-07-29 16:38:21 +07:00
end-4 0f4293e4cb background: clock "separate" from bg image 2025-07-28 22:49:01 +07:00
end-4 7172b134ea ai: more context in system prompt 2025-07-28 22:40:54 +07:00
end-4 4a9e342a1c ai: add suggestions for /tool 2025-07-28 18:11:23 +07:00
end-4 f98d869c21 why 2025-07-28 10:38:16 +02:00
end-4 1312310a6e translation: update vietnamese 2025-07-28 13:33:49 +07:00
end-4 ad9c81f405 translation: Add Russian translation (#1732) 2025-07-28 08:16:51 +02:00
end-4 496caa6fb1 fix weirdass scroll speed 2025-07-28 11:58:50 +07:00
end-4 2fd7d45b9c deps: add hyprsunset 2025-07-28 07:31:11 +07:00
Vercixx 0b087665a8 translation: Add Russian translation 2025-07-27 22:33:49 +03:00
end-4 39862fba2a make panel borders more subtle 2025-07-27 22:44:08 +07:00
end-4 3ac44d211f ai: separate model and tool selection 2025-07-27 22:33:25 +07:00
end-4 d3392000af translations: add Italian language file (#1723) 2025-07-27 15:48:44 +02:00
Salvo Giangreco 564d2e109f translations: add Italian language file
Signed-off-by: Salvo Giangreco <giangrecosalvo9@gmail.com>
2025-07-27 14:52:59 +02:00
end-4 fe07298adb hyprlanddata: use stdiocollector instead of jq hack with splitparser 2025-07-27 08:51:43 +07:00
end-4 cc176a999d Fix empty notifications (#1728) 2025-07-27 03:12:19 +02:00
Javier Rolando 47c5a41aa6 fix empty notifications 2025-07-26 20:49:04 -03:00
end-4 2ad6f2c9fc Make Performance profile setting translatable (#1725) 2025-07-27 00:54:10 +02:00
Vercixx 8905bc1c27 Make Performance toggle translatable 2025-07-26 16:58:43 +03:00
end-4 064d5174c2 ai: add command execution requests 2025-07-26 14:20:55 +07:00
end-4 c69c8f6ef5 osd: make spinning brightness icon not wiggle 2025-07-26 14:12:43 +07:00
end-4 7fb81049f3 welcome app: fix material theme 2025-07-26 09:09:52 +07:00
end-4 5099ce15db session: detect running downloads 2025-07-25 23:09:17 +07:00
lyingfish ed500395d3 feat(background): show clock for video wallpapers.\ 2025-07-25 21:38:47 +08:00
Anton Epikhin a1e88fc3c2 Added hyprlock layout indicator 2025-07-25 16:35:42 +03:00
end-4 c8b007631d ai: refractor api formats 2025-07-25 20:14:37 +07:00
Anton Epikhin 6bc1f8a39f OSK update on activeLayout event 2025-07-25 14:26:49 +03:00
Anton Epikhin fe84f6cab1 init indicator with main keyboard and update layout on every activelayout event 2025-07-25 11:33:16 +03:00
end-4 27eea1c7a6 feat: power-profile switcher in topbar (#1653) 2025-07-25 09:11:46 +02:00
end-4 32f94704c7 bar: power profiles: change icon for "balanced" 2025-07-25 14:10:55 +07:00
end-4 05fdbf3d24 rename showPerfProfileToggle -> showPerformanceProfileToggle 2025-07-25 13:58:40 +07:00
end-4 f28c791cf2 hyprlock: remove misleading comments in default config 2025-07-25 10:40:53 +07:00
end-4 a4b474ff39 wallpaper: more flexible parallax 2025-07-25 10:39:58 +07:00
end-4 38c76fe86b Fix: Always scroll clipboard history to top when content changes (#1690) (#1713) 2025-07-25 04:31:46 +02:00
end-4 d09259c79a search: fix clipboard gets scrolled to bottom 2025-07-25 09:30:59 +07:00
Celestial.y a683fa2414 feat: add option to ignore conflicting files (#1613) 2025-07-25 08:58:39 +08:00
MrRogueKnight e744816928 Update SearchWidget.qml 2025-07-25 01:53:31 +05:30
end-4 15703bce04 session: detect more package managers 2025-07-24 21:40:35 +07:00
end-4 f4f5540d08 qs: use new qs import for search algorithms 2025-07-24 20:45:57 +07:00
end-4 b1b37685c1 session: warn when package manager is running 2025-07-24 20:41:44 +07:00
end-4 0ff4cc572c sidebar: ai: clearer statusbar tooltips 2025-07-24 19:37:27 +07:00
end-4 081b9c17d5 tooltip colors follow m3 docs again 2025-07-24 19:36:50 +07:00
end-4 eb6b21e7e6 ai: add api key indicator 2025-07-24 19:28:45 +07:00
end-4 baa17c304b ai: show search queries, temperature, and token count 2025-07-24 18:05:21 +07:00
end-4 7b8b388667 ai: make temperature actually work 2025-07-24 16:24:27 +07:00
end-4 118529d8d3 ai: gemini 2.5: update model codes, add flash lite 2025-07-24 16:19:26 +07:00
end-4 b67c4553f6 bar: layout indicator: make not freaking tiny 2025-07-23 22:25:18 +07:00
end-4 47980da78e Layout indicator for Hyprland kb_layout option (#1471) 2025-07-23 17:22:04 +02:00
end-4 3d57d444df Merge branch 'main' into layout_service 2025-07-23 17:20:38 +02:00
end-4 5870632c19 Merge remote-tracking branch 'upstream/main' into layout_service 2025-07-23 22:18:22 +07:00
end-4 ffeb27f04e bar: layout indicator: smaller 2025-07-23 22:12:54 +07:00
end-4 012df9dcd7 hyprlandxkb: dont update when not necessary 2025-07-23 22:11:40 +07:00
end-4 82fd2334cf bar: layout indicator: more proper layout parsing 2025-07-23 22:07:34 +07:00
end-4 7bafa57989 radiobutton: fix inaccurate height 2025-07-23 10:26:16 +07:00
end-4 5b4ccd9d59 previous commit but i didn't know there are 2 spots to fix 2025-07-23 09:34:23 +07:00
end-4 be2b86909a switchwall: fix mpv options being overriden by load-scripts only (#1696) 2025-07-23 09:26:52 +07:00
end-4 82506ae7cd groupbutton: press and hold for alt action 2025-07-23 09:00:54 +07:00
end-4 574a2a11e7 night light: use hyprsunset <- gammastep 2025-07-23 09:00:31 +07:00
end-4 3d5ed9401c bar: don't animate circprogs (#1570) 2025-07-23 08:57:33 +07:00
end-4 3b5a674409 fix(ai): add the full received message to rawContent (OpenAi format) (#1695) 2025-07-22 15:22:42 +02:00
Jonas Bloch f9856bdabd fix(ai): add the full received message to rawContent
The messages were not preserved and passed to further calls outside of the reasoning part.
2025-07-22 09:50:51 +02:00
end-4 b6f75acf53 quickshell: configPath -> shellPath 2025-07-22 09:17:17 +07:00
end-4 c0f7504b36 bar: tray: not make icons fully monochrome 2025-07-22 09:17:03 +07:00
end-4 02f1c461c5 readme: add keybind cheatsheet image 2025-07-21 16:51:07 +02:00
end-4 c6fa348986 Update CONTRIBUTING.md 2025-07-21 16:27:33 +02:00
end-4 8ff226fbad overview: add ipc handlers for clipboard history and emoji picker 2025-07-21 20:44:37 +07:00
end-4 349700d7fb ai: gemini: fix random json spilling 2025-07-21 17:56:31 +07:00
end-4 0d9d11b2e0 lock: temporarily go back to hyprlock
issues with quickshell lock:
- crashes when (un)plugging monitors
- kb focus is loss after suspend
- previously active app is not re-focused after unlocking
2025-07-21 14:46:55 +07:00
end-4 734cf56631 appsearch: icon guess: both lower n uppercase domain name app name (#1674) 2025-07-21 11:56:04 +07:00
end-4 d4e782aa6c appsearch: icon guess: lowercase (#1674) 2025-07-21 11:51:37 +07:00
end-4 c517264baf lock: hyprlock fallback 2025-07-21 11:33:23 +07:00
end-4 d5809621d9 hyprland: better scrolling 2025-07-21 11:32:59 +07:00
end-4 6ec24e9932 Fix monitor offset w/ left-of-center monitors in overview (#1656) 2025-07-21 06:25:01 +02:00
end-4 a7805af421 lock: add password box content timeout 2025-07-21 10:45:33 +07:00
end-4 c5f8377a85 fix quickshell bg showing over mpvpaper (fixes #1684) 2025-07-21 10:15:29 +07:00
end-4 7ba14a4cc8 hyprland: allow lock xray 2025-07-21 03:29:04 +02:00
end-4 d38a168e52 Do not timeout notification if expiration is 0 (#1683) 2025-07-20 18:56:40 +02:00
end-4 f4dcf1fb4b lock: fix text alignment 2025-07-20 22:57:31 +07:00
end-4 93cf930126 fix(wallpaper/konachan): make random konachan respect locale by utilizing xdg user dirs (if any) (#1662) 2025-07-20 17:43:21 +02:00
Alvin 3bd542aa65 do not timeout notification if expiration is 0 2025-07-20 11:24:13 -04:00
alyingfish 5e78b09577 feat: add option to ignore certain apps in dock (#1681)
* feat: add option to ignore certain apps in dock

Co-authored-by: end-4 <97237370+end-4@users.noreply.github.com>
2025-07-20 17:17:23 +02:00
end-4 42b483b878 hyprland: add rules for lock screen 2025-07-20 21:58:02 +07:00
end-4 b2b24206a1 hyprland: remove steam float rule, fix tearing rule 2025-07-20 21:57:49 +07:00
end-4 ecf824f85f remove redundant PersistentStates 2025-07-20 21:56:37 +07:00
end-4 329b6e6ebd Right sidebar: restore last viewed bottom widget (#1622) 2025-07-20 16:53:58 +02:00
end-4 f6e89ed60c right sidebar: bottomwidgetgroup tabs: set currentIndex directly 2025-07-20 21:52:32 +07:00
end-4 b6618d2193 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-07-20 21:43:27 +07:00
ふらまりん 09bcd9ae4b Merge branch 'main' into fix/pictures-dir-respect-locale 2025-07-20 22:36:34 +08:00
end-4 73fa273e29 fix random konachan script not updating wallpaper (#1661) 2025-07-20 16:28:03 +02:00
end-4 b93b329da9 Properly fix open with menu in KDE (#1673) 2025-07-20 16:25:14 +02:00
end-4 db38e8496f lock: make it cover also fullscreen apps 2025-07-20 20:52:40 +07:00
end-4 c1c291a9e3 use quickshell for lock 2025-07-20 08:58:40 +07:00
end-4 a000abc908 switchwall: less duplicate config file declaration 2025-07-20 08:39:12 +07:00
Dignity 084508db84 use different filename if already used by config 2025-07-19 19:24:49 +02:00
Dignity 6a4b8cc778 Merge branch 'end-4:main' into main 2025-07-19 19:18:54 +02:00
end-4 cbd1b48b93 fix record script 2025-07-19 23:09:46 +07:00
Moeta Yuko d4bda66c65 Properly fix open with menu in KDE
* Use XDG menu scheme from KDE, which is already implicitly introduced
  by illogical-impulse-kde.
* Set XDG_MENU_PREFIX globally, so kbuildsycoca6 is automatically
  invoked by /usr/bin/xdg-mime via the pacman hook. Consequently, the
  manual call can (and should) be removed.
2025-07-19 16:47:59 +08:00
end-4 ed06192d6a background: don't flash the default wallpaper on startup (#1670) 2025-07-19 14:56:28 +07:00
end-4 4b4b2c9efa ai: add 🐧😭💢 2025-07-19 12:01:10 +07:00
end-4 bdc1e56df4 icons: make (normal) substitutions work with uppercase classes 2025-07-19 11:27:52 +07:00
end-4 528a7261d3 notifications: make stupid warning shorter 2025-07-19 10:36:17 +07:00
end-4 8603918771 icons: add guess by icon search 2025-07-19 10:35:52 +07:00
ふらまりん 47007288e8 fix(translation): fix comma 2025-07-19 09:37:39 +08:00
ふらまりん 68fa1715d0 fix(translation): reflect dir change in zh_cn 2025-07-19 09:34:45 +08:00
ふらまりん 0ee77b9ebc Merge branch 'main' into fix/pictures-dir-respect-locale 2025-07-19 09:28:26 +08:00
end-4 19ea9ea3d1 kill all apps before shutting down/rebooting/etc 2025-07-18 23:42:10 +07:00
end-4 055da37987 screenshot: fix window regions 2025-07-18 23:13:00 +07:00
end-4 65e3b6c84c fix typo 2025-07-18 23:03:58 +07:00
end-4 3aec3da80d Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-07-18 22:54:28 +07:00
end-4 7b3884ab1a konachan.net instead of konachan.com to prevent captchas (#1664) 2025-07-18 22:54:23 +07:00
ふらまりん 5382b4bfb1 fix(wallpaper/konachan): fix mkdir 2025-07-18 21:06:45 +08:00
ふらまりん ae30ab03d5 fix(wallpaper/konachan): utilize XDG_PICTURES_DIR in random konachan 2025-07-18 21:02:21 +08:00
end-4 2426682cc2 readme: just link to wiki 2025-07-18 12:47:46 +02:00
end-4 86e041945a activewindow: fix null warnings 2025-07-18 17:40:18 +07:00
end-4 ac0aaf7ba9 overview: make drag hotspot be at the mouse 2025-07-18 16:39:44 +07:00
end-4 bab166baea notifications: destroy wrapper object when quickshell's notif is destroyed (#1465) 2025-07-18 16:09:35 +07:00
end-4 40f2e0b6a7 notif item: fix binding loop for notifs with images 2025-07-18 15:29:08 +07:00
end-4 0806c97fe5 right sidebar: change toggles order 2025-07-18 12:36:49 +07:00
end-4 2cc313855b launcher: clipboard: delete button 2025-07-18 12:36:25 +07:00
end-4 3311d68262 hyprland: fix env syntax error 2025-07-18 09:19:30 +07:00
end-4 1e4493474f wayland electron envvar, librewolf browser fallback (#1660) 2025-07-18 04:14:27 +02:00
end-4 9abdfd8da0 Update env.conf 2025-07-18 04:13:17 +02:00
end-4 8452b9a234 Update CONTRIBUTING.md 2025-07-18 03:44:55 +02:00
Dignity ccf512b8ad fix random konachan script not updating wallpaper 2025-07-17 20:44:56 +02:00
Nouvborne c1832de01f Update env.conf 2025-07-17 18:13:04 +00:00
Nouvborne e6c44737ac Update keybinds.conf 2025-07-17 18:11:07 +00:00
end-4 f42e6773aa settings: add wallpaper parallax 2025-07-17 23:44:13 +07:00
end-4 fdc05ee4a0 right sidebar: volume mixer: use listview, add separator 2025-07-17 23:43:20 +07:00
end-4 12e107448b right sidebar: add easyeffects toggle 2025-07-17 23:42:59 +07:00
end-4 c461bba5a3 Fix the theme color of the settings page; Update translations (#1659) 2025-07-17 17:16:22 +02:00
end-4 e38906714e Merge branch 'main' into addon-i18n 2025-07-17 17:15:52 +02:00
end-4 cfeae73c91 notifications: fix eliding when collapsed 2025-07-17 22:08:31 +07:00
end-4 5865a62a94 gitignore: add .qmlls.ini 2025-07-17 22:07:03 +07:00
月月 c64e079da4 translations: update translations/zh_CN.json 2025-07-17 22:10:37 +08:00
月月 7f3fb26651 Translation: Update weather information card title to support multiple languages, and clean up unnecessary translation entries 2025-07-17 22:01:41 +08:00
月月 fca5adbbd3 Recover the import "root:/services/" in the wrongly deleted setting.qml 2025-07-17 21:49:14 +08:00
end-4 254870c9ab quickshell: use qs imports instead of root:/ 2025-07-17 20:24:01 +07:00
end-4 fb6721e348 sidebar: ai chat: think block: fix undefined easing type 2025-07-17 20:23:43 +07:00
end-4 6d9e4ad2fa more quickshell.execdetached instead of hyprland dispatch trick 2025-07-17 20:23:03 +07:00
end-4 6f5781564c hyprlock: bolder clock 2025-07-17 19:56:39 +07:00
end-4 20711e125b dock: right click to pin app 2025-07-17 15:45:43 +07:00
end-4 d197787ab8 fix tabbar warning 2025-07-17 15:45:35 +07:00
end-4 158428e63e not attempt to show translated globalshortcut description cuz they can't be changed 2025-07-17 15:28:31 +07:00
end-4 8a4f2f2851 Add custom multilingual implementation (#1633) 2025-07-17 10:19:50 +02:00
月月 9978c87b67 translations: update translations/zh_CN.json 2025-07-17 16:03:27 +08:00
end-4 1e7c84a6c1 translations: update qsTrs to Translation.tr and allow translation of notifications 2025-07-17 13:57:55 +07:00
月月 9ca67f0095 translations: Update Chinese language files 2025-07-17 14:25:57 +08:00
end-4 1429b5977b translations: adjust vietnamese 2025-07-17 13:13:38 +07:00
end-4 4660a154d0 translations: add untranslated text, fix some originals 2025-07-17 13:13:38 +07:00
月月 fec4990506 translations: Update chat save message in Chinese translations 2025-07-17 08:45:25 +08:00
月月 380d126b59 Merge branch 'addon-i18n' of https://github.com/xiaomeng2004/dots-hyprland into addon-i18n 2025-07-17 08:42:54 +08:00
月月 6dff90f7e2 Merge remote-tracking branch 'origin/main' into addon-i18n 2025-07-17 08:41:34 +08:00
end-4 9056b551ab add vietnamese translation 2025-07-17 01:35:49 +07:00
end-4 035e8b3e5d ai: fix weird save chat description 2025-07-17 00:22:15 +07:00
1cebp 3b0574bd46 Fix monitor offset w/ left-of-center monitors in overview 2025-07-16 13:16:01 -04:00
月月 2b2733679c i18n: Update translation for online model disallowance message to remove model name reference 2025-07-16 23:46:02 +08:00
end-4 864c83172b readme: make the ii logo on the left and note on the right 2025-07-16 17:41:16 +02:00
月月 8a68cf207a i18n: Refactor translation management tools and add ignore feature for dynamic resources
- Updated README.md to reflect changes in translation management tools and added ignore mark feature for dynamic resources.
- Created Chinese translation guide for the translation management tools.
- Created English translation guide for the translation management tools.
- Enhanced translation-cleaner.py to skip keys marked with /*keep*/ during cleanup.
- Improved translation-manager.py to create backups only when updating keys interactively.
- Updated zh_CN.json with new translations and added ignore marks for dynamic values.
2025-07-16 23:36:47 +08:00
end-4 db82175b61 Update CONTRIBUTING.md 2025-07-16 15:54:23 +02:00
月月 2ad60a40a8 i18n: Refactor string formatting to use arg() method for translations 2025-07-16 21:11:27 +08:00
月月 b98e843a9d i18n: removed duplicate translation services and fixed imports 2025-07-16 16:48:21 +08:00
Ninjdai 365a649776 Update UtilButtons.qml 2025-07-16 10:31:49 +02:00
Ninjdai 0ecf72b4c3 Merge branch 'end-4:main' into power-profile-toggle 2025-07-16 10:28:48 +02:00
end-4 93ef3c3bda dock: fix screen 2025-07-16 10:54:39 +07:00
end-4 19aa66568f background: add parallax for sidebars 2025-07-16 10:38:21 +07:00
end-4 d176d38552 dock: fix hover region and weird popup cutoff 2025-07-16 10:23:21 +07:00
end-4 623cd842a6 search: prevent shaky while typing, prevent clipboard scrolling to bottom 2025-07-16 10:00:48 +07:00
end-4 77f21d8e89 overview: don't fill the screen 2025-07-16 09:52:46 +07:00
end-4 eedd5d8f27 hyprland keybinds: remove trailing comma (#1559) 2025-07-16 09:39:53 +07:00
end-4 36390e107b dock: dont anchor left right 2025-07-16 09:35:42 +07:00
end-4 7821cfe131 dock: dont aggressively unload 2025-07-16 09:34:36 +07:00
end-4 a08e9e0e79 screen corners: not have a fullscreen layer 2025-07-16 09:34:22 +07:00
end-4 06ed6dd1e7 use space grotesk for clocks 2025-07-16 09:04:20 +07:00
Ninjdai 90013c7451 feat: power-profile switcher in topbar 2025-07-15 22:44:24 +02:00
end-4 bb221326eb background parallax: make half groups really half group 2025-07-16 00:17:18 +07:00
end-4 08e3a9bddb background: parallax wallpaper 2025-07-16 00:15:31 +07:00
end-4 abc9b4cdb7 systeminfo: fix distro id 2025-07-15 23:20:08 +07:00
end-4 c46a4cb3ef nuke anyrun 2025-07-15 22:45:34 +07:00
end-4 4d10ee6036 media controls: adjust color overlay transparency 2025-07-15 20:44:17 +07:00
end-4 cb20a2bc76 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-07-15 20:37:47 +07:00
end-4 77c5923782 cheatsheet: fix weird popup anim 2025-07-15 20:37:36 +07:00
end-4 ffe1783aa3 background: clock: fly in from random direction 2025-07-15 20:37:25 +07:00
end-4 bb27413e97 hyprland: add window rules for xdg-portal file dialogs (#1648) 2025-07-15 14:12:17 +02:00
nahilrasheed 86d3f75d12 hyprland: add window rules for xdg-portal file dialogs
Add windowrulev2 entries for file picker dialogs with titles like "wants
to save" and "wants to open" to float and center them.
2025-07-15 14:34:44 +03:00
end-4 3110df8974 background: make it fill properly 2025-07-15 09:27:05 +07:00
end-4 78c91500d6 wallpaper: fix stretch 2025-07-14 22:55:15 +07:00
end-4 631303bffe use quickshell for wallpaper 2025-07-14 20:43:52 +07:00
end-4 efa60d09fc Update CONTRIBUTING.md 2025-07-14 09:31:22 +02:00
月月 2eff8d6db4 i18n: Fix translatable string extraction tool bug. 2025-07-14 15:08:40 +08:00
Pim Rijkers 7fcea64020 Merge remote-tracking branch 'upstream/main' into right-sidebar--restore-last-viewed-bottom-widget 2025-07-13 22:15:29 +02:00
月月 8f3b2474d2 i18n: Add multilingual support for the Settings interface and update the Simplified Chinese translation file. 2025-07-14 00:33:03 +08:00
月月 0c2b807447 i18n: update translations/tools/README.md 2025-07-13 15:24:29 +08:00
月月 e0b7a7f4b1 Merge remote-tracking branch 'origin/main' into addon-i18n 2025-07-13 13:22:49 +08:00
月月 bdb7657e22 i18n:Update the translation tool guide 2025-07-13 13:19:53 +08:00
月月 99af57fbc6 Updated Chinese translation 2025-07-13 13:14:02 +08:00
end-4 66d1d3e9c3 volume mixer: adjust layout 2025-07-13 01:54:30 +07:00
end-4 a5831cf365 slider: more accurate sizes 2025-07-13 01:54:13 +07:00
end-4 f726c9495e media controls: fix black color on first open 2025-07-13 01:53:40 +07:00
end-4 e98f84d9bc bar: fix media title spilling for non-verbose 2025-07-13 00:20:58 +07:00
end-4 59afc892f4 Revert "bar: use lazyloader"
too lazy so revert, bar needed in most cases anyway
2025-07-12 22:42:25 +07:00
end-4 1641425fff reapply bar corner transparency fix 2025-07-12 22:37:38 +07:00
月月 fb0d3f7f40 i18n:Replace qstr with Translation.tr and update the translation file 2025-07-12 22:46:24 +08:00
end-4 271732ed0b bar: weather: fix popup position for bottom bar 2025-07-12 20:36:34 +07:00
end-4 e59dd2cab2 add option to disable theming (#1586) 2025-07-12 20:13:26 +07:00
月月 af5d25b575 Merge remote-tracking branch 'origin/main' into addon-i18n 2025-07-12 21:03:24 +08:00
end-4 f6bb5385cf search: use qs' execdetached instead of executor proc 2025-07-12 19:25:08 +07:00
end-4 c0a3a0d7d2 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-07-12 19:15:59 +07:00
end-4 ae58e59d67 search: konachan wallpaper command (#1624) 2025-07-12 19:15:41 +07:00
end-4 2c435da5d7 add windowrule floating for Zotero (#1623) 2025-07-12 14:15:04 +02:00
end-4 1e1aeb2673 notif popup: fix right spacing 2025-07-12 19:05:48 +07:00
end-4 c5982a3ee1 bar: use lazyloader 2025-07-12 19:05:37 +07:00
Habibul Fauzan e42b0d20f8 Update rules.conf add windowrule for Zotero
Update rules.conf add windowrule for Zotero
2025-07-12 09:24:47 +07:00
end-4 f52cfc3df0 bar: add keybind to toggle (super+j) 2025-07-12 07:58:34 +07:00
end-4 3aff266699 bar: fix corner transparency (#1618) 2025-07-11 18:30:13 +02:00
end-4 f3144a9c8f Add Cursor to Code Editor keybind (#1619) 2025-07-11 18:20:07 +02:00
1cebp d482796dc3 Add Cursor to Code Editor keybind 2025-07-11 11:17:27 -04:00
Sighthesia f2831c2b88 Hug bar round corner transparency 2025-07-11 21:44:11 +08:00
end-4 b958c0ad6c ai: save last chat, make sure model's messages are saved properly 2025-07-11 19:37:23 +07:00
end-4 b1ee817c78 Update ServicesConfig.qml 2025-07-11 19:37:04 +07:00
end-4 76422ff42b fix hardcoded "/home/end" (#1616) 2025-07-11 14:13:06 +02:00
陈华 4d3788cca6 fix kde-material-you-colors: wallpaper path 2025-07-11 15:01:20 +03:00
陈华 528f5e755b fix hardcoded paths: /home/end -> ~ 2025-07-11 14:57:40 +03:00
end-4 65179b2358 settings: add 24h/12h time format config 2025-07-11 17:52:42 +07:00
end-4 bb5eabb75e hyprland: fix plasma system monitor keybind 2025-07-11 17:36:37 +07:00
end-4 b8f04bef41 Update README.md 2025-07-11 12:35:49 +02:00
end-4 eec1251db6 Update README.md 2025-07-11 10:06:07 +02:00
end-4 ace114be0b Update README.md 2025-07-11 09:13:39 +02:00
end-4 75d344c9df readme: update badge colors 2025-07-11 08:59:05 +02:00
end-4 d05f1ce67f readme: add discord 2025-07-11 08:45:11 +02:00
obsidrielle 715aa8d845 feat: add option to ignore conflicting files 2025-07-11 13:37:25 +08:00
end-4 a10f08a775 unfuck terminal color generation (#1612) 2025-07-11 09:32:40 +07:00
end-4 35b687b4ea fix dirs in scripts 2025-07-11 09:29:58 +07:00
end-4 f0a2438dea fish: add alias for quickshell config 2025-07-11 09:26:18 +07:00
end-4 770c4de78b fix more properly 2025-07-11 09:19:05 +07:00
end-4 c2f12eedfc fix qs exec (fixes #1610) 2025-07-11 09:18:21 +07:00
end-4 c69eaf7777 move quickshell config to subfolder to ease distribution
https://quickshell.outfoxxed.me/docs/guide/distribution/
2025-07-10 22:03:01 +07:00
end-4 5ee46cfc30 overview: make icon sizes more acceptable (#1479) 2025-07-10 20:08:47 +07:00
end-4 33f2f960b9 quickshell: temporarily disable hyprland layer masking (#1479) 2025-07-10 16:26:17 +07:00
end-4 d2eefd5768 hyprland: no annoying overlapping dolphin copy dialog 2025-07-10 15:15:32 +07:00
end-4 280f7ff8c0 bar: activewindow: more accurate on multimonitor systems 2025-07-10 10:55:08 +07:00
end-4 7afea39f1d cheatsheet: periodic table: adjust colors 2025-07-10 10:54:46 +07:00
end-4 f865ed877d sidebar: warp: no weird connection loop 2025-07-09 22:33:11 +07:00
end-4 465660db07 overview: remove debug print 2025-07-09 22:32:26 +07:00
end-4 9293ffdb26 bar: clock: use shorter day of week (by default) 2025-07-09 22:32:18 +07:00
end-4 d572f4a113 switchwall: unfuck wallpaper query on multimonitor (#1581) 2025-07-09 14:36:07 +07:00
end-4 a8f52a5adf search: adjust highlight color 2025-07-09 14:35:27 +07:00
end-4 b6f0d00137 overview: unfuck window moving on offset monitors 2025-07-09 11:41:16 +07:00
end-4 8ba91edeae make screencorners exit more nicely 2025-07-09 10:41:49 +07:00
end-4 5081b2e9d1 unfuck startup wallpaper for multimonitor 2025-07-09 10:16:03 +07:00
end-4 9a90d26e81 right sidebar: cloudflare warp 2025-07-09 10:13:37 +07:00
end-4 a0301bbc13 settings: add search prefixes 2025-07-09 09:46:10 +07:00
end-4 8ca2ed6781 periodic table 2025-07-09 09:41:13 +07:00
end-4 b0750506cf give CustomIcon colorization 2025-07-09 09:40:59 +07:00
Pim Rijkers 44443c4a37 moved storage from config to persistent state 2025-07-08 14:16:40 +02:00
end-4 2d6a897a66 settings: more options 2025-07-07 18:17:57 +02:00
end-4 32380d29c8 settings: add osd timeout 2025-07-07 17:57:05 +02:00
end-4 d801f132d1 bar: add outline to floating mode 2025-07-07 17:56:54 +02:00
end-4 45369c1ec4 appearance: not make bg color weird 2025-07-07 17:43:44 +02:00
end-4 52810b97f4 settings: apply colors on material palette selection 2025-07-07 17:43:19 +02:00
end-4 813395c987 move weathericons.qml 2025-07-07 17:30:44 +02:00
end-4 04e0266a4e sidebar: ai: add suggestions for save/load 2025-07-07 17:19:50 +02:00
end-4 ae69a4f11a ai: load/save 2025-07-07 16:48:43 +02:00
Pim Rijkers 25eb5fb449 add automatic restore 2025-07-07 14:13:35 +02:00
end-4 9d6452aaaf screenshooter: remove weird gap on non-window region labels 2025-07-06 09:11:37 +02:00
end-4 43b9378144 config: option to show/hide screenshot content regions (#1539) 2025-07-06 09:06:14 +02:00
end-4 7bcb01964f settings: move weather 2025-07-06 09:05:23 +02:00
end-4 e06ab94fb6 readme: remove acceidentally pasted image 2025-07-05 21:04:18 +02:00
end-4 e393e4df1a readme: add showcase video for ii-qs 2025-07-05 21:03:54 +02:00
end-4 b679a1339a feat(modules/bar): add weather bar (#1520) 2025-07-05 11:50:52 +02:00
end-4 e843164f60 bar: weather: fix alignment 2025-07-05 11:50:26 +02:00
end-4 8dccac4cda bar: weather: disable by default 2025-07-05 11:45:27 +02:00
end-4 41a8bfa097 bar: weather popup: use loader properly 2025-07-05 11:44:28 +02:00
end-4 ba8c737543 weather bar: remove unnecessary nested item 2025-07-05 11:38:07 +02:00
end-4 9043440c8d fix spacing 2025-07-05 11:37:51 +02:00
end-4 f6f7ac19fd fix bar font size 2025-07-05 11:32:59 +02:00
end-4 bcb60d8ab7 Update README.md 2025-07-05 10:30:18 +02:00
end-4 73d13254de Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-07-05 09:55:15 +02:00
end-4 d5f7a72d19 bar: workspaces: adjust monochromization 2025-07-05 09:55:12 +02:00
end-4 d4f193ae69 dock: monochrome icons 2025-07-05 09:55:01 +02:00
end-4 265b410a87 Update switchwall.sh 2025-07-05 09:07:23 +02:00
end-4 d9b9b8c9b2 media controls: mix a bit of accent color 2025-07-05 09:06:59 +02:00
end-4 9b050e8e21 add border to panels 2025-07-05 09:06:22 +02:00
end-4 b0cd46f783 screenshot: add app icons 2025-07-05 09:05:43 +02:00
end-4 3c7d55c793 extra bg tint 2025-07-05 09:05:08 +02:00
end-4 4e71d002ea smooth zooming 2025-07-05 09:04:52 +02:00
end-4 cd92d14ad2 readme: update screenshot 2025-07-05 08:43:30 +02:00
end-4 db64d4a12b include possible zed aliases in keybinds.conf (#1575) 2025-07-05 07:25:13 +02:00
ふらまりん b289ceccad include possible zed aliases in keybinds.conf 2025-07-05 11:23:26 +08:00
end-4 f973052d16 Update README.md 2025-07-05 01:29:11 +02:00
end-4 16e07a8213 Update README.md 2025-07-05 00:25:10 +02:00
end-4 5064db2aad readme: add illogical impulse logo 2025-07-05 00:23:27 +02:00
end-4 cf20581603 Update README.md 2025-07-05 00:18:38 +02:00
end-4 e78b84cd41 bar: monochrome icons 2025-07-04 20:02:44 +02:00
end-4 7d2856e9b7 deps: add darkly qt style 2025-07-04 17:54:15 +02:00
end-4 1fb0e8b32b add breeze 2025-07-04 17:51:12 +02:00
end-4 83a7581a34 icon guess: fix steam regex 2025-07-04 17:20:33 +02:00
end-4 8cd0433ab6 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-07-04 17:04:49 +02:00
end-4 2f03ce5f06 symlink quickshell to illogical impulse icon
remove this if quickshell gets its icon bundled later
2025-07-04 17:03:27 +02:00
end-4 3a9189a994 readme: remove "pls logo ideas" 2025-07-04 17:00:43 +02:00
end-4 c7519f338e add logo (closes #1436) 2025-07-04 16:58:44 +02:00
end-4 11dcffb95d overview: only show windows in same monitor as widget 2025-07-03 23:04:41 +02:00
end-4 746c5805fb Update Config.qml 2025-07-03 23:04:00 +02:00
end-4 85a9a08b43 settings: add dock options 2025-07-03 22:56:45 +02:00
end-4 089468393e notifs: discard notif on action invocation 2025-07-03 22:56:23 +02:00
end-4 e99f51e6ac media: fix space at start of track title 2025-07-03 22:56:05 +02:00
Hasan A. Tekeoğlu 8b83b42eed chore(Weather): use generic city name for default value 2025-07-03 10:00:08 +03:00
月月 66579f659f Merge remote-tracking branch 'origin/main' into addon-i18n 2025-07-02 22:21:58 +08:00
Hasan A. Tekeoğlu f51c0c7c9a Merge branch 'weather-bar-feat' of https://github.com/tekeoglan/dots-hyprland into weather-bar-feat 2025-07-02 15:53:12 +03:00
Hasan A. Tekeoğlu 9ecbe09de5 Merge branch 'end-4:main' into weather-bar-feat 2025-07-02 15:52:49 +03:00
Hasan A. Tekeoğlu 2684bbae69 refactor(WeatherBar): put in barRightSide 2025-07-02 15:52:24 +03:00
end-4 59ef5ac390 dock: add back enable config option now that it works properly 2025-07-02 13:44:05 +02:00
end-4 c00d2a5b50 ai: add prompt configuration 2025-07-02 12:49:39 +02:00
end-4 e23d8abef3 hyprland: noblur only for xwayland context menus (closes #1509) 2025-07-01 22:43:33 +02:00
end-4 fc3c711a7e installation: make symlink command not fail the script (#1486) 2025-07-01 19:48:45 +02:00
end-4 d358b35876 unfuck light/dark switching (#1556) 2025-07-01 18:00:20 +02:00
Hasan A. Tekeoğlu fd6af822cd chore(Weather): make things more clear 2025-07-01 13:42:54 +03:00
Hasan A. Tekeoğlu 50cc371100 chor(Weather): rename show to enable 2025-07-01 13:19:24 +03:00
Hasan A. Tekeoğlu c94231365f chore(WeatherService): rename to Weather 2025-07-01 12:57:14 +03:00
Hasan A. Tekeoğlu b982c788fe style(WeatherPopup): remove the border 2025-07-01 07:11:06 +03:00
Hasan A. Tekeoğlu 67c75b1cce fix(ServiceConfig): add weatherbar section 2025-07-01 05:42:50 +03:00
Hasan A. Tekeoğlu fd873ff7c1 fix(): WeatherBar pushing MiddleSection to the left 2025-07-01 05:29:10 +03:00
Hasan A. Tekeoğlu c17db4bfb1 Resolve conflicting merge issues 2025-07-01 05:20:41 +03:00
Hasan A. Tekeoğlu a18791ef16 Merge branch 'weather-bar-feat' of https://github.com/tekeoglan/dots-hyprland into weather-bar-feat 2025-07-01 04:49:29 +03:00
end-4 9892e51e1d sidebar: description box: dont show arrows when 1 item 2025-06-30 21:43:29 +02:00
end-4 bf936cd0d7 sidebar: make ai and booru suggestion description clearer 2025-06-30 21:32:06 +02:00
end-4 5ffcf98487 persistent states: also use jsonadapter 2025-06-30 17:23:46 +02:00
end-4 8e7a376407 hyprland: make borders more readable 2025-06-30 16:56:59 +02:00
end-4 6e9bb4945c screenshot: do offset adjustments directly on each monitor's region data (#1539) 2025-06-30 15:37:01 +02:00
end-4 45846bf696 screenshot: fix offset region target on click (#1539) 2025-06-30 15:28:55 +02:00
end-4 7ca0f263ba configoptions: use quickshell jsonadapter 2025-06-30 14:27:26 +02:00
end-4 22319ffccf hyprland: update window rules 2025-06-30 13:53:10 +02:00
end-4 68673de641 screenshot: fix window/layer positions for offset monitors (#1539) 2025-06-30 13:51:50 +02:00
end-4 50eae43ca2 screenshot: fix content regions on scaled monitors (#1539) 2025-06-30 13:12:52 +02:00
end-4 5d6db58d76 bar: shadow for floating style 2025-06-29 23:49:45 +02:00
end-4 d513d0e1b3 welcome: add bar style 2025-06-29 23:49:35 +02:00
end-4 32dd5eecb7 Create .qmlformat.ini 2025-06-29 23:40:38 +02:00
end-4 ecb2f246b6 settings: add config option for floating bar 2025-06-29 23:10:13 +02:00
end-4 18ea20f1df bar: fix bottom mode, add corner style config 2025-06-29 23:00:57 +02:00
end-4 30c54cb7ce screenshot: account for scaled monitors (#1539) 2025-06-29 21:05:31 +02:00
end-4 65f9b6a242 settings: prompt config add callater for setting 2025-06-29 21:05:31 +02:00
end-4 abdfd17482 Update color.txt path in switchwall.sh (#1530) 2025-06-29 15:16:45 +02:00
end-4 fdc0f16b08 volume mixer: manual node filtering to make it work with easyeffects 2025-06-29 08:51:07 +02:00
end-4 36db4ae327 screenshot tool: add layer regions 2025-06-29 00:23:19 +02:00
Hasan A. Tekeoğlu 689f6c90e7 feat(WeatherService): add geolocation service 2025-06-28 20:48:34 +03:00
Hasan A. Tekeoğlu d8f5471b3e config(WeatherService): add enableGps option 2025-06-28 20:45:49 +03:00
Hasan A. Tekeoğlu 9404b21f82 config(hyprland): fix invalid geoclue agent path 2025-06-28 16:58:54 +03:00
Hasan A. Tekeoğlu bb456687a6 feat(settings): add weather section 2025-06-28 08:35:22 +03:00
Hasan A. Tekeoğlu 660af6e018 fix(modules/bar): WeatherBar pushing middlesection to the left 2025-06-28 08:34:43 +03:00
Hasan A. Tekeoğlu d7cf0f4f27 fix(WeatherBar): not using config fonts 2025-06-28 08:32:39 +03:00
end-4 4b17b1aae7 screenshot keybind: add fallback 2025-06-27 22:21:02 +02:00
end-4 604abfea96 screenshot: use quickshell, ksnip -> swappy 2025-06-27 22:10:45 +02:00
end-4 ad73ca018a record script: fix fullscreen 2025-06-27 22:07:57 +02:00
end-4 bfc3918b2d update keybinds 2025-06-27 21:35:28 +02:00
end-4 d73e72097b remove unnecessary include 2025-06-27 16:26:19 +02:00
end-4 a202e16116 notifs: fix weird preview when body contains newlines 2025-06-27 16:25:57 +02:00
end-4 5588f8f1d5 material symbols: format 2025-06-27 16:25:42 +02:00
end-4 561a528bef update ai prompt 2025-06-27 16:25:26 +02:00
月月 7299642cf5 Merge remote-tracking branch 'origin/main' into addon-i18n 2025-06-27 18:40:06 +08:00
Hasan A. Tekeoğlu 3f44ecb068 feat(modules/bar): add weather bar 2025-06-27 12:30:25 +03:00
end-4 4f7ed4da53 search widget: fix wrong calculator result (#1424) 2025-06-26 22:37:03 +02:00
end-4 08b07ff729 Add dolphin as dependency (#1431) 2025-06-26 22:30:47 +02:00
end-4 f119a44442 ai: fix code blocks being cut off (#1513) 2025-06-26 22:19:20 +02:00
end-4 b27dc3496c progressbar: unecessary rect -> item 2025-06-26 22:18:16 +02:00
end-4 4a2453410a deps: add qt avif image plugin
for yt thumbnails
2025-06-24 14:51:04 +02:00
torhaala 51885623c8 Update switchwall.sh 2025-06-23 18:41:29 +02:00
end-4 ad462649b0 add brave browser substitution (fixes #1439) 2025-06-23 10:17:38 +02:00
end-4 b6ba428404 settings: more options 2025-06-23 02:37:28 +02:00
end-4 06574c19ae settings: increase page content width 2025-06-23 02:37:15 +02:00
end-4 7ca2da3723 overview: remove show xwayland indicator option
we dont show an ugly icon now so it's not necessary
2025-06-23 02:36:52 +02:00
end-4 6ebccf097f settings: make sections clearer 2025-06-23 02:36:07 +02:00
end-4 7cf3c264ab fix spinbox looped value 2025-06-23 02:35:55 +02:00
end-4 ced0f6efb1 settings: more options 2025-06-23 01:35:08 +02:00
end-4 5991c8f994 add styled textinput 2025-06-23 01:34:44 +02:00
end-4 b5046fa6dc content subsection: add info tooltip 2025-06-23 01:34:32 +02:00
end-4 1cd5b0ba1d battery: add auto suspend 2025-06-23 01:34:10 +02:00
end-4 d03100d60a add spinbox 2025-06-23 01:33:31 +02:00
end-4 529b67d728 fix dark/light mode util button not in rowlayout 2025-06-22 23:24:17 +02:00
end-4 b05e682545 feat(modules/bar): add nightmode button (#1481) 2025-06-22 23:20:53 +02:00
end-4 e97e41c162 revert weird util button width 2025-06-22 23:20:29 +02:00
月月 a5fca59a69 Merge remote-tracking branch 'origin/main' into addon-i18n 2025-06-22 19:19:18 +08:00
Hasan A. Tekeoğlu 5d9620881b feat(modules/bar): change darkmode without changing the wallpaper 2025-06-21 21:25:29 +03:00
Hasan A. Tekeoğlu cdbb72bec4 Merge branch 'end-4:main' into darkmode-button-feat 2025-06-21 21:02:06 +03:00
end-4 7e46e40eeb settings: reorganize and add settings 2025-06-21 11:59:40 +02:00
end-4 5ffbd55f58 settings: bar and audio options 2025-06-21 03:24:03 +02:00
月月 cef02f367b Merge remote-tracking branch 'origin/main' into addon-i18n 2025-06-21 09:10:40 +08:00
end-4 ddcf13678d sidebar: make gamemode update properly 2025-06-21 03:00:01 +02:00
end-4 e4be9852a3 quickshell: switch from hyprland dispatch exec trick to quickshell execdetached 2025-06-21 02:51:21 +02:00
end-4 29c7031bb2 refractor selection groups and config option row 2025-06-21 01:31:34 +02:00
end-4 f66e26d4cc content page: add bottom padding 2025-06-21 01:05:04 +02:00
end-4 d5a9ae32f2 adjust config switch size 2025-06-21 01:04:07 +02:00
end-4 47c9d63210 add center title config option 2025-06-21 01:03:56 +02:00
Hasan A. Tekeoğlu e56fbf820a feat(modules/bar): add nightmode button 2025-06-20 22:04:29 +03:00
end-4 3d9a5a72b6 settings: add titlebar 2025-06-19 23:29:52 +02:00
end-4 2db4b33fe2 fix configswitch not working when clicking the actual switch 2025-06-19 23:29:25 +02:00
end-4 a940c1b4fe adjust transparency 2025-06-19 23:29:06 +02:00
end-4 d437e126ab enable wayland flag for chrome and code again 2025-06-19 21:49:11 +02:00
end-4 62e0b7f669 redo accidentally overwritten corner transparency 2025-06-19 21:19:30 +02:00
end-4 eaa56ff555 settings: add material palette and transparency 2025-06-19 19:32:31 +02:00
end-4 e8414c88ba settings: about page 2025-06-19 18:58:30 +02:00
end-4 0416ddbf3f swappy -> ksnip 2025-06-19 17:54:09 +02:00
end-4 4ebd486426 add back ai primary buffer query (closes #1462) 2025-06-19 17:31:36 +02:00
end-4 f844a54a87 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-06-19 17:21:42 +02:00
end-4 0caf72a78f make right sidebar open qs settings app 2025-06-19 17:21:28 +02:00
end-4 bd6e8894b6 notifications: drop actions on restart (they don't work properly anyway) 2025-06-19 17:21:05 +02:00
end-4 cbed76fea9 adjust transparency 2025-06-19 17:20:03 +02:00
end-4 fd1f9c39b0 update window rule for settings app 2025-06-19 17:19:43 +02:00
end-4 8bc05c1373 settings: use quickshell settings app 2025-06-19 17:19:29 +02:00
end-4 cad1cfb66a hyprland: adjust anims, disable swallow 2025-06-19 17:19:02 +02:00
end-4 f80feb6734 Bar.qml: Fix round decorators transparency and visibility consistency with bar (#1470) 2025-06-19 17:15:25 +02:00
スケベ ad7fdd1d3f layout indicator in top right 2025-06-19 18:14:05 +03:00
Sighthesia bf6e5fafea Bar.qml: Fix round decorators transparency and visibility consistency with bar 2025-06-19 20:35:10 +08:00
end-4 f5ea891dd7 settings: add fake screen rounding option 2025-06-19 08:19:33 +02:00
end-4 1814f7cbec update settings pages 2025-06-19 08:13:15 +02:00
end-4 6abefecedf refractor button with icon and lightdark pref button to new file 2025-06-19 08:13:08 +02:00
end-4 07b6e8efbd even better dupe media player filtering 2025-06-19 08:11:01 +02:00
end-4 e7897cef8b more media controls filter trick (#1443) 2025-06-19 08:08:34 +02:00
end-4 66bd690b66 sidebar: calendar: animated navrail selection 2025-06-19 00:37:53 +02:00
end-4 7fba4b72bf content page: add min width 2025-06-19 00:37:30 +02:00
end-4 aefeeb8f6f adjust anim curves 2025-06-19 00:36:46 +02:00
end-4 3f294416ea refractor navrail tab array 2025-06-19 00:36:37 +02:00
end-4 9f4c75a75c settings: pages 2025-06-18 23:56:47 +02:00
end-4 bd79bc232b fab: update color mappings 2025-06-18 23:56:22 +02:00
end-4 ab991789f0 welcome: refractor content page and sections 2025-06-18 23:56:10 +02:00
end-4 b4340091c4 appearance: add colonprimarycontainer, anim curve durations 2025-06-18 23:55:30 +02:00
end-4 811a1ce6cb material symbol: also bold when filled 2025-06-18 23:55:06 +02:00
end-4 ed5be0c2ac nuke old navigation rail button 2025-06-18 23:51:45 +02:00
end-4 02f1ed75f3 add comment 2025-06-18 23:51:35 +02:00
end-4 16ed1f107f navigationrailbutton: make tabbar-compatible 2025-06-18 17:49:28 +02:00
end-4 37282e4316 welcome: more padding, add tooltips 2025-06-18 17:30:38 +02:00
end-4 93baba1568 settings app: expandable navrail buttons 2025-06-18 17:30:18 +02:00
end-4 afbf6c8ccd xdg desktop portal: gtk -> kde 2025-06-18 17:28:56 +02:00
end-4 5d24cc45a3 config options: remove image viewer 2025-06-18 10:41:57 +02:00
end-4 08d6c07d19 update starship config 2025-06-18 09:26:57 +02:00
end-4 3123a78bfe settings app: base window with navrail 2025-06-18 01:45:05 +02:00
end-4 aafa661f7a revealer: fix abrupt hiding 2025-06-18 01:37:16 +02:00
end-4 5c045c0b42 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-06-18 01:35:58 +02:00
end-4 59a58d8f76 adjust rectangular shadow strength 2025-06-18 01:35:45 +02:00
end-4 644c081812 rename navrailbutton -> navigationrailbutton 2025-06-18 01:35:32 +02:00
end-4 a68fa96b52 DateTime based on system locale (#1444) 2025-06-17 23:50:56 +02:00
end-4 20097099e1 refractor selection button to new file 2025-06-17 23:20:29 +02:00
end-4 a6a2b51970 fix progress bar binding loop 2025-06-17 23:20:06 +02:00
スケベ f2c72cad4a localized datetime 2025-06-18 00:12:53 +03:00
end-4 d1822be2a9 center-right block click to open right sidebar (closes #1442) 2025-06-17 19:05:07 +02:00
Zhineng Cao b34a26724f Merge branch 'end-4:main' into new-i18n 2025-06-17 19:17:01 +08:00
end-4 dd2e2a9bca config option for csd of quickshell windows 2025-06-17 12:27:39 +02:00
end-4 3acbe92363 welcome: fill buttons 2025-06-17 12:24:06 +02:00
end-4 72f2aa5c2f welcome: weeb & ai policy 2025-06-17 12:21:22 +02:00
end-4 5d7905b566 welcome: choose wallpaper file button 2025-06-17 11:38:49 +02:00
end-4 6d822142ad Update README.md 2025-06-17 11:06:26 +02:00
end-4 745857e515 welcome: random wall 2025-06-17 10:49:11 +02:00
end-4 8419697542 welcome: more buttons 2025-06-17 10:06:23 +02:00
end-4 c725284acb notifications: discard dead notif on action 2025-06-17 09:51:06 +02:00
月月 ccabd24db2 Add imports to service modules to support session functionality 2025-06-17 15:47:57 +08:00
end-4 265d3fdbdc quickshell: first run: set wallpaper iff none set 2025-06-17 09:07:09 +02:00
月月 89e25e3504 Add translation management tool suite and update Chinese translations
- Introduced a comprehensive guide for the translation management tool suite, detailing components, usage, and best practices.
- Added `translation-manager.py`, `translation-cleaner.py`, and `manage-translations.sh` scripts for managing translations.
- Updated the Chinese translation file (`zh_CN.json`) to improve existing translations and remove unused keys.
- Enhanced documentation with examples and troubleshooting tips for better user experience.
2025-06-17 14:29:33 +08:00
end-4 45b31f1eae Add emoji dependency (#1435) 2025-06-17 08:26:16 +02:00
end-4 d6718e9f10 noto emoji -> twemoji 2025-06-17 08:26:02 +02:00
lautaro ezequiel deco ef2248b523 Add shell emojis dependency 2025-06-17 02:40:35 -03:00
月月 b32734b9f5 Quickshell qstr seems not to be working, trying to implement custom translation
Add Chinese (zh_CN) translations for Quickshell interface and settings
2025-06-17 12:54:22 +08:00
Jx 9e27b4f232 Add dolphin as dependency 2025-06-17 00:18:27 -03:00
end-4 54dfad1d5b add keybind to edit shell config 2025-06-17 01:48:44 +02:00
end-4 11607ac41e add pr template to prevent "hi i made many personal changes pls merge" 2025-06-17 01:17:54 +02:00
end-4 ed60ccdf5d big icon view for wallpaper picker 2025-06-17 00:45:14 +02:00
end-4 050ba1606e Add terminalApp global for kde Apps (#1408) 2025-06-17 00:42:24 +02:00
end-4 a1ea208113 fix: quickshell bar swap usage NaN (#1427) 2025-06-17 00:39:06 +02:00
end-4 83bc08e810 sidebar: ai chat: clearer "pls /key" for newcomers 2025-06-17 00:30:59 +02:00
end-4 36e87fe71f tray: accessibility: bigger size, config option for monochrome 2025-06-17 00:18:12 +02:00
end-4 2c90de7375 auto m3 palette: use scheme-content for very low saturation pics 2025-06-17 00:17:16 +02:00
end-4 00b1aa1222 config options: add fixed bg clock pos 2025-06-16 23:41:45 +02:00
end-4 5dfa1b3445 fix config arrays stored as objects 2025-06-16 23:25:59 +02:00
end-4 a40d0c96af video wallpapers: prevent mpv mpris (#1360) 2025-06-16 22:46:47 +02:00
end-4 96d17f8fcb material palette: apply to kde material you colors 2025-06-16 22:46:14 +02:00
end-4 1cebec39f7 allow customizing material color palette w/ auto mode 2025-06-16 22:27:50 +02:00
end-4 5c4c1f5362 adjust welcome colors 2025-06-16 22:26:27 +02:00
end-4 92051b88ec audio: make volume not stuck over max (#1411) 2025-06-16 21:21:33 +02:00
end-4 6cd80407c0 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-06-16 21:15:35 +02:00
end-4 c27238548d audio: more nan fix (#1411) 2025-06-16 21:15:34 +02:00
end-4 b4b2ca1790 Fixed Terminal Color generation bug for quickshell (#1428) 2025-06-16 19:09:51 +02:00
end-4 a5a9f907cd audio: protection: don't change volume to NaN (#1411) 2025-06-16 19:06:37 +02:00
hrsvrn 97255be8ed Fixed Terminal Color generation bug for quickshell 2025-06-16 20:20:07 +05:30
Souyama e631c2e3d3 fix swap usage nan 2025-06-16 16:59:15 +05:30
end-4 dbd36c2fb4 Update README.md 2025-06-15 23:31:58 +02:00
end-4 31ba269d24 hyprland: add float rule+keybind for welcome app 2025-06-15 16:24:15 +02:00
end-4 41c5c2a99b first run experience: welcome app 2025-06-15 16:22:47 +02:00
end-4 eb8fc41c01 dock: make loading async 2025-06-15 16:22:13 +02:00
end-4 e4683115bd update issue templates for quickshell version 2025-06-15 13:52:13 +02:00
end-4 503823aa2e config options: add weeb and ai policies 2025-06-15 10:09:56 +02:00
end-4 1f41129669 record script: adjust message case 2025-06-15 09:16:25 +02:00
end-4 6c4830c47a record.sh fixes (#1351) 2025-06-15 09:05:41 +02:00
end-4 cbe04512ee search: remove arch-specific command-not-found funcitonality (#1409) 2025-06-15 08:59:39 +02:00
end-4 7b12756b93 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-06-15 08:58:52 +02:00
Sneethe 1bbafaa97d Merge branch 'main' of https://github.com/end-4/dots-hyprland into record-script.sh 2025-06-15 15:38:24 +10:00
Celestial.y ca9d4f8353 Fix an error in env file (#1412) 2025-06-15 11:55:36 +08:00
Bishoy Ehab 75d70d5e87 Fix an error in env file 2025-06-15 05:37:44 +03:00
Celestial.y 22a796deae Not using recursive env var
P.S. I have had done it in ii-ags
2025-06-15 09:08:08 +08:00
end-4 e190c6c7db make background widget loader async 2025-06-15 01:27:40 +02:00
Jx f8d9d92e49 Add terminalApp global for kde Apps
This helps with "Open with neovim" in dolphin.

Although it doesn't apply the quickshell theme since it opens kitty and neovim without going through a shell.

I'm not sure what would be the proper solution
2025-06-14 17:59:54 -03:00
end-4 f33fb45b89 no sussy trust me bro 2025-06-14 15:59:01 +02:00
end-4 859c79010c readme: installation: point to wiki page of new version 2025-06-14 12:46:21 +02:00
end-4 bc993bb7e2 quickshell: add scale factor envvar 2025-06-14 11:11:36 +02:00
end-4 7ef91639e8 keybinds: make stuff more nicely packed on the cheatsheet 2025-06-14 11:08:28 +02:00
end-4 e5e4f40867 window rules: more precise catch for kde's bluetooth connect 2025-06-14 10:56:12 +02:00
end-4 67edf4e822 keybinds: apps: more flexibility 2025-06-14 10:55:53 +02:00
end-4 9a360a3009 overview: left/right to switch ws 2025-06-14 10:08:04 +02:00
end-4 f92718c391 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-06-14 10:01:42 +02:00
end-4 f17437b419 fix right sidebar esc to close 2025-06-14 10:01:40 +02:00
end-4 468709c645 readme: deprecation notice for ags version 2025-06-14 08:48:45 +02:00
end-4 389246b180 background clock: hide in default position 2025-06-14 08:16:59 +02:00
end-4 5cb087e650 installation: set qt app style 2025-06-14 00:26:02 +02:00
end-4 c802217513 Merge branch 'main' of https://github.com/end-4/dots-hyprland 2025-06-14 00:04:08 +02:00
end-4 ec14e36be3 installation: include dolphin app nag fix 2025-06-14 00:03:58 +02:00
end-4 590f25aeff readme: add thanks fox 2025-06-13 23:50:16 +02:00
end-4 fba79bdd21 readme: no more fuzzel in main stuff list 2025-06-13 23:44:48 +02:00
end-4 a45210db9e remove "pls test quickshell version" (#1401) 2025-06-13 23:44:08 +02:00
_xB 1af3f6f485 unneeded stuff 2025-06-14 00:27:06 +03:00
end-4 46692d4bbb Update README.md 2025-06-13 23:16:26 +02:00
end-4 32ae084d86 illogical-impulse: Quickshell rewrite (#1276) 2025-06-13 23:15:42 +02:00
end-4 5fb1efa8bb bar: fix bracket 2025-06-13 23:13:24 +02:00
end-4 924fc26eaa QS Rewrite: notification: Fix Chromium-based notifs (#1362) 2025-06-13 23:02:07 +02:00
end-4 c96f2f5eb4 notif filter: remove redundant "edge" 2025-06-13 23:00:59 +02:00
end-4 63c59af390 QS Rewrite: bar: Add an option for choosing screens (#1363) 2025-06-13 22:55:20 +02:00
end-4 0ad9858379 bar: screensList -> screenList 2025-06-13 22:54:24 +02:00
end-4 0b49b73152 config options: bar: rename screensList -> screenList 2025-06-13 22:54:00 +02:00
end-4 62909dedfa configoptions: bar: empty screen list by default 2025-06-13 22:52:18 +02:00
end-4 50e69c2fa5 bar: fix screen filtering 2025-06-13 22:51:50 +02:00
_xB 2e472450c5 notifications: support popular chromium-based browsers 2025-06-13 23:45:18 +03:00
_xB 975c469e1a notifications: re-add support for HTML tags 2025-06-13 23:29:17 +03:00
end-4 e72405c754 revealer: fix visibility 2025-06-13 22:28:08 +02:00
end-4 2b384330fc bar: increase ws number show delay 2025-06-13 22:27:58 +02:00
end-4 8a0204a279 bar: add the missing '&&' 2025-06-13 22:27:39 +02:00
end-4 b7bc1a1a12 Merge branch 'main' into ii-qs 2025-06-13 22:04:15 +02:00
end-4 4d6deffd88 install script: update ags version notice 2025-06-13 21:45:08 +02:00
end-4 efb2f3fee5 install script: notify about ags version 2025-06-13 21:36:05 +02:00
end-4 d70a117270 bar: make groups cleaner 2025-06-13 20:39:09 +02:00
_xB 1a0df48ac3 bar: Use ScriptModel to only update related screens 2025-06-13 21:38:33 +03:00
end-4 753df0b48c fish: make clear actually clear in kitty 2025-06-13 20:33:36 +02:00
end-4 be5b932beb bar: workspaces: show dots only by default 2025-06-13 18:23:02 +02:00
end-4 b1729eed27 fix weird material symbols 2025-06-13 18:22:47 +02:00
end-4 cb6021602e keybinds: fix ctrl+super opening overview 2025-06-13 18:20:19 +02:00
end-4 1cdb124fd4 keybinds: prevent multiple overlaying screen snips 2025-06-13 18:19:59 +02:00
end-4 3011f77e88 media controls: adjust colors 2025-06-13 17:37:07 +02:00
end-4 c882b162d2 fix active window title not showing 2025-06-13 17:36:48 +02:00
end-4 dc24541f61 add transparency option (#1398) 2025-06-13 17:04:53 +02:00
end-4 89ed9e2b52 progress bar: make sperm amplitude follow the m3 specs 2025-06-13 15:46:05 +02:00
end-4 925f82301a fix newline before prompt (proper solution for#1397) 2025-06-13 15:45:35 +02:00
_xB b759be8e7e Merge branch 'ii-qs' into ii-qs-patch-1 2025-06-12 19:37:50 +03:00
end-4 da8a8aec4e adjust default util button visibility 2025-06-12 15:35:31 +02:00
end-4 b70e176011 QS Rewrite: bar: add microphone control to util buttons (#1365) 2025-06-12 15:33:58 +02:00
end-4 4c97434cca util buttons: make buttons hide properly 2025-06-12 15:33:27 +02:00
end-4 4a9af7e7bd translator: add no skibidi flag at right place 2025-06-12 15:27:20 +02:00
end-4 30f3825f1d progressbar: sperm: fix left end cutoff 2025-06-12 15:24:54 +02:00
_xB 3767542bac bar: re-add color picker button config 2025-06-12 13:51:48 +03:00
end-4 22fb505af9 progress bar: change sperm morphing anim curve 2025-06-12 12:51:28 +02:00
_xB f76fe37269 bar: re-add color picker button 2025-06-12 13:51:03 +03:00
end-4 acc6ce644e media controls: material 3 sperm 2025-06-12 12:43:45 +02:00
end-4 8f094e9a90 translator: add useless flag arabian guy requested 2025-06-12 12:43:10 +02:00
end-4 a63dec24b8 fix typo (#1393 is closed?) 2025-06-12 12:00:17 +02:00
_xB c8be29e02c Merge branch 'ii-qs' into ii-qs-patch-1 2025-06-12 09:23:30 +03:00
_xB fc157dd709 bar: Filter Variants instead of hiding PanelWindow 2025-06-12 09:22:22 +03:00
_xB af409dc0c9 bar: wrap buttons in Loaders 2025-06-12 09:01:25 +03:00
end-4 13bad429bc refractor visualizer to its own file 2025-06-12 07:44:03 +02:00
end-4 89ff743c5d Appearance: more m3colors in colors 2025-06-12 07:43:52 +02:00
_xB c3fa00b5c6 bar: add visibility options to utilButtons 2025-06-12 05:45:22 +03:00
_xB 60c93fd2ee Add the utilButtons config options 2025-06-12 05:43:36 +03:00
end-4 b7b183d2ca quickshell: use more .colors (rather than .m3colors) 2025-06-12 00:12:24 +02:00
end-4 1721c2bbb2 material symbols: disable filll anim for now
performance/memory concerns
2025-06-11 23:16:38 +02:00
end-4 24374efdce bar: change music icon 2025-06-11 23:16:11 +02:00
end-4 5a867ea061 media controls: improve dupe entry filtering, correct cava config 2025-06-11 22:59:16 +02:00
end-4 c2c7078957 translator: remove debug print 2025-06-11 22:30:55 +02:00
end-4 a3818322a6 media controls: visualizer 2025-06-11 22:30:43 +02:00
end-4 4473129599 fix session screen button size 2025-06-11 11:52:24 +02:00
end-4 23f0e90a7b sidebar: translator: save selected language, cleaner selector 2025-06-11 11:36:56 +02:00
end-4 0fb28af3c7 sidebar: translator: change layout to reduce eye movement 2025-06-11 11:06:22 +02:00
end-4 65983ade46 sidebar: translator: language selector 2025-06-11 10:59:52 +02:00
end-4 244d3f6067 idle inhibitor button: now wrong binding 2025-06-11 09:01:24 +02:00
end-4 8956752e85 ripple button: default size based on contentitem 2025-06-11 09:00:28 +02:00
end-4 039cb57167 overview: partially fix window position for offset monitors (#1388) 2025-06-11 08:39:18 +02:00
end-4 ac6a64efab right sidebar: fix idle inhibitor exiting on close (#1381) 2025-06-11 08:25:05 +02:00
end-4 fa75cc91a0 Add systemsettings as dependency (KDE desktop config) (#1385) 2025-06-11 08:04:17 +02:00
Jx ee0df41dec Add systemsettings as dependency (KDE desktop config)
Otherwise the gear from the right pannel does nothing
2025-06-10 20:39:46 -03:00
end-4 0ad006eea1 config loader: write back on load to include new options in user config 2025-06-11 00:40:07 +02:00
end-4 fd5553a0ad format 2025-06-11 00:36:26 +02:00
end-4 74e049b7b4 Directories: create shell config dir 2025-06-11 00:36:18 +02:00
end-4 80f809b8b2 config options: make fakescreenrounding default to 2 2025-06-11 00:36:09 +02:00
end-4 bbee1e85ac deps: add bluedevil and plasma-nm 2025-06-11 00:33:53 +02:00
end-4 bd0438be83 bg clock: fix positioning on scaled screens 2025-06-10 13:35:45 +02:00
end-4 4f8574ef50 wallpaper region limit: use min size of all instead of max 2025-06-10 13:24:58 +02:00
end-4 de941d8b9e hyprland: fix float rules for plasma stuff 2025-06-10 11:24:52 +02:00
end-4 a1e052b070 Update rules.conf 2025-06-10 09:15:48 +02:00
end-4 f7f4affe51 dock: unload when not needed 2025-06-10 09:14:54 +02:00
end-4 cf652482c5 better control -> plasma wifi widget 2025-06-10 08:59:31 +02:00
end-4 bec43ff8ed dock: fix hover to reveal behavior (#1375) 2025-06-10 08:53:00 +02:00
end-4 49888f30f0 Update README.md 2025-06-09 23:35:17 +02:00
end-4 b3a3975461 dock: fix alignment 2025-06-09 23:29:52 +02:00
end-4 93a14293aa overview: clearer window borders 2025-06-09 23:08:51 +02:00
end-4 a6ecf107b3 quickshell: fix some warnings 2025-06-09 23:04:35 +02:00
end-4 56958236e2 nicer link colors 2025-06-09 23:04:04 +02:00
end-4 2c4537bd02 Update README.md 2025-06-09 22:36:17 +02:00
end-4 cfb8a851e6 readme: screenshots 2025-06-09 22:34:04 +02:00
end-4 6fffa86fc2 dock: middle click to open new window 2025-06-09 18:08:10 +02:00
end-4 0beccd69e8 overview: adjust hover/click colors 2025-06-09 17:47:57 +02:00
end-4 5c2b12bf96 dock: join pinned apps and open windows 2025-06-09 17:43:58 +02:00
end-4 4b4364d2a5 right sidebar: more buttons 2025-06-09 17:42:04 +02:00
end-4 3c82ce828b config options: correct settings app 2025-06-09 17:41:33 +02:00
end-4 2a8725ec8d deps: remove xdg-user-dirs (#1369) 2025-06-09 16:31:04 +02:00
end-4 936ca85bab overview: fix blurry icons 2025-06-09 13:11:39 +02:00
end-4 a81acb3dbe overview: cleaner, add back hover effect 2025-06-09 12:51:28 +02:00
end-4 db8d51b931 overview: window previews!!! 2025-06-09 12:25:41 +02:00
end-4 fa2723a54d dock: remove user config option because it doesn't work
(just use enableDock in shell.qml)
2025-06-09 12:23:58 +02:00
end-4 8e1f28b11a less weird tooltip color for dark mode 2025-06-09 09:25:22 +02:00
end-4 08e46c5af8 make 0-size warnings stfu 2025-06-09 09:20:51 +02:00
Celestial.y 2020e13a05 make update.sh script (#1336) 2025-06-09 11:17:44 +08:00
end-4 2663c46b7e terminal: nice dir listing 2025-06-08 21:50:24 +02:00
end-4 d4f223c894 starship: a refresh 2025-06-08 21:39:03 +02:00
end-4 d521b2aae4 ai: latex: properly catch bracket-wrapped expressions 2025-06-08 19:02:00 +02:00
end-4 dc8bfce62e ai: fix latex rendering 2025-06-08 18:36:40 +02:00
end-4 cfb4f1a5e1 gnome control center -> plasma systemsettings 2025-06-08 17:05:20 +02:00
end-4 f840af4652 fix funny notice uhm some guys in discord said its not correct n stuff 2025-06-08 11:44:16 +02:00
end-4 726558c0a0 background widgets 2025-06-08 11:30:12 +02:00
end-4 8dab758d78 dock: hover region adjustment 2025-06-08 11:29:33 +02:00
end-4 e8c294f434 remove redundant defaulted prop assignment 2025-06-08 11:29:16 +02:00
end-4 be9b7f3629 least_busy_region.py: take files with spaces properly 2025-06-08 11:28:54 +02:00
end-4 e18456d18e material symbol: use curverendering 2025-06-08 11:27:54 +02:00
end-4 31c379cdfd dont enable dock by default 2025-06-08 11:27:38 +02:00
end-4 f084cd7a23 material symbols: prevent memory spikes 2025-06-08 08:19:15 +02:00
Bishoy Ehab 506fb857aa Add --skip-notice argument and change the way to check the git repo 2025-06-08 07:58:04 +03:00
Bishoy Ehab d96abe7a4d Add warining for users [the script is not fully tested] 2025-06-08 07:47:14 +03:00
end-4 0b7f80ed05 script for least busy region of image 2025-06-08 02:10:01 +02:00
end-4 c9ffb84ffc bar: borderless: add separators, no longer default 2025-06-07 23:25:13 +02:00
end-4 bbd2bfda5d dock: adjust active color 2025-06-07 23:02:15 +02:00
end-4 1add44ba2f dock: show on empty workspace 2025-06-07 22:37:32 +02:00
end-4 a8474af78d ai: comment debug print 2025-06-07 22:37:03 +02:00
end-4 99ab1b179b dock: pin kitty by default 2025-06-07 22:24:21 +02:00
end-4 db1fc0f6be dock: fix bottom spacing 2025-06-07 22:23:03 +02:00
end-4 0d4877a77e dock: display num of open windows 2025-06-07 21:57:57 +02:00
end-4 f5168bfcb6 QS Rewrite: dock: Show pinned apps (#1364) 2025-06-07 21:46:51 +02:00
end-4 5364d0e4f7 dock: use quickshell-native way to open apps 2025-06-07 21:45:52 +02:00
end-4 1591b72e4a installation: remove ags 2025-06-07 21:00:51 +02:00
end-4 57327ab0fe earbang protection 2025-06-07 19:43:05 +02:00
Bishoy Ehab 181ac0561d Add some space 2025-06-07 20:12:50 +03:00
Bishoy Ehab d00a21ac56 Merge branch 'end-4:main' into main 2025-06-07 20:10:39 +03:00
end-4 c1a4670de2 yad -> kdialog (closes #1367) 2025-06-07 16:51:02 +02:00
end-4 0ea31737ea fixed a typo in env.conf (#1368) 2025-06-07 16:36:25 +02:00
end-4 2c548a4296 fcitx5 blur 2025-06-07 14:58:46 +02:00
end-4 aadb38370c adjust shadows 2025-06-07 14:58:41 +02:00
sam 341c6be9be fixed a typo lol 2025-06-07 20:24:14 +08:00
end-4 643b197d02 notifications: fix spacing/eliding 2025-06-07 14:10:31 +02:00
end-4 e03800cf64 screen corners: mask layer visibility to the corners only 2025-06-07 11:29:32 +02:00
end-4 810ea2ce3b circ prog: bigger gap angle 2025-06-07 11:14:28 +02:00
end-4 b6dcd19d04 bar: workspaces: use secondary container for occupied 2025-06-07 11:12:10 +02:00
end-4 2b451c012b overview: anims when opening/closing windows 2025-06-07 08:49:41 +02:00
end-4 194b470cf2 installation: skip .local/bin 2025-06-06 23:29:29 +02:00
end-4 b70dbf5f10 hypridle: longer timeouts 2025-06-06 22:56:05 +02:00
end-4 a2f2fb816b make ripples more subtle (circle -> radial gradient) 2025-06-06 21:25:56 +02:00
end-4 31e782a36f ai chat: prevent function call message from abrupt jumps 2025-06-06 20:50:53 +02:00
end-4 eeb41de46c fix listview items being weird when changing both y and height 2025-06-06 20:50:06 +02:00
end-4 9111ada32b add m3 expressive slow spatial curve 2025-06-06 20:39:40 +02:00
end-4 56b11e9ab7 comments 2025-06-06 20:39:29 +02:00
end-4 403614d337 add app name to code save notif 2025-06-06 20:39:15 +02:00
_xB aa951b0bc0 bar: add microphone control to util buttons 2025-06-06 01:12:11 +03:00
_xB ef1170c770 dock: Show pinned apps again 2025-06-06 01:09:38 +03:00
_xB 33feaff817 notification: Fix Chromium-based notifs 2025-06-06 01:04:12 +03:00
xB 2087ea72f8 QS Rewrite: bar: Add an option for choosing screens 2025-06-06 00:47:26 +03:00
end-4 66c95231a7 readme: more quickshill 2025-06-05 20:53:43 +02:00
Celestial.y 077f52f6b8 chore: add fish shell compatible setup link (#1357) 2025-06-06 01:27:25 +08:00
end-4 2cd548ae11 hyprland: remove weird keybind i forgor 2 unset 2025-06-05 14:18:32 +02:00
end-4 bef0739471 config option for time format 2025-06-05 13:27:38 +02:00
end-4 1e24608e2b ai: add temperature 2025-06-05 13:15:02 +02:00
Hari Chalise 56bb53ed95 sep for fish shell 2025-06-05 16:32:07 +05:45
end-4 938b4b2c69 hyprland: update keybinds 2025-06-05 01:16:17 +02:00
Hari Chalise 663c3483be chore: make setup url compatible with fish shell
as fish is a non-posix-compliant shell, it doesn't support bash syntax like bash <(), so i have changed the url to one that fish shell supports.
2025-06-05 00:25:28 +05:45
end-4 135a3c2426 hyprland: add ubuntu's terminal keybind 2025-06-04 08:32:53 +02:00
end-4 9ac800ce9b hyprland: keybinds: rearrange zoom keybinds 2025-06-03 23:52:32 +02:00
Sneethe 108e0a8c78 record-script.sh fixes
Even if ~/Videos exists, `xdg-user-dir VIDEOS` requires xdg-user-dirs-update to be run first.
Some people just mkdir their desired xdg-user-dir directories. And so they won't have $HOME/.config/user-dirs.dirs for `xdg-user-dir VIDEOS` to work.
Now instead if there is no user-dirs.dirs match for VIDEOS then $HOME/Videos/ is used instead.

You can now cancel the recording region, which exits the script. Previously if you pressed escape when choosing the recording region, record-script would record the fullscreen.
This resulted in me accidentally recording my entire screen for hours.
2025-06-04 07:30:10 +10:00
end-4 3404335b21 make hyprland background always dark 2025-06-03 14:16:05 +02:00
end-4 e6b6ed60a9 translator: larger trigger delay 2025-06-03 10:22:59 +02:00
end-4 51cb27f747 search: automatically trim file protocol in commands 2025-06-03 10:22:38 +02:00
end-4 8ab8c0046b format 2025-06-03 10:22:16 +02:00
end-4 f86b85b3de fix font inconsistencies 2025-06-03 09:53:52 +02:00
end-4 b5ac985b7d Change sound muting behavior (#1342) 2025-06-03 09:17:30 +02:00
end-4 ee56903530 startup wallpaper animation 2025-06-03 00:25:41 +02:00
end-4 81446091d3 sidebar: translation widget 2025-06-02 23:24:10 +02:00
end-4 c26685b1de update sidebar 2025-06-02 23:23:58 +02:00
end-4 0fba075f52 ai: fix more null error 2025-06-02 18:39:57 +02:00
end-4 2c113018d2 ai: gemini: fix message marked done too early 2025-06-02 18:34:44 +02:00
end-4 9ddf4d2b2f ai message: fix null errors 2025-06-02 18:33:35 +02:00
end-4 fdadca431f add back that pragma, still necessary, oops 2025-06-02 18:33:23 +02:00
end-4 098098ab2d grimblast -> hyprshot
grimblast does nasty shit and crashes quickshell
2025-06-02 18:15:56 +02:00
end-4 7c98b37e4f quickshell: remove no longer necessary pragma 2025-06-02 18:15:14 +02:00
end-4 18990c5de7 primary tab bar: adaptive layout 2025-06-02 17:51:22 +02:00
end-4 bf22194182 ai: gemini: configurator 2025-06-02 14:48:10 +02:00
end-4 35bd46faea fix sidebar radius 2025-06-02 14:47:18 +02:00
Bishoy Ehab 90ea701797 Replace /bin/bash with /usr/bin/env bash shebang 2025-06-02 15:23:39 +03:00
end-4 6aadba9a3a fuzzel: don't overwrite non-color config in color generation 2025-06-02 10:52:20 +02:00
end-4 d4ad68f8c6 Allow fuzzel.ini to be customized (#1344) 2025-06-02 10:45:34 +02:00
Sneethe 1af166ef7c Don't use cache for fuzzel.theme 2025-06-02 18:23:32 +10:00
end-4 209cfc131a nuke ags config 2025-06-02 08:31:37 +02:00
end-4 2b66c6fa89 Merge branch 'main' into ii-qs 2025-06-02 08:29:27 +02:00
Sneethe 7593938986 Allow fuzzel.ini to be customized
Instead of overwriting the entire fuzzel.ini on each theme change. Theme
changes are made to fuzzel.theme which is then imported by fuzzel.ini

Rationale:
I like to use vim binds for fuzzel and there wasn't a good way to modify
fuzzel.ini without making the end-4 update process complicated.
2025-06-02 13:41:40 +10:00
end-4 7d749f16c5 Update fuzzel-emoji.sh 2025-06-02 00:10:02 +02:00
end-4 c940b72776 quickshell emoji picker 2025-06-02 00:09:47 +02:00
end-4 751e5ca543 relocate scripts 2025-06-01 23:45:51 +02:00
Bishoy Ehab e2e6604d16 Merge branch 'end-4:main' into main 2025-06-01 23:39:32 +03:00
end-4 31d06277e1 hyprlock: add background blur 2025-06-01 22:32:24 +02:00
end-4 1380696977 kitty: add search 2025-06-01 21:33:20 +02:00
end-4 7e5610a9e1 fix: correct ags package name in uninstall.sh (#1343) 2025-06-01 21:12:58 +02:00
D7OM e5b920550b fix: correct ags package name in uninstall.sh 2025-06-01 22:07:28 +03:00
end-4 368c7c3cea Update README.md 2025-06-01 20:34:29 +02:00
end-4 ea8f06b632 Update README.md 2025-06-01 20:29:28 +02:00
end-4 e08230cf69 readme: more emphasis on new quickshell version and less on reporting issues with ags version 2025-06-01 20:28:50 +02:00
end-4 1099258d07 left sidebar: add detach/attach instructions + keybind 2025-06-01 18:14:02 +02:00
end-4 e024f896a6 left sidebar: fix width anim 2025-06-01 17:53:28 +02:00
end-4 aaf652b17c detachable sidebar 2025-06-01 17:47:32 +02:00
end-4 a6a3a144d2 remove debug print (AGAIN) 2025-06-01 17:47:00 +02:00
end-4 5e8f912aa9 update plasma browser integration size 2025-06-01 16:23:40 +02:00
end-4 2b0d4b2c32 installation: remove gradience 2025-06-01 16:21:25 +02:00
end-4 c9563ffb63 quickshell: task manager: gnome-usage -> plasma system monitor 2025-06-01 15:26:48 +02:00
end-4 7f13abf771 update snowman-style battery nag
https://discord.com/channels/961691461554950145/961693710968557598/1378504799141756991
2025-06-01 13:24:10 +02:00
end-4 3f274e65ac boorus: add t.alcy.cc 2025-06-01 12:31:07 +02:00
end-4 0d7769c884 make network indicator work with ethernet 2025-06-01 11:21:28 +02:00
end-4 57a2580a5d adjust notif status btn size 2025-06-01 10:16:14 +02:00
end-4 771ff14462 notifications: add silent button 2025-06-01 10:12:37 +02:00
end-4 834a684d6f remove persistent state for bottom sidebar group tabs (buggy) 2025-06-01 10:10:57 +02:00
end-4 b172020f5b workspace: adjust active indicator anim curve 2025-06-01 09:51:45 +02:00
end-4 5ad78a77a1 workspaces: adjust icon opacity 2025-06-01 09:19:55 +02:00
end-4 1dfde18b7d kitty: add cursor trail 2025-06-01 09:15:54 +02:00
end-4 1136804c32 remove redundant wallpaper command in matugen config 2025-06-01 09:15:17 +02:00
asalde_le1 623fd80a54 Add a keybind for the microphone toggle button 2025-06-01 06:51:57 +03:00
asalde_le1 277162f4d4 Enable sound unmuting and show the muted sound icon 2025-06-01 06:46:54 +03:00
end-4 3a6e607383 bar: workspaces: active ws trail 2025-06-01 00:35:50 +02:00
end-4 b759580466 overview: show ws number, animated active indicator 2025-05-31 23:52:48 +02:00
end-4 23e5df38a3 switch from foot to kitty terminal 2025-05-31 23:15:32 +02:00
end-4 2046b5c58a make light/dark switching window not show up directly 2025-05-31 22:39:52 +02:00
end-4 c334da9907 hyprland: make osk slide from bottom 2025-05-31 22:39:03 +02:00
end-4 18802fef96 hyprland: add osk keybind 2025-05-31 22:38:41 +02:00
end-4 31e139da29 hyprland: adjust anims 2025-05-31 22:38:32 +02:00
end-4 189a1aa0ac on screen kb: init 2025-05-31 22:34:29 +02:00
end-4 f98be82f96 kb key: more flexible size 2025-05-31 22:34:10 +02:00
end-4 be29519f58 group button & ripple button: fix non-left btn release, add more actions 2025-05-31 22:33:39 +02:00
end-4 3448adb776 booru: add app name to download notif 2025-05-31 22:33:01 +02:00
end-4 8b9dc8cde8 app icon guess: add regex for polkit popup 2025-05-31 22:32:40 +02:00
end-4 e85a899be0 battery: fix charging warning when low -> plug -> unplug 2025-05-31 22:32:18 +02:00
end-4 6be83d0050 bar: util buttons: replace color picker with virtual kb 2025-05-31 22:31:44 +02:00
end-4 5fe64bfdeb make fcitx5 follow qt theme 2025-05-31 16:34:46 +02:00
end-4 9af8fc137f icons: breeze -> breeze-plus 2025-05-31 16:26:08 +02:00
end-4 a0b69f2884 first run experience 2025-05-31 12:09:02 +02:00
end-4 e5161a1f4f battery: remove unnecessary imports 2025-05-31 12:08:14 +02:00
end-4 92947e3360 easy transparency for yoinkers 2025-05-31 01:39:06 +02:00
end-4 42abc57b65 warn on low battery 2025-05-31 01:38:34 +02:00
end-4 a3d6f9f07d installation: update setuptools 2025-05-30 23:17:15 +02:00
end-4 db9754c43e remove agsv1 pkg from install script 2025-05-30 22:58:21 +02:00
end-4 5a38388c62 fix install script trying to install non-exsistent packages 2025-05-30 22:48:12 +02:00
end-4 138fc54392 dock: fix hover area accuracy, less braindead styling 2025-05-30 22:43:02 +02:00
end-4 47a34dc76b bar: add bottom position 2025-05-30 22:41:50 +02:00
end-4 e119d6d582 Update README.md 2025-05-30 17:55:45 +02:00
end-4 3089681246 keybinds: add Windows close 2025-05-30 17:55:38 +02:00
end-4 4079948b98 fix emoji picker 2025-05-30 17:55:20 +02:00
end-4 cfba132074 make installation clearer since it's not yet merged 2025-05-30 17:51:40 +02:00
end-4 1a2632909d delete unnecessary copy of kde material you color config 2025-05-30 17:41:09 +02:00
end-4 cd86de26de dependencies: add glib2 2025-05-30 17:33:24 +02:00
end-4 e8aa344976 nuke ags dependencies 2025-05-30 17:28:18 +02:00
end-4 c136422197 update dependencies 2025-05-30 17:23:09 +02:00
end-4 9322ae2e5c polkit: use kde's 2025-05-30 17:01:03 +02:00
Bishoy Ehab f61da8e09a change to pull no matter any branch 2025-05-30 17:59:50 +03:00
Bishoy Ehab b1a0e3c258 Update update.sh script to copy with -p option (preserve mode) 2025-05-30 17:58:55 +03:00
end-4 3a3fcc482f icon guess: update regexes 2025-05-30 16:55:54 +02:00
end-4 aef313a8b9 overview: fix shadow cutoff 2025-05-30 13:40:22 +02:00
end-4 47e26fd62f dock: fix warnings 2025-05-30 12:22:03 +02:00
end-4 b870f6b930 search: fix slow list move 2025-05-30 12:21:56 +02:00
end-4 18e23618ea dock: previews: morphing anims 2025-05-30 11:46:20 +02:00
end-4 3cd8865a50 dock: previews 2025-05-30 11:27:57 +02:00
end-4 198bcc6a3a readme: update dolphin mimetype fix 2025-05-30 09:32:29 +02:00
end-4 cbe086d835 refractor shadows 2025-05-30 09:32:17 +02:00
end-4 7966a8dadf use better control for bluetooth 2025-05-30 08:38:37 +02:00
end-4 fc75ae4b63 disable dock 2025-05-30 08:32:52 +02:00
end-4 782926de0f Update SearchItem.qml 2025-05-30 08:32:41 +02:00
end-4 46fdd3306c clipboard images: don't stretch 2025-05-30 08:32:16 +02:00
end-4 05d134dd9d workspaces: hide app icon when transparent 2025-05-30 08:32:01 +02:00
end-4 38a026e1dd Update SysTrayItem.qml 2025-05-30 08:31:38 +02:00
end-4 c36ca265a5 guess icons also by desktop entry search 2025-05-30 00:37:21 +02:00
end-4 440438ef33 volume mixer: guess icon also by node name 2025-05-30 00:36:53 +02:00
end-4 9cea880569 keybinds: switch to qt apps 2025-05-30 00:12:54 +02:00
end-4 3cf64401ef overview: indicate xwayland with italics and tooltip instead of icon 2025-05-29 23:51:38 +02:00
end-4 363e3327ba app search: adjust substitutions 2025-05-29 23:50:51 +02:00
end-4 8ecf9a2597 improve icon guessing 2025-05-29 23:27:46 +02:00
end-4 f942fb086a Update kdeglobals 2025-05-29 22:45:47 +02:00
end-4 694a54e331 qt apps: use breeze for colored folder icons 2025-05-29 22:44:49 +02:00
end-4 2a90777d26 add kde-material-you-colors config 2025-05-29 22:38:23 +02:00
end-4 5b6db69dd6 media controls: use quickshell's color quantizer 2025-05-29 22:24:39 +02:00
end-4 96282c4390 fix weird bold font in some places 2025-05-29 22:13:18 +02:00
end-4 9cbbaff170 add kdeglobals 2025-05-29 22:12:35 +02:00
end-4 8fdb2490c6 color generation: fix qt apps not getting correct light/dark mode 2025-05-29 21:58:02 +02:00
end-4 832f1ec571 Update README.md 2025-05-29 21:52:33 +02:00
end-4 a2eba2faf8 qt apps: use kde-material-you-colors 2025-05-29 21:29:21 +02:00
end-4 3758bdb338 hyprland: rename bezier curves 2025-05-29 13:24:11 +02:00
end-4 e35f1ae3fd hyprland: make shadow more visible 2025-05-29 13:23:47 +02:00
end-4 0d3dfe4b57 clipboard copied checkmark: only show for clipboard entries 2025-05-29 12:21:28 +02:00
end-4 4b0ee5b8ab clipboard history: remove unnecessary refreshes 2025-05-29 11:44:52 +02:00
end-4 89203e8794 cliphist service: delay a bit before grabbing entries from cliphist 2025-05-29 11:41:58 +02:00
end-4 a8533235c1 clipboard search: do not search by entry id 2025-05-29 11:38:12 +02:00
end-4 5938e6f632 search item: reorder: checkmark goes first 2025-05-29 11:26:21 +02:00
end-4 72fa76fde6 clipboard history: checkmark for selected entry 2025-05-29 11:20:08 +02:00
end-4 0ff0efe39c cliphist: refresh on clipboard change 2025-05-29 11:19:45 +02:00
end-4 c58c3d2174 dock: apps 2025-05-29 09:22:31 +02:00
end-4 2553c3ba1d shell.qml: add comment 2025-05-29 09:22:26 +02:00
end-4 5070b51e48 clipboard: decode images to /tmp 2025-05-29 09:22:12 +02:00
end-4 9503ca2129 cliphist image: cleanup decoded img on destruction 2025-05-29 09:21:56 +02:00
Bishoy Ehab 2f0a0b88e2 make update.sh script 2025-05-29 02:20:38 +03:00
end-4 d00ffdd0f1 readme: remove unnecessary pkgs 2025-05-28 19:46:38 +02:00
end-4 ba2b7fa1f9 shell.qml: make it slightly more accessible for yoinkers 2025-05-28 11:35:51 +02:00
end-4 a5abe19854 dock: pin button, launcher button 2025-05-28 11:35:19 +02:00
end-4 f1cee49494 ai: remove openai (addresses #1335) 2025-05-28 08:55:08 +02:00
end-4 442ddc1a7b clipboard history: images 2025-05-28 00:09:38 +02:00
end-4 f04d5f6202 overview: fix kb focus on hl 0.49, mask visible region 2025-05-27 22:49:40 +02:00
end-4 66c75342d4 move common dirs to Directories <--renamed-- XdgDirectories 2025-05-27 22:49:03 +02:00
end-4 5ea497068c Revert "use better-control instead of gnome settings and blueberry"
This reverts commit e1ee645e87.
2025-05-27 22:28:28 +02:00
end-4 e9485f0b8a Revert "keybinds: replace gnome settings with better control"
This reverts commit 24276cdf93.
2025-05-27 22:25:50 +02:00
end-4 adce55865e Revert "use bettercontrol for settings app (#1278)"
This reverts commit cfe48fb0a1.
2025-05-27 22:24:48 +02:00
end-4 02712868f9 search: fix item clipping 2025-05-27 20:35:57 +02:00
end-4 fb2c9ac7df favicon for links in clipboard entries 2025-05-27 20:33:56 +02:00
end-4 1a79012c61 ai search source: pass displaytext to favicon 2025-05-27 20:33:36 +02:00
end-4 37f1cd2992 ai: add gemini flash 2.5 (preview) 2025-05-27 20:10:00 +02:00
end-4 7bd910bb44 refractor favicon 2025-05-27 20:09:46 +02:00
end-4 5402893c16 overview: always show again 2025-05-27 19:34:22 +02:00
end-4 d4e8ca51a4 search: change anchor declaration 2025-05-27 11:23:50 +02:00
end-4 a759ec4e1c newline 2025-05-27 11:22:19 +02:00
end-4 4e93bd0307 notif add link click 2025-05-27 11:22:06 +02:00
end-4 8ede97a278 replace multieffect shadows with rectangularshadow ones 2025-05-27 09:40:26 +02:00
end-4 4ea6474cb6 make search result text smaller 2025-05-27 09:16:11 +02:00
end-4 a76a9bed3b adjust notif action button position 2025-05-27 09:16:01 +02:00
end-4 b78d489dfd update soramane's dotfiles license 2025-05-27 09:02:54 +02:00
end-4 54224557f0 generalize the : thing in llm apis 2025-05-27 09:02:44 +02:00
end-4 6d036e972d search: change highlighting to underline 2025-05-27 09:02:19 +02:00
end-4 d12ada5222 fixed gpt (openrouter) service logic (#1329) 2025-05-27 08:43:20 +02:00
end-4 80203c17c1 search: disable expand anim for clipboard showup 2025-05-27 00:00:00 +02:00
end-4 536fb27941 search: highlight results 2025-05-26 23:31:31 +02:00
end-4 02a3434e58 search: add levelshtein distance based search 2025-05-26 22:52:25 +02:00
Et3rnos c6ff825aa5 fixed gpt (openrouter) service logic 2025-05-26 21:42:11 +01:00
end-4 a6556f3890 overview: dont close when not searching clipboard and trying to search clipboard 2025-05-26 20:07:28 +02:00
end-4 0b80403a4b space 2025-05-26 20:06:22 +02:00
end-4 a29f12549a remove unused import 2025-05-26 20:03:10 +02:00
end-4 60625da067 format 2025-05-26 20:03:05 +02:00
end-4 cf4f7cdd28 string utils: add escape html 2025-05-26 20:02:58 +02:00
end-4 e9e6539cd0 Update keybinds.conf 2025-05-26 20:02:46 +02:00
end-4 262f278bb4 quickshell clipboard 2025-05-26 20:02:43 +02:00
end-4 24b369882a calendar: make day of week not interactable 2025-05-26 12:42:25 +02:00
end-4 7ab8012e0e notif clear button: ripple -> bouncy 2025-05-26 12:28:47 +02:00
end-4 a582cc57ac sidebar: quick toggles: make long buttons less round 2025-05-26 12:25:04 +02:00
end-4 58f23d3b47 sidebar: quick toggles: make right clickable ones bigger 2025-05-26 12:23:42 +02:00
end-4 bca1a77ae3 more hacking friendliness 2025-05-26 12:10:03 +02:00
end-4 5434771d77 media controls: adjust playpause button radius 2025-05-26 11:56:14 +02:00
end-4 21e705443e notification item: don't show unnecessary border when it's the only one in the group 2025-05-26 11:55:59 +02:00
end-4 a2ab9d2877 more hacking friendly widgets 2025-05-26 11:40:13 +02:00
end-4 6c1b27bac9 player control: playpause button change radius according to state 2025-05-26 11:39:52 +02:00
end-4 ce1418cfdb refractor radiobutton in volume mixer to new file 2025-05-26 11:39:37 +02:00
end-4 9b8eac6b54 audio device selector more bouncy 2025-05-26 11:38:50 +02:00
end-4 ede03f61bf provide basic descriptions for services 2025-05-26 10:46:07 +02:00
end-4 f765fdf531 ai: fix invalid message when switching model 2025-05-26 10:45:59 +02:00
end-4 ce94bd1b6a media controls: filter redundant players 2025-05-26 10:17:16 +02:00
end-4 ea41ee4241 notifications: timeout, prevent some warnings when dismissing notif 2025-05-26 09:37:57 +02:00
end-4 ce9993071c notifications: middle click to dismiss 2025-05-26 00:09:09 +02:00
end-4 a6e3f20dc8 make layer1 color blend more with bg than layer2 2025-05-25 23:58:36 +02:00
end-4 20a62d1fdc notif items: make dragging area cover also the icon 2025-05-25 23:55:16 +02:00
end-4 20e517a7ca notif groups: dont show invisible items 2025-05-25 23:41:51 +02:00
end-4 dbe2a922e3 notif: prevent unexpected shuffle on dismiss 2025-05-25 23:36:18 +02:00
end-4 db67398c97 remove redundant null check on music.js (#1320) 2025-05-25 22:52:55 +02:00
end-4 a24825f676 latex renderer: ensure readability after changing light/dark 2025-05-25 22:48:08 +02:00
end-4 837a2a06fa notifications: groups 2025-05-25 22:47:31 +02:00
end-4 85d3bc4444 media controls: fix weird white corners 2025-05-25 22:17:25 +02:00
end-4 3fb84b1f7f brightness service: add credit notice 2025-05-25 22:16:39 +02:00
end-4 e030fb1282 drag manager: don't hog input when not interactive 2025-05-25 22:16:23 +02:00
end-4 0ea7d156a5 drag manager widget 2025-05-25 20:38:55 +02:00
end-4 7c8f9db6d9 media controls: add shadow 2025-05-25 20:38:10 +02:00
end-4 e4093622d5 styled slider: scale radius 2025-05-25 20:37:56 +02:00
end-4 8b439d8917 styled switch: use correct anim curve for colors 2025-05-25 20:37:35 +02:00
end-4 16d96ae7ee wallpaper switcher: nicer notification name 2025-05-25 20:37:12 +02:00
end-4 675c4c3a07 notification service: add groups 2025-05-25 20:36:52 +02:00
end-4 1bc23257c7 record script: nicer app name 2025-05-25 20:02:58 +02:00
Greyfeather 9cce9edf17 remove redundant null check on music.js 2025-05-25 02:13:33 -06:00
end-4 aad4584aa7 media controls: make cover art more consistent 2025-05-25 09:17:28 +02:00
end-4 5afc4bc41e hypridle: allow suspending when steam is running (fixes #1319) 2025-05-25 07:46:27 +02:00
end-4 530339c494 idle: suspend even when steam is open 2025-05-25 07:45:39 +02:00
end-4 440d9c6907 ai: code blocks: add save to file button 2025-05-24 23:18:22 +02:00
end-4 7de5f54da2 slider: not scale handle margins twice 2025-05-24 22:46:21 +02:00
end-4 929d3836fd adjust slider design 2025-05-24 22:42:12 +02:00
end-4 b80294181c booru: add curl flags for img download 2025-05-24 22:04:32 +02:00
end-4 82713ed19a ai message: add null checks 2025-05-24 22:04:16 +02:00
end-4 bd60ea451f media controls: make cover art download more reliable 2025-05-24 22:04:03 +02:00
end-4 113024ba83 bouncy audio device selector buttons 2025-05-24 21:03:25 +02:00
end-4 a88119c3c0 ai messages: bouncy action buttons 2025-05-24 21:00:13 +02:00
end-4 ca2c6ee470 group button: cleaner default size 2025-05-24 20:59:53 +02:00
end-4 e6cc014634 remove old comment 2025-05-24 20:59:22 +02:00
end-4 9d425cd737 change small animations to use expressiveEffects curve 2025-05-24 20:59:10 +02:00
end-4 43eb4739f8 flow -> flowbuttongroup 2025-05-24 20:58:50 +02:00
end-4 ed8bcd8823 stop+start -> restart 2025-05-24 20:58:24 +02:00
end-4 5b8023740d button group: default to 0 padding 2025-05-24 20:58:04 +02:00
end-4 e0c6d92608 clean workspaces a bit 2025-05-24 20:57:48 +02:00
end-4 2641c79d65 left sidebar: bouncy command buttons 2025-05-24 19:00:18 +02:00
end-4 76abad2487 group button: modify parent's clickindex on its own 2025-05-24 18:46:16 +02:00
end-4 ba8df6e7fe adjust button bounce duration 2025-05-24 18:45:13 +02:00
end-4 b11050a231 refractor sidebar toggles group 2025-05-24 18:02:14 +02:00
end-4 fce4709d63 playercontrol: remove useless id from copy paste 2025-05-24 18:01:45 +02:00
end-4 bb67c8bb1f use bouncy anims 2025-05-24 18:01:30 +02:00
end-4 7adb95fbf8 session menu: fix button radius anim, adjust colors 2025-05-24 18:01:11 +02:00
end-4 524d69e6f8 remove debug print 2025-05-24 13:11:48 +02:00
end-4 0cf12bc3be bouncy button group for toggles 2025-05-24 13:10:49 +02:00
end-4 e7e55e7f95 revert stupid triggeredonstart for resource usage 2025-05-24 13:10:35 +02:00
end-4 67be162f20 bar: don't show battery indicator on desktkop 2025-05-24 11:54:21 +02:00
end-4 c8a4da6d8b bar: add "hella shortened" form for even narrower screens 2025-05-24 11:44:07 +02:00
end-4 0e74fc78e5 bar: add shortened form for narrow screens 2025-05-24 11:15:47 +02:00
end-4 ddb434662b anims: go back to emphasized for now 2025-05-24 11:02:52 +02:00
end-4 4fb7d7a7db resources and system info: use triggeredOnStart 2025-05-24 11:02:24 +02:00
end-4 086ba7c35a notifications: add icon for installation and upscaling prompts 2025-05-24 10:52:17 +02:00
end-4 b3e339c60f fix hyprland spelling 2025-05-24 10:05:54 +02:00
end-4 cfbf18f564 Fix ddcutil to fall back to binary serial number (#1311) 2025-05-24 10:04:48 +02:00
end-4 ac8314931f booru: fix image placement, gives single images big radius
the latter adds visual interest with some variation
2025-05-24 09:51:39 +02:00
end-4 1929b6dc8e left sidebar panelWindow size: account for bounciness 2025-05-24 09:50:08 +02:00
end-4 705a797971 wallpaper switcher: don't check resolution for videos 2025-05-24 09:49:43 +02:00
end-4 a29103d639 Set swww to video thumbnail when setting video wallpaper (#1306) 2025-05-24 09:18:18 +02:00
end-4 e87f731fb5 ripple button: add pressed radius 2025-05-23 16:46:07 +02:00
end-4 9fcf041c06 logout screen: clearer focus state color 2025-05-23 16:45:39 +02:00
end-4 b82f577420 add m3 expressive anim curves 2025-05-23 16:45:01 +02:00
end-4 513ae09951 guess better control icon 2025-05-23 16:44:27 +02:00
end-4 d011abf918 rounder todo list fab 2025-05-23 16:44:01 +02:00
end-4 f7349e6346 bar: clearer sidebar active state 2025-05-23 16:43:45 +02:00
end-4 40c0d12004 Adds JSDoc Typing to some of the JavaScript Files (#1307) 2025-05-22 20:13:51 +02:00
end-4 927487c60f make buttons ripple 2025-05-22 19:01:20 +02:00
end-4 042a4d1c24 left sidebar: slightly simplify opening/closing 2025-05-22 16:29:00 +02:00
end-4 fb26e74bcb space mono -> jetbrains mono 2025-05-22 16:27:16 +02:00
end-4 711e4b47db foot: switch to jetbrains mono font 2025-05-22 16:25:59 +02:00
end-4 4130aa7d27 fix notif disappearing too fast 2025-05-22 16:09:26 +02:00
end-4 ecbb72390a fix notif popup not showing 2025-05-22 15:44:28 +02:00
end-4 3e39fc7b13 make unload actually unload... 2025-05-22 15:00:44 +02:00
end-4 f366b9aca6 right sidebar: unload only content not panelwindow 2025-05-22 14:58:37 +02:00
end-4 fa8104480b right sidebar: actually unload completely on hide 2025-05-22 14:38:33 +02:00
end-4 e2d44e9766 make notifs not popup weirdly 2025-05-22 14:33:38 +02:00
end-4 e1d62c7c5a fix typo 2025-05-22 14:33:16 +02:00
end-4 8815846fe0 notif popup: fix undefined errors 2025-05-22 14:29:08 +02:00
end-4 c96bef3d3c remove unnecessary contentheight on listview 2025-05-22 14:28:17 +02:00
end-4 6b23854918 remove debug print 2025-05-22 14:27:55 +02:00
end-4 b66f1b7e93 fix notif popup anims 2025-05-22 14:24:52 +02:00
end-4 382a75e4c6 notification: simplify destruction, fix stuck when focus lost 2025-05-22 14:05:10 +02:00
end-4 cfc8cc30b6 right sidebar: cleaner notification implementation 2025-05-22 13:35:38 +02:00
end-4 1261d5033e booru: fix next page button text alignment 2025-05-22 12:20:11 +02:00
Greyfeather 61979a4a58 resolve comments 2025-05-21 19:31:52 -06:00
Greyfeather 0cc04bd2e4 fix typo 2025-05-21 19:22:39 -06:00
end-4 8c67c425e9 overview: fix closing immediately 2025-05-22 00:55:01 +02:00
end-4 c0c5f23bbc fix left sidebar closing immediately 2025-05-22 00:52:35 +02:00
end-4 b79fc0306c add qt6ct config 2025-05-22 00:50:04 +02:00
end-4 51b285b831 add qt6ct config 2025-05-22 00:49:34 +02:00
end-4 24276cdf93 keybinds: replace gnome settings with better control 2025-05-21 22:14:02 +02:00
end-4 2571b3f532 overview: (properly) put overview grid in loader 2025-05-21 22:12:05 +02:00
end-4 d26a95253e make loaders work properly for: media controls, osds, session 2025-05-21 21:59:51 +02:00
Nakii46 e85822c811 Fix ddcutil to fall back to binary serial number
Fix ddcutil to fall back to binary serial number if no serial number is found for a display. Also it will ignore duplicate entries that can happen when a monitor is connected via DisplayPort (More info: https://www.ddcutil.com/faq/#duplicate_displayport)
2025-05-21 15:32:30 +02:00
Greyfeather c4035b75be Merge remote-tracking branch 'refs/remotes/fork/ii-qs' into ii-qs 2025-05-21 00:25:21 -06:00
Greyfeather 65b5ec93c7 merge upstream 2025-05-21 00:22:49 -06:00
Souyama 13cb540e49 Update switchwall.sh
Updated video image
2025-05-21 08:20:05 +05:30
end-4 0f8a48ed0d boorus: create homework folder 2025-05-20 23:45:34 +02:00
end-4 44b5b25c0d clipboard history: back to simple command that works 2025-05-20 23:25:58 +02:00
end-4 b65b677839 dont let clipboard paste on select (very nasty...) 2025-05-20 23:24:37 +02:00
end-4 249ee0b55f hyprland: media controls keybind 2025-05-20 23:23:56 +02:00
end-4 e1ee645e87 use better-control instead of gnome settings and blueberry 2025-05-20 23:23:39 +02:00
end-4 cfe48fb0a1 use bettercontrol for settings app (#1278) 2025-05-20 23:17:47 +02:00
end-4 2ad293221c remove debug print 2025-05-20 23:04:09 +02:00
end-4 b1b6e837ba media controls: go back to qt5 opacity mask to prevent crash 2025-05-20 23:03:34 +02:00
end-4 d0c180f8fc media controls: use multieffect instead of qt5 graphical effects 2025-05-20 13:48:19 +02:00
end-4 fcdf2dc7f6 use multieffect for shadows 2025-05-20 12:58:39 +02:00
end-4 bece489ee9 media controls: adjust colors 2025-05-20 10:58:09 +02:00
end-4 1287fbebd7 adjust media control blur radius 2025-05-20 10:51:03 +02:00
end-4 0e0bcd4617 media controls: fix rounding 2025-05-20 10:45:47 +02:00
end-4 b0ed1e75b6 media controls: use blurred cover art for bg 2025-05-20 10:43:45 +02:00
end-4 1adfc4e89f make bar util buttons cleaner 2025-05-20 10:17:12 +02:00
end-4 e57bf529cd bar: introduce borderless mode 2025-05-20 10:17:04 +02:00
end-4 9816314749 ai use message ids to point to data
i thought it would give cleaner updates...
2025-05-20 10:16:21 +02:00
end-4 0ab39c2c50 left sidebar: fix focus 2025-05-20 10:15:29 +02:00
end-4 4715b02a45 wallpaper switcher: prompt upscale 2025-05-20 08:51:30 +02:00
end-4 a32edd387e mfking chore: add qsTr() to strings for translations 2025-05-20 00:35:09 +02:00
end-4 26a5dbd91c services: null check for ConfigOptions for hackability/yoinkability 2025-05-19 23:36:17 +02:00
end-4 fbe6c8733b Add option to ignore certain apps in dock (#1303) 2025-05-19 23:29:28 +02:00
end-4 cd177a3fcd color utils: adapt to accent: use hsl 2025-05-19 23:28:12 +02:00
end-4 2475a64bdc color utils: use qt's native color funcs 2025-05-19 23:27:57 +02:00
end-4 912422bca5 player control: default to accent when there's no cover 2025-05-19 23:27:32 +02:00
end-4 2da3d80a14 sidebars: no more rememnber last used tab
works inconsistently because of uhm swipeviews
also it's weird... ai is more useful than anime grills and notifs are more useful than mixer imo...
2025-05-19 23:16:04 +02:00
end-4 14f7542a21 move color funcs to their own file instead of appearance 2025-05-19 23:13:17 +02:00
end-4 80661d4f86 wallpaper switcher: prompt video dep installation thru notif 2025-05-19 22:40:06 +02:00
end-4 715496079f allow video wallpaper 2025-05-19 22:25:39 +02:00
end-4 f1b6789b15 Fix: Prevent raw HTML rendering in notifications (#1299) 2025-05-19 21:56:19 +02:00
end-4 a65363c60f fix #1300 2025-05-19 21:48:41 +02:00
LOSEARDES77 d4603c6b8a Fix it not working 2025-05-19 15:52:47 +02:00
LOSEARDES77 a149abf9fe Add option to ignore certain apps in dock 2025-05-19 15:43:22 +02:00
end-4 7db6df769b rename global state for sidebar open tracker 2025-05-19 12:19:16 +02:00
end-4 0e2252995c Update requirements.in 2025-05-19 11:35:25 +02:00
end-4 d8dc1c7d69 remove pywal from requirements 2025-05-19 11:34:30 +02:00
end-4 086451951a remove >pywal launcher action 2025-05-19 11:34:18 +02:00
end-4 6281c3a23c no more pywal 2025-05-19 11:31:55 +02:00
end-4 d9b4de45e6 ags: no more pywal 2025-05-19 11:25:49 +02:00
end-4 d0c5b92fb9 media controls: adjust layout 2025-05-19 11:03:52 +02:00
end-4 e6344a704d music title cleaning: only clean brackets at start 2025-05-19 09:38:06 +02:00
end-4 671d2463b8 ai: add null check for gemini annotations 2025-05-19 09:37:47 +02:00
end-4 2b393708b7 bar: util buttons: use filled icons, fix alignment 2025-05-19 09:01:15 +02:00
end-4 e33b4fad58 dont open media controls when empty 2025-05-19 09:00:21 +02:00
end-4 8b725202b3 remove debug print 2025-05-19 09:00:08 +02:00
end-4 29fb9a5268 no more hacky focus grab thanks to hyprland's dfb841c303263208c2f8ac7a55fbdf4668594fb7 2025-05-19 08:45:40 +02:00
end-4 a0ed714199 media controls: next/prev track button 2025-05-19 08:44:32 +02:00
end-4 a287b4524b use filled icons on bar 2025-05-19 08:43:55 +02:00
Greyfeather 08b9014ee2 add JSDoc to notification_utils 2025-05-19 00:21:38 -06:00
Greyfeather 23b6199684 add JSDoc to icons.js 2025-05-18 23:59:27 -06:00
Greyfeather c5b5cf4d2c add JSDoc to string_utils 2025-05-18 18:35:38 -06:00
end-4 c9f1a80dc2 adjust media control colors 2025-05-19 00:09:08 +02:00
end-4 5479d66a66 don't use qs' default reload popup 2025-05-18 23:01:28 +02:00
end-4 73deae7ece media controls: multi instance, colorize 2025-05-18 23:01:15 +02:00
end-4 d365ede358 don't prompt plasma browser integration installation 2025-05-18 21:24:20 +02:00
end-4 7428da2552 dont filter native mpris from firefox & chrome 2025-05-18 21:22:48 +02:00
end-4 314a6c67b6 feat: media controls 2025-05-18 18:54:28 +02:00
end-4 931b276d60 tweak osd size 2025-05-18 18:53:25 +02:00
end-4 1ce47424a6 right sidebar: remove unecessary visibility hook 2025-05-18 18:52:21 +02:00
end-4 69cd0fc447 no more % on indicators 2025-05-18 18:52:04 +02:00
end-4 68b233f4ef keybinds: "user"/"custom" -> "extra" 2025-05-18 11:08:36 +02:00
end-4 611f819373 refractor elementMoveEnter anims 2025-05-18 02:00:47 +02:00
end-4 b14df306ce refractor some animations 2025-05-18 01:50:12 +02:00
end-4 9385961fb8 make osdvalueindicator more customizable (internally) 2025-05-18 00:50:25 +02:00
end-4 b9fe3da1e3 brightness osd: fix no onBrightnessChanged signal warning 2025-05-18 00:48:34 +02:00
end-4 5af7ede329 session menu: only show on focused monitor 2025-05-18 00:37:08 +02:00
end-4 4626ab2bb2 fix cant assign undefined warning 2025-05-18 00:31:38 +02:00
end-4 853622e05e brightness osd: fix screen change connection target 2025-05-18 00:27:14 +02:00
end-4 27ca14d208 volume osd: only show on focused screen 2025-05-18 00:26:42 +02:00
end-4 4fa53bb4fc osd anim: slide -> popin 2025-05-18 00:25:24 +02:00
end-4 e0b883cc3e brightness osd: show only on focused screen 2025-05-18 00:20:33 +02:00
end-4 4df645a025 notif popup: show only on focused screen 2025-05-17 23:57:32 +02:00
end-4 f76da801fe fix notif dismiss on right sidebar open 2025-05-17 23:57:12 +02:00
end-4 8533310f29 left sidebar: put in loader 2025-05-17 23:45:53 +02:00
end-4 2b98b8dada remove unused var 2025-05-17 23:45:38 +02:00
end-4 01cb51d6b4 left sidebar: pinning, single instance 2025-05-17 23:42:16 +02:00
end-4 e66606170b qs: set basic as base qtquick controls style
fixes stuff for fox
2025-05-17 23:41:36 +02:00
end-4 889cff1888 cheatsheet: dont create multiple for each monitor 2025-05-17 23:41:04 +02:00
end-4 e7e08cda59 right sidebar: dont create multiple for each monitor 2025-05-17 23:19:41 +02:00
end-4 c8bbdbc472 tab buttons: fix pointing hand cursor 2025-05-17 23:04:00 +02:00
end-4 8d91007a89 readme: remove some unnecessary deps 2025-05-17 23:03:41 +02:00
end-4 e8d899d4d0 adjust osd padding 2025-05-17 22:54:09 +02:00
end-4 f5137ada13 give secondary tab button ripple 2025-05-17 22:47:54 +02:00
end-4 edec446aed space 2025-05-17 22:47:44 +02:00
end-4 50221e938b tabs: make ripple function correctly on hold 2025-05-17 22:37:37 +02:00
end-4 705a659d19 adjust layer 1 colors 2025-05-17 22:15:15 +02:00
end-4 2b778dcf6e add spacing to tab pages 2025-05-17 22:15:01 +02:00
end-4 8355ea842c make bar slide instead of pop in 2025-05-17 22:11:33 +02:00
end-4 625e2992a5 adjust ripple anim 2025-05-17 00:19:08 +02:00
end-4 7b97b4060c primary tab buttons: ripple 2025-05-17 00:12:49 +02:00
end-4 18f6f2ee9a replace background empty item with null 2025-05-16 23:52:44 +02:00
end-4 84f28f6411 tabs: nicer indicator anim 2025-05-16 23:50:20 +02:00
end-4 11087142af re enable anims for fuzzel 2025-05-16 23:14:33 +02:00
end-4 97442f3c11 clipboard history: also type directly 2025-05-16 23:14:08 +02:00
end-4 502c50f155 add wtype dep 2025-05-16 23:00:35 +02:00
end-4 aa06056fac remove unnecessary rubyshot 2025-05-16 23:00:29 +02:00
end-4 e9e7b74c1b Update fuzzel-emoji 2025-05-16 22:58:12 +02:00
Samuel Leutner 09696d9fdb Fix: Prevent raw HTML rendering in notifications
Notifications were occasionally displaying raw HTML content,
including tags, instead of the intended plain text message.

This commit introduces a regex to strip all HTML tags from
notification content before display, ensuring a proper
user experience.
2025-05-16 17:57:24 -03:00
Greyfeather a78b56c450 add jsdoc to file_utils.js 2025-05-16 14:48:29 -06:00
end-4 f15ca250c1 HyprlandKeybinds: fix children undefined 2025-05-16 22:46:31 +02:00
end-4 c695a4879c cheatsheet: put in loader 2025-05-16 22:46:11 +02:00
end-4 6dc3b7ff92 quickshell: keybinds: remove debug print 2025-05-16 22:28:30 +02:00
end-4 8b84939ec5 hyprland: adjust special ws anim duration 2025-05-16 22:28:10 +02:00
end-4 f1a980144e hyprland: update config 2025-05-16 22:24:50 +02:00
end-4 b39cbac179 hyprland: allow 3 finger ws swipe 2025-05-16 20:55:26 +02:00
end-4 e6569235a4 hyprland: disable splash rendering 2025-05-16 20:55:14 +02:00
end-4 c803b1e711 booru: prevent cursor warping when opening link 2025-05-16 19:19:31 +02:00
end-4 9cb1547136 cheatsheet: appear instantly 2025-05-16 19:19:05 +02:00
end-4 57c6e31d59 hyprland: enable focus on activate 2025-05-16 19:18:55 +02:00
end-4 54fbf89a67 cheatsheet: adjust appearance 2025-05-16 19:12:29 +02:00
end-4 fba67168d9 cheatsheet: support user keybinds 2025-05-16 19:12:09 +02:00
end-4 3cc45e37fc hyprland: make keybinds descriptions shorter, remove unnecessary stuff 2025-05-16 19:09:32 +02:00
end-4 2bdae7d96a hyprland: update keybinds 2025-05-16 18:23:48 +02:00
end-4 e5f757e1ea fix HyprlandData event update filter 2025-05-16 18:22:36 +02:00
end-4 455bcdde4d cheatsheet 2025-05-16 18:22:05 +02:00
end-4 8daa1702d0 refractor xdg dirs 2025-05-16 16:02:05 +02:00
end-4 9a68f80ffa booru: put context menu in loader, add tooltip for tags 2025-05-16 14:56:14 +02:00
end-4 3b764ca70e adjust tray item colorization again 2025-05-16 13:58:58 +02:00
end-4 15ac370409 bar: scroll hint: adjust color and anim curve 2025-05-16 13:41:48 +02:00
end-4 c00b43f99f bar: tray: adjust colorization 2025-05-16 11:46:39 +02:00
end-4 f13b8cb160 osd: fix screen 2025-05-16 11:46:24 +02:00
end-4 a2948d8967 add nicer fallback for missing icons 2025-05-16 11:34:26 +02:00
end-4 a2d48303ca bar: add scrolling hint 2025-05-16 11:26:02 +02:00
end-4 e7e6f4d0b5 brightness: make keybind and bar scroll consistent 2025-05-16 10:41:28 +02:00
end-4 6680e9adec osd: make brightness icon go speen speen 2025-05-16 08:26:23 +02:00
end-4 e85af8750a go back to material symbols rounded 2025-05-16 08:26:08 +02:00
end-4 b2c1ad628e ai service: rename currentModel and model in setModel for clarity 2025-05-15 23:10:21 +02:00
end-4 9fdf7bd6a4 quickshell: brightness service: add globalshortcut 2025-05-15 23:05:27 +02:00
end-4 b022f23d7a put overview in loader 2025-05-15 23:04:15 +02:00
end-4 9c9a615556 hyprland: reorder keybinds 2025-05-15 23:02:49 +02:00
end-4 0cd2f12f48 hyprland: add descriptions to some keybinds 2025-05-15 22:56:18 +02:00
end-4 f31c8feb13 make session screen not have awkward animation 2025-05-15 22:54:43 +02:00
end-4 7ec5c04130 brightness service: don't spill brightnessctl output into logs 2025-05-15 22:53:09 +02:00
end-4 c985273dc6 use brightness service from caelestia-dots/shell 2025-05-15 22:50:35 +02:00
end-4 2499675687 overview: search: put types of icons into loaders 2025-05-15 22:49:25 +02:00
end-4 b9e116e17f secondary tab button: icon in loader 2025-05-15 22:48:45 +02:00
end-4 0f7eed736b overview: fix a null warning 2025-05-15 22:15:02 +02:00
end-4 bddbfbcc45 bar: fix ws click switching 2025-05-15 06:35:47 +02:00
end-4 c1a8aca3fb notif popup: don't show constantly internally 2025-05-14 23:30:19 +02:00
end-4 006b6c00d9 put osds into loaders 2025-05-14 23:29:44 +02:00
end-4 13f10fc0f0 put right sidebar in loader 2025-05-14 23:08:17 +02:00
end-4 9d6b4e07da put session menu in loader 2025-05-14 22:58:13 +02:00
end-4 f6cb404ada put overview in loader 2025-05-14 22:57:03 +02:00
end-4 6c2d86a6b3 fix notif popup screen data 2025-05-14 22:21:24 +02:00
end-4 6deecbc1d4 fix notif shadow anchors warning 2025-05-14 22:20:58 +02:00
end-4 1cff3051d6 put battery charge icon into loader 2025-05-14 22:20:47 +02:00
end-4 f7c36a9700 adjust session screen alpha 2025-05-14 22:07:57 +02:00
end-4 db1e3cbab1 put notif popup in lazy loader 2025-05-14 22:07:19 +02:00
end-4 2339eda157 notifs: put different icon representations in loaders 2025-05-14 21:36:28 +02:00
end-4 c3c581fcaa more spacing on notif action buttons 2025-05-14 21:36:00 +02:00
end-4 a35fe507f2 quickshell: fix click-outside-to-close on hyprland 0.49 2025-05-14 21:17:56 +02:00
end-4 aae1efe81c fix duped launcher actions 2025-05-14 20:47:07 +02:00
end-4 d6807be932 ai: fix text input up/down arrow navigation 2025-05-14 20:09:00 +02:00
end-4 feca4c6256 Feat: switch to video background and colorgen (#1292) 2025-05-14 18:09:23 +02:00
obsidrielle def2d6f383 Style: remove unused variables and args 2025-05-14 12:01:51 +08:00
obsidrielle 8c62520666 Refactor: consistently use temporary files and mv (atomic operation) 2025-05-14 10:45:01 +08:00
obsidrielle a544f09114 Refactor: rewrite startup script without modifying config 2025-05-14 10:35:11 +08:00
end-4 6c26a90068 persistent ai model setting 2025-05-13 22:39:33 +02:00
end-4 bd80b83881 update ags config 2025-05-13 21:53:30 +02:00
end-4 18356feab7 quickshell: fix panelwindow size deprecation warnings 2025-05-13 21:53:13 +02:00
end-4 d5eee84c87 hyprland: hide special on ws change 2025-05-13 20:51:54 +02:00
obsidrielle cd9167344f Feat: switch to video background and colorgen 2025-05-13 08:39:30 +08:00
obsidrielle 1a2284234a Feat: switch to video background and colorgen 2025-05-12 22:36:16 +08:00
end-4 ee6a4c366e ags: nuke scripts already handled by quickshell 2025-05-11 16:36:31 +02:00
end-4 543243239a make quickshell's color generation handle ags 2025-05-11 16:32:32 +02:00
end-4 23af7648e4 matugen: add ags sourceview themes 2025-05-11 15:49:03 +02:00
end-4 b91dde50af fix overview toggle mouse hog 2025-05-11 12:05:08 +02:00
end-4 9ce4795266 bar: resolve some warnings 2025-05-11 11:48:38 +02:00
end-4 ce553c2c0e fix tab bar interaction with persistent states 2025-05-11 11:27:49 +02:00
end-4 6030d21e37 bar: fix messed mouse interaction hog/passthrough 2025-05-11 11:20:24 +02:00
end-4 39594baa46 bar: volume mute indicator 2025-05-11 11:06:19 +02:00
end-4 64ec9bdfe4 shorter 2025-05-11 10:29:18 +02:00
end-4 9116cf83df volume osd: handle mute 2025-05-11 10:03:03 +02:00
end-4 51686c4aa4 change progress bar anim 2025-05-11 10:01:01 +02:00
end-4 3e66c2d0f3 change race condition delay 2025-05-11 10:00:14 +02:00
end-4 7fe8838999 mic mute indicator 2025-05-11 09:59:48 +02:00
end-4 5dbf255c5f fix overview focus grab on init 2025-05-11 08:48:03 +02:00
end-4 de07c95257 hyprland: make fuzzel no anim 2025-05-11 08:14:26 +02:00
end-4 84fd898bbe make choice of booru provider and nsfw persistent 2025-05-11 08:08:41 +02:00
end-4 b827edf2ef persistent state manager: prevent writing default config before first load 2025-05-11 08:08:01 +02:00
end-4 d90067a11d make overviewToggleReleaseInterrupt description clearer 2025-05-11 08:03:55 +02:00
end-4 af5654e99f overview: only show ws highlight on focused monitor 2025-05-11 07:43:32 +02:00
end-4 6619989cf2 left sidebar: fix entry focus on open 2025-05-10 23:57:13 +02:00
end-4 18366c147f make left sidebar selected tab persistent 2025-05-10 23:51:33 +02:00
end-4 3c877197b4 make right sidebar tab persistent 2025-05-10 23:42:28 +02:00
end-4 f13912a027 make persistent states persistent 2025-05-10 23:05:32 +02:00
end-4 9d51815661 hyprland: cleanup bezier curves 2025-05-10 22:56:39 +02:00
end-4 116bea5f97 overview: handle monitor transformations 2025-05-10 22:38:09 +02:00
end-4 88bb486dc8 overview: fix monitor scaling 2025-05-10 22:06:53 +02:00
end-4 2d962ce9a8 ai: message text block dont write back when ai is writing 2025-05-10 21:24:19 +02:00
end-4 dc903de212 introduce persistent states (persistence to be added) 2025-05-10 21:23:47 +02:00
end-4 b05049dedf move toPlainObject to object_utils.js 2025-05-10 21:23:20 +02:00
end-4 8031625af7 move trimFileProtocol to file_utils.js 2025-05-10 21:22:32 +02:00
end-4 bce69c77c7 uncomment zerochan username config option 2025-05-10 21:21:29 +02:00
end-4 96ca6db76d adjust layer anim curves 2025-05-10 20:28:57 +02:00
end-4 5d16a04ea6 config options: notify on reload 2025-05-10 20:09:48 +02:00
end-4 846677caa1 config loader 2025-05-10 17:53:38 +02:00
end-4 826f54e90d ai: text block: remove unecessary key hogger 2025-05-10 17:53:21 +02:00
end-4 3876b07bc3 ai: dont keep text when command fails 2025-05-10 11:49:09 +02:00
end-4 aae8429629 very small refractor 2025-05-10 11:48:45 +02:00
end-4 6d382e467a ai: adjust search source button style 2025-05-10 11:16:01 +02:00
end-4 1b70a5eb16 booru: cleaner download 2025-05-10 11:15:34 +02:00
end-4 f93cca8a13 ai: gemini: annotation sources 2025-05-10 10:56:35 +02:00
end-4 0af7924be9 add default user agent option 2025-05-10 10:56:22 +02:00
end-4 b7e3b5d887 bar: allow hiding bg 2025-05-10 10:55:59 +02:00
end-4 b3723f7dc6 notifications: adjust animations 2025-05-10 08:53:03 +02:00
end-4 6ec3f91e0f ai: provide a default system prompt 2025-05-10 01:55:00 +02:00
end-4 6758d8daf3 ai: add api key advice 2025-05-10 01:53:43 +02:00
end-4 c0f5f55c63 ai: system prompt 2025-05-10 00:38:38 +02:00
end-4 c57772aa9d gemini: search capabilities 2025-05-10 00:24:29 +02:00
end-4 b99fe14214 rename bar's "small circle button" + prevent init color shift 2025-05-09 20:25:16 +02:00
end-4 aa07895a97 rename material theme service 2025-05-09 20:24:39 +02:00
end-4 f3d0fd5313 ai: "animate" thinking 2025-05-09 18:40:28 +02:00
end-4 de2ead426f ai: handle thinking 2025-05-09 18:23:22 +02:00
end-4 efcfd375c0 adjust animations 2025-05-09 18:23:11 +02:00
end-4 de61b46ccb remove debug print 2025-05-09 18:22:49 +02:00
end-4 bbe0641503 update hyprlock config 2025-05-09 15:49:11 +02:00
end-4 2be5e9063b hyprlock: caps lock indicator 2025-05-09 01:09:37 +02:00
end-4 2221b4d32c booru: prevent race condition in cache folder cleaning 2025-05-09 01:08:51 +02:00
end-4 b4e3221711 comment debug print 2025-05-09 01:07:55 +02:00
end-4 c13acd0152 wrap {} with () 2025-05-09 01:07:47 +02:00
end-4 c3323da840 ai chat: latex rendering 2025-05-09 01:07:31 +02:00
end-4 e56a3a591b systray: more readable monochrome icons 2025-05-09 00:58:42 +02:00
end-4 ee42d9f142 matugen: fix hyprland file path 2025-05-08 21:20:30 +02:00
end-4 3a6d0ef468 Update README.md 2025-05-08 18:04:09 +02:00
end-4 6df4806b82 ai chat: fix code block line numbers 2025-05-08 17:56:43 +02:00
end-4 c94ec8e6b2 ws num peek: don't peek if user already does smth w/ super quickly 2025-05-08 17:56:15 +02:00
end-4 8096e91e55 more ?. 2025-05-08 14:57:07 +02:00
end-4 706fd5cab8 refractor 2025-05-08 14:46:21 +02:00
end-4 4a87cf5c8b move grimblast & record script out of ags folder 2025-05-08 11:55:12 +02:00
end-4 3d6e7970ac adjust window rounding to match vscode & zen browser 2025-05-08 11:53:59 +02:00
end-4 6223320d7d ai chat: code block: i beam cursor when editing 2025-05-08 11:29:19 +02:00
end-4 0a331061c3 fix string escaping 2025-05-07 23:48:24 +02:00
end-4 47a8149968 ai chat: animated button color 2025-05-07 19:13:44 +02:00
end-4 a765a190cd ai chat: better code snippets 2025-05-07 19:13:28 +02:00
end-4 e83dfdc5d8 shorter line 2025-05-07 19:12:50 +02:00
end-4 8464f0107c code block syntax highlighting 2025-05-07 12:16:20 +02:00
end-4 f3e0f14c44 cleaner ai message buttons 2025-05-07 09:06:35 +02:00
end-4 cae673bd72 change text selection color 2025-05-07 00:08:07 +02:00
end-4 e3e70e7316 oops forgot to commit this line 2025-05-06 23:57:30 +02:00
end-4 db173152c3 ai chat: action buttons
copy, edit, toggle markdown rendering, delete
2025-05-06 23:57:17 +02:00
end-4 38efbb0d21 ai (service): add openrouter models, handle reasoning 2025-05-06 23:55:18 +02:00
end-4 ca91f528bb search: refractor 2025-05-06 23:50:56 +02:00
end-4 5f87d3a99f notif: escape when copying 2025-05-06 23:50:17 +02:00
end-4 418ac5da0c booru: better layout when expanded 2025-05-06 11:23:52 +02:00
end-4 e38a0bdac7 overview: add active border 2025-05-06 10:50:04 +02:00
end-4 009bc60c41 fix api key setting 2025-05-06 10:44:14 +02:00
end-4 24de218132 add listview add fade anim 2025-05-06 10:43:23 +02:00
end-4 e5779ff05c update markdown test message 2025-05-06 10:43:03 +02:00
end-4 46067c6811 ai: detect ollama models 2025-05-06 00:55:30 +02:00
end-4 8ff520e7ec ai chat: smaller name 2025-05-05 23:57:19 +02:00
end-4 98647d11f3 make tag buttons feel faster 2025-05-05 23:47:58 +02:00
end-4 8d93f44509 ai chat: make it work with online models 2025-05-05 23:47:34 +02:00
end-4 e3cf6b37e8 replace xdg-open with Qt.openUrlExternally 2025-05-05 17:02:14 +02:00
end-4 afa2697e4e revert stupid anim curve 2025-05-05 16:39:46 +02:00
end-4 1d39710d3f remove fill for search result icons 2025-05-05 15:32:01 +02:00
end-4 db0f077c3b booru: prevent GOAWAY on sidebar resize 2025-05-05 15:31:49 +02:00
end-4 a6098a007a remove unused var 2025-05-05 15:31:27 +02:00
end-4 ddf6181271 ai chat: make messages copyable 2025-05-05 13:29:59 +02:00
end-4 9a1e0633a1 nicer fallback icon for volume mixer 2025-05-05 13:29:47 +02:00
end-4 7469d8264f sidebar resizing 2025-05-05 12:23:35 +02:00
end-4 0ae52eafdc nicer text 2025-05-05 11:52:57 +02:00
end-4 cba6471099 nicer icon fill 2025-05-05 11:47:22 +02:00
end-4 aa7df0a74c fix console warnings for osds 2025-05-05 11:34:01 +02:00
end-4 5506f6eae9 volume mixer: smaller icons 2025-05-05 11:29:23 +02:00
end-4 4285dce730 nicer(?) calendar collapse fade
or at least more correct idk
2025-05-05 11:29:14 +02:00
end-4 6e34831183 ai chat: show message nicely, command suggestions 2025-05-05 11:06:52 +02:00
end-4 352d389cc4 material symbols: support filling 2025-05-05 11:05:58 +02:00
end-4 94ef226b92 ai chat 2025-05-05 01:13:41 +02:00
end-4 e02875890b booru: allow provider description to be translated 2025-05-05 01:10:46 +02:00
end-4 84ae535756 booru: add domain name to go to source button 2025-05-04 20:44:37 +02:00
end-4 1fe568150f booru: make immediate response nicer 2025-05-04 00:45:20 +02:00
end-4 41e82f0693 booru: instant feedback on enter 2025-05-04 00:11:36 +02:00
end-4 dc0a15e63b booru: small refractor 2025-05-04 00:05:04 +02:00
end-4 3404eacf4b remove extra space 2025-05-03 21:40:13 +02:00
end-4 ceac2931ab fancier tooltips 2025-05-03 21:31:43 +02:00
end-4 bc8b01a6f6 booru: show provider and command description 2025-05-03 21:31:31 +02:00
end-4 a2722478ba booru: add api provider suggestions 2025-05-03 18:43:07 +02:00
end-4 3284e41545 animations: new curve 2025-05-03 18:12:06 +02:00
end-4 4a44d78389 launcher: fuzzy search 2025-05-03 15:49:01 +02:00
end-4 1beb723cf3 booru: tag suggestions 2025-05-01 19:57:10 +02:00
end-4 730488f3c5 booru: minor spacing adjustment 2025-05-01 16:34:24 +02:00
end-4 059e5c6761 booru: filter empty tags 2025-05-01 07:50:03 +02:00
end-4 bcfb4e169e add missing clipping for scrollable content 2025-05-01 07:49:40 +02:00
end-4 1aa721dac8 overview make window focus work more 2025-04-30 23:12:19 +02:00
end-4 f0c1f0adff brightness: use exponential adjustment 2025-04-30 22:21:10 +02:00
end-4 7d71d9d507 add substitution for zen browser 2025-04-30 22:20:19 +02:00
end-4 17935cdc13 adjust ws icon size 2025-04-30 22:19:57 +02:00
end-4 34268147e6 set namespace for bar 2025-04-30 22:19:50 +02:00
end-4 1e5079cd61 booru: next button/command 2025-04-30 11:18:06 +02:00
end-4 fef0cc366a booru: fix 1image row width, add actions menu 2025-04-30 00:43:10 +02:00
end-4 d08d0a8914 "booru": waifu.im support 2025-04-29 23:38:29 +02:00
end-4 f2b523545b booru: proper danbooru support, fix gelbooru 2025-04-29 22:26:45 +02:00
end-4 f72e480e91 make the icon named more accurately
they cant copyright a fucking 4 point star right????????
2025-04-29 21:00:03 +02:00
end-4 f7a73edaea relocate api indicator 2025-04-29 13:28:43 +02:00
end-4 54514522d4 booru: add api provider indicator 2025-04-29 13:18:27 +02:00
end-4 f21f670d21 remove debug print 2025-04-29 11:17:35 +02:00
end-4 891da6c522 booru: style changes, tag button dont add space at beginning 2025-04-29 11:10:53 +02:00
end-4 5543efac7a booru: more sexy 2025-04-29 10:44:44 +02:00
end-4 b605cf33dd move anime stuff in their own folder 2025-04-29 07:21:15 +02:00
end-4 5de8414b64 booru image click to open sourcee 2025-04-28 23:59:49 +02:00
end-4 f24cd8fa35 booru: page number 2025-04-28 23:58:10 +02:00
end-4 1f5ea7b983 booru: images, clear, provider setting 2025-04-28 23:24:11 +02:00
end-4 160a55d859 booru: api caller service 2025-04-28 10:20:27 +02:00
end-4 c0eff65377 fix overview focus 2025-04-28 00:07:51 +02:00
end-4 c596cd21f6 tooltips: add delay 2025-04-27 23:56:33 +02:00
end-4 36e3171391 separator lines for tabbar 2025-04-27 23:49:15 +02:00
end-4 cc69a4bac4 bar: more intuitive buttons, topleft icon 2025-04-27 23:48:30 +02:00
end-4 ab9b17a188 use more hyprland dispatch exec instead of a process for simple stuff 2025-04-27 23:22:27 +02:00
end-4 9b0d769598 use hyprland global keybind dispatch for window toggling 2025-04-27 23:06:22 +02:00
end-4 4548000077 fix indentation 2025-04-27 20:55:41 +02:00
end-4 ad9452e656 left sidebar: add keybinds 2025-04-27 20:35:28 +02:00
end-4 a34d65f342 session: remove unnecessary focus 2025-04-27 20:35:11 +02:00
end-4 7f9dc76698 bar: cleaner width 2025-04-27 20:35:01 +02:00
end-4 f2a9641a95 left sidebar foundations 2025-04-27 18:58:06 +02:00
end-4 0ef575b082 use dbus keybind for releasing super for overview
AAAAAAAAAAAAAAAA LETS FUCKING GO FINALLY A GOOD LOOKING LAUNCHER THAT POPS UP INSTANTLY
2025-04-27 18:32:40 +02:00
end-4 3b8595748c workspace app icons: nicer transition 2025-04-27 00:13:27 +02:00
end-4 5e8f4048da show biggest app icon on workspaces, faster keybinds 2025-04-26 23:50:46 +02:00
end-4 f52ba7ad2b remove debug print 2025-04-26 21:32:27 +02:00
end-4 af4ecc55ce overview: drag and drop to move windows 2025-04-26 21:24:08 +02:00
end-4 6f6b3876fb Update config.fish 2025-04-26 15:28:11 +02:00
end-4 ffb7872a79 hyprland keybinds: move away from scripts in ags folder 2025-04-26 14:57:09 +02:00
end-4 6ab4c3e786 Update README.md 2025-04-26 14:43:24 +02:00
end-4 bbd472f478 terminal colors: cache -> state dir 2025-04-26 14:42:50 +02:00
end-4 dc53953766 venv: ags -> quickshell 2025-04-26 14:25:52 +02:00
end-4 35e4626fbc update hyprland config 2025-04-26 14:18:52 +02:00
end-4 a9c40bc86d color generation 2025-04-26 14:17:13 +02:00
end-4 5e9a6bf965 Update README.md 2025-04-26 09:22:28 +02:00
end-4 98547ba837 search: fix space confirming choice 2025-04-25 22:10:16 +02:00
end-4 e691fdcc59 search: run command 2025-04-25 22:01:19 +02:00
end-4 63c844cdeb overview: search 2025-04-25 20:35:37 +02:00
end-4 e1359116b8 better support for workspace 10000 2025-04-25 18:02:40 +02:00
end-4 e34a2494dd Update README.md 2025-04-25 16:07:50 +02:00
end-4 3c10a074da Update README.md 2025-04-24 23:17:26 +02:00
end-4 ebb831d345 app search qol: enter first item, entry always respond to char keys 2025-04-24 23:02:05 +02:00
end-4 72ccce04c6 overview: app search 2025-04-24 22:36:47 +02:00
end-4 8dd82baf26 use qsTr (for translations later) 2025-04-24 20:28:22 +02:00
end-4 84f031573e overview: middle click to close 2025-04-24 20:26:58 +02:00
end-4 49b3107adb typo 2025-04-24 19:56:12 +02:00
end-4 700b126a9e overview: no cursor warp for click-to-focus, add ws focus 2025-04-24 10:01:26 +02:00
end-4 e612abad23 make xwayland indicator configurable 2025-04-24 09:44:32 +02:00
end-4 6513ee82da overview: xwayland indicator 2025-04-24 09:37:08 +02:00
end-4 3c38bb3a72 bar: right click right side for next track 2025-04-24 09:36:58 +02:00
end-4 042c8dd461 overview windows: interaction 2025-04-23 22:16:18 +02:00
end-4 41ffd0ac80 overview 2025-04-23 20:40:29 +02:00
end-4 806230ff52 notif popup dismiss animation fix 2025-04-22 08:10:54 +02:00
end-4 13f68dacfb update hyprland layer rules 2025-04-22 08:04:21 +02:00
end-4 8e9f8bf173 use dolphin; update session keybind 2025-04-22 08:04:12 +02:00
end-4 2459bf2464 fix weird notif width
stupid copilot bug
2025-04-21 23:40:20 +02:00
end-4 54fdf043c9 notification popups 2025-04-21 23:29:31 +02:00
end-4 5dc0dc133d safer property access + style adjustments 2025-04-21 21:31:33 +02:00
end-4 99b9de9d5c session menu 2025-04-21 21:14:01 +02:00
end-4 dfc0a53a5f update hyprland layer rule for osd 2025-04-21 18:17:49 +02:00
end-4 0728557b04 osd: separate, make keybinds prefer qs over ags 2025-04-21 18:15:01 +02:00
end-4 0faf9287ba osd 2025-04-21 17:51:28 +02:00
end-4 9678751156 circular progress more like m3 2025-04-21 15:29:21 +02:00
end-4 073e35381c fancier radiobuttons 2025-04-21 11:05:18 +02:00
end-4 eca98598cf mixer: add audio device selector 2025-04-21 00:47:34 +02:00
end-4 9164ad2471 swap usage: don't show when zero and there's music 2025-04-20 22:15:10 +02:00
end-4 f9a8138264 notification: make dragging not lag 2025-04-20 22:14:34 +02:00
end-4 9c6aff249f volume mixer list placeholder 2025-04-20 18:37:14 +02:00
end-4 5b84100c52 refractor 2025-04-20 18:28:28 +02:00
end-4 19ba832938 volume mixer 2025-04-20 17:53:17 +02:00
end-4 e66c942790 notifications: copy button 2025-04-20 17:53:11 +02:00
end-4 ab334c7a94 Update keybinds.conf 2025-04-20 12:32:50 +02:00
end-4 138854dcbc clipping rounding for scrollables 2025-04-20 12:32:04 +02:00
end-4 bc6d963800 notifications: handle body images 2025-04-20 12:14:44 +02:00
end-4 9d7262382f notifications remove gap between time and arrow 2025-04-20 10:53:48 +02:00
end-4 74fe9f44dd notifications: drag right to dismiss 2025-04-20 10:52:14 +02:00
end-4 11ff4bbfaf MORE ANIMATION FIX AAAAAA 2025-04-20 09:46:13 +02:00
end-4 b5a9e01455 notifications: avoid id collisions across sessions 2025-04-20 08:44:06 +02:00
end-4 3096107d6b notif animations 2025-04-20 00:48:43 +02:00
end-4 905d26570f fix animations 2025-04-19 23:57:50 +02:00
end-4 b879489d43 pointing hand interaction 2025-04-19 23:47:30 +02:00
end-4 9a82d40ddc notifications: better destroy animation 2025-04-19 23:46:47 +02:00
end-4 6ae0e5f84d update layer rules 2025-04-19 23:13:15 +02:00
end-4 d44a1dce8d keybinds: update notif test 2025-04-19 23:12:59 +02:00
end-4 6d2469fe4c notifications: handle images 2025-04-19 23:11:10 +02:00
end-4 17289cef29 notif actions 2025-04-19 22:37:14 +02:00
end-4 3677873a05 notif actions 2025-04-19 21:38:33 +02:00
end-4 3b2628fbd7 notifications properly working 2025-04-19 20:07:44 +02:00
end-4 63e29d18fb fix notif time 2025-04-19 00:25:39 +02:00
end-4 6b457c7780 notification list 2025-04-19 00:09:51 +02:00
end-4 02151a93f6 fancier tabs 2025-04-18 12:43:39 +02:00
end-4 d8d812cf47 sidebarright bottom widget group collapse 2025-04-18 10:38:52 +02:00
end-4 bef66ac40a fix ugly dialog text field 2025-04-18 09:27:58 +02:00
end-4 75bf5028fd sync 2025-04-17 23:01:48 +02:00
end-4 2d540c16bc cursor shape for network and bluetooth buttons 2025-04-17 22:17:58 +02:00
end-4 8bf8c200d7 sidebar todo dialog add fade anim 2025-04-17 22:15:27 +02:00
end-4 7f779476cc Update rules.conf 2025-04-17 21:54:12 +02:00
end-4 f798b912a6 make cursor shape pointing hand on button hover 2025-04-17 16:39:23 +02:00
end-4 873cb24642 fix calendar scroll 2025-04-17 16:28:13 +02:00
end-4 1d9b543f57 todo widget: add ability to add items 2025-04-17 16:27:03 +02:00
end-4 1bb4bf8372 todo list proper anims 2025-04-17 12:41:52 +02:00
end-4 4db72d941e todo list 2025-04-17 12:31:51 +02:00
end-4 d6914a4ea2 sidebar todo 2025-04-17 01:32:35 +02:00
end-4 c62b9f8d4b new folder for services, fancy calendar month button 2025-04-16 21:48:47 +02:00
end-4 586c349f1f sidebar calendar done 2025-04-16 20:18:22 +02:00
end-4 f5d47335e8 sidebar calendar some anims 2025-04-16 10:44:15 +02:00
end-4 f7c7313087 sidebar: static calendar 2025-04-16 10:41:08 +02:00
end-4 199bc99fb5 sidebar navigation item anims 2025-04-16 00:01:14 +02:00
end-4 7c217dc25c sidebar calendar thingie: navrail 2025-04-15 22:46:18 +02:00
end-4 62ef2fc421 bluetooth and wifi 2025-04-15 20:10:52 +02:00
end-4 ff8cee9dde cleaner import; sidebar quick toggles 2025-04-15 08:58:08 +02:00
end-4 c273669003 sidebar progress 2025-04-14 23:35:40 +02:00
end-4 ab81e79eec sidebar esc to close 2025-04-14 12:59:52 +02:00
end-4 ab04d1e10d add reload popup 2025-04-14 12:19:02 +02:00
end-4 9f0deefec4 per-monitor handling of sidebar opening 2025-04-14 12:18:33 +02:00
end-4 a139c29a2b toggleable sidebar 2025-04-13 17:07:32 +02:00
end-4 248ff831ab make screen corner configurable 2025-04-13 16:42:55 +02:00
end-4 28bd79234d rounding decorations 2025-04-13 16:37:30 +02:00
end-4 7b8582124d fix stupid tooltip corner 2025-04-13 02:27:58 +02:00
end-4 08a2cb7234 Merge branch 'ii-qs' of https://github.com/end-4/dots-hyprland into ii-qs 2025-04-12 16:05:20 +02:00
end-4 eff8d1e4c3 no more pragma needed 2025-04-12 15:40:40 +02:00
end-4 8a18c395fe qt stuff qs <- main (#1223) 2025-04-12 15:38:08 +02:00
end-4 dae2857391 system tray 2025-04-11 23:35:05 +02:00
end-4 d77e4f14bf bar brightness scroll 2025-04-11 20:43:18 +02:00
end-4 06fc4baf4e active window title + workspace fix 2025-04-11 17:10:19 +02:00
end-4 c29041aa9e bar: resources/music: dynamic show/hide 2025-04-11 16:03:54 +02:00
end-4 d9ed5434ac bar: media indicator 2025-04-11 14:54:22 +02:00
end-4 3bb67a9a4f bar: workspaces: better occupied state 2025-04-11 01:39:31 +02:00
end-4 742ec413f3 bar resource usage indicator 2025-04-11 01:16:55 +02:00
end-4 ad63ae699f battery 2025-04-11 00:05:34 +02:00
end-4 ff93725b28 the perfect workspace indicator 2025-04-10 17:03:57 +02:00
end-4 5c88c6a5a6 button color anims 2025-04-10 13:09:49 +02:00
end-4 15990bf8d1 utilbuttons 2025-04-10 12:55:26 +02:00
end-4 91cef5700a clock 2025-04-10 02:06:15 +02:00
end-4 179be02e0d Update README.md 2025-04-10 00:19:17 +02:00
end-4 2e466abf71 empty bar 2025-04-10 00:16:42 +02:00
923 changed files with 62298 additions and 26222 deletions
@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
version="1.1"
id="svg9"
sodipodi:docname="oxygen.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs9" />
<sodipodi:namedview
id="namedview9"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="7.6782609"
inkscape:cx="-11.916761"
inkscape:cy="11.786523"
inkscape:window-width="1627"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg9" />
<g
id="g9"
transform="translate(0.7158741,-0.307456)">
<path
d="m 12.821126,8.892686 c 0,2.99523 -2.42813,5.42337 -5.4233602,5.42337 -2.99523,0 -5.42334,-2.42814 -5.42334,-5.42337 0,-2.99523 2.42811,-5.42334 5.42334,-5.42334 2.9952302,0 5.4233602,2.42811 5.4233602,5.42334 z"
fill="white"
id="path7"
style="fill:#000000" />
<path
d="m 16.593826,4.412536 c 0,1.04182 -0.8445,1.88638 -1.8863,1.88638 -1.0419,0 -1.8864,-0.84456 -1.8864,-1.88638 0,-1.041819 0.8445,-1.88638 1.8864,-1.88638 1.0418,0 1.8863,0.844561 1.8863,1.88638 z"
fill="white"
id="path8"
style="fill:#000000" />
<path
d="m 16.593826,15.495056 c 0,1.4325 -1.1612,2.5937 -2.5937,2.5937 -1.4325,0 -2.5938,-1.1612 -2.5938,-2.5937 0,-1.4325 1.1613,-2.5938 2.5938,-2.5938 1.4325,0 2.5937,1.1613 2.5937,2.5938 z"
fill="white"
id="path9"
style="fill:#000000" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

@@ -1,339 +0,0 @@
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
-81
View File
@@ -1,81 +0,0 @@
"use strict";
// Import
import Gdk from 'gi://Gdk';
import GLib from 'gi://GLib';
import App from 'resource:///com/github/Aylur/ags/app.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
// Stuff
import userOptions from './modules/.configuration/user_options.js';
import { firstRunWelcome, startBatteryWarningService } from './services/messages.js';
import { startAutoDarkModeService } from './services/darkmode.js';
// Widgets
import { Bar, BarCornerTopleft, BarCornerTopright } from './modules/bar/main.js';
import Cheatsheet from './modules/cheatsheet/main.js';
// import DesktopBackground from './modules/desktopbackground/main.js';
import Dock from './modules/dock/main.js';
import Corner from './modules/screencorners/main.js';
import Crosshair from './modules/crosshair/main.js';
import Indicator from './modules/indicators/main.js';
import Osk from './modules/onscreenkeyboard/main.js';
import Overview from './modules/overview/main.js';
import Session from './modules/session/main.js';
import SideLeft from './modules/sideleft/main.js';
import SideRight from './modules/sideright/main.js';
import { COMPILED_STYLE_DIR } from './init.js';
const range = (length, start = 1) => Array.from({ length }, (_, i) => i + start);
function forMonitors(widget) {
const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
return range(n, 0).map(widget).flat(1);
}
function forMonitorsAsync(widget) {
const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
return range(n, 0).forEach((n) => widget(n).catch(print))
}
// Start stuff
handleStyles(true);
startAutoDarkModeService().catch(print);
firstRunWelcome().catch(print);
startBatteryWarningService().catch(print)
const Windows = () => [
// forMonitors(DesktopBackground),
forMonitors(Crosshair),
Overview(),
forMonitors(Indicator),
forMonitors(Cheatsheet),
SideLeft(),
SideRight(),
forMonitors(Osk),
forMonitors(Session),
...(userOptions.dock.enabled ? [forMonitors(Dock)] : []),
...(userOptions.appearance.fakeScreenRounding !== 0 ? [
forMonitors((id) => Corner(id, 'top left', true)),
forMonitors((id) => Corner(id, 'top right', true)),
forMonitors((id) => Corner(id, 'bottom left', true)),
forMonitors((id) => Corner(id, 'bottom right', true)),
] : []),
...(userOptions.appearance.barRoundCorners ? [
forMonitors(BarCornerTopleft),
forMonitors(BarCornerTopright),
] : []),
];
const CLOSE_ANIM_TIME = 210; // Longer than actual anim time to make sure widgets animate fully
const closeWindowDelays = {}; // For animations
for (let i = 0; i < (Gdk.Display.get_default()?.get_n_monitors() || 1); i++) {
closeWindowDelays[`osk${i}`] = CLOSE_ANIM_TIME;
}
App.config({
css: `${COMPILED_STYLE_DIR}/style.css`,
stackTraceOnError: true,
closeWindowDelay: closeWindowDelays,
windows: Windows().flat(1),
});
// Stuff that don't need to be toggled. And they're async so ugh...
forMonitorsAsync(Bar);
// Bar().catch(print); // Use this to debug the bar. Single monitor only.
-24
View File
@@ -1,24 +0,0 @@
// Want only the overview from my config? this is what you're looking for!
// Remember to install: `dart-sass`, `ags`, `material-symbols`, and `xorg-xrandr`
// To launch this, run the following
// ags -c ~/.config/ags/config_overviewOnly.js
// To toggle the overview, run:
// ags -t overview
// You might wanna add that as a keybind (in hyprland.conf)
// bind = Super, Tab, exec, ags -t overview
// Import
import App from 'resource:///com/github/Aylur/ags/app.js'
// Widgets
import Overview from './modules/overview/main.js';
import { COMPILED_STYLE_DIR } from './init.js';
handleStyles(true);
App.config({
css: `${COMPILED_STYLE_DIR}/style.css`,
stackTraceOnError: true,
windows: [
Overview(),
],
});
-55
View File
@@ -1,55 +0,0 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
import configOptions from "../modules/.configuration/user_options.js";
const { langCode, Extra_logs } = configOptions.i18n
const translations = {};
let currentLanguage = langCode || getLanguageCode();
function getLanguageCode() {
let langEnv = GLib.getenv('LANG') || GLib.getenv('LANGUAGE') || 'Default.';
let langCode = langEnv.split('.')[0];
return langCode;
}
// Load language file
function loadLanguage(lang) {
if (!translations[lang]) {
try {
let filePath = `~/.config/ags/i18n/locales/${lang}.json`;
filePath = filePath.replace(/^~/, GLib.get_home_dir());
let file = Gio.File.new_for_path(filePath);
let [success, contents] = file.load_contents(null);
if (success) {
let decoder = new TextDecoder('utf-8');
let jsonString = decoder.decode(contents);
translations[lang] = JSON.parse(jsonString);
}
} catch (error) {
if (Extra_logs || lang === "Default")
console.warn(`Failed to load language file, language code: ${lang}:\n`, error);
return;
}
}
currentLanguage = currentLanguage || lang;
}
// Initialize default language
function init() {
try {
loadLanguage(currentLanguage);
if (Extra_logs)
console.log(getString("Initialization complete!") || "Initialization complete!");
loadLanguage("Default");
} catch (error) {
console.error('Failed to initialize default language:', error);
}
}
// Get translation, if no corresponding value, return the key
function getString(key) {
if (key && !translations[currentLanguage]?.[key] && Extra_logs)
console.warn(`${translations[currentLanguage]["Not found"] || "Not found"}:::${key}`);
return translations[currentLanguage]?.[key] || translations['Default']?.[key] || key;
}
export { getString, init };
-250
View File
@@ -1,250 +0,0 @@
{
"No media": "No media",
"Powered by Google": "Powered by Google",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.",
"Precise": "Precise",
"Balanced": "Balanced",
"Creative": "Creative",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1",
"Enhancements": "Enhancements",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points",
"Safety": "Safety",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "When turned off, tells the API (not the model) \nto not block harmful/explicit content",
"History": "History",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Saves chat history\nMessages in previous chats won't show automatically, but they are there",
"Key stored in:": "Key stored in:",
"To update this key, type": "To update this key, type",
"Updated API Key at": "Updated API Key at",
"Currently using": "Currently using",
"Select ChatGPT-compatible API provider": "Select ChatGPT-compatible API provider",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.",
"Official Ollama API.\nPricing: Free.": "Official Ollama API.\nPricing: Free.",
"A unified interface for LLMs": "A unified interface for LLMs",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key",
"Provider shown above": "Provider shown above",
"Chat with models compatible with OpenAI's Chat Completions API.\nNot affiliated, endorsed, or sponsored by any of the providers.": "Chat with models compatible with OpenAI's Chat Completions API.\nNot affiliated, endorsed, or sponsored by any of the providers.",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "An API key is required\nYou can grab one <u>here</u>, then enter it below",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points",
"Powered by waifu.im + other APIs": "Powered by waifu.im + other APIs",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.",
"Tags →": "Tags →",
"Invalid command.": "Invalid command.",
"Anime booru": "Anime booru",
"Powered by yande.re and konachan": "Powered by yande.re and konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.",
"Lewds": "Lewds",
"Shows naughty stuff when enabled": "Shows naughty stuff when enabled",
"Saves images in folders by their tags": "Saves images in folders by their tags",
"Message Gemini...": "Message Gemini...",
"Enter Google AI API Key...": "Enter Google AI API Key...",
"Message the model...": "Message the model...",
"Enter API Key...": "Enter API Key...",
"Enter tags": "Enter tags",
"Enter tags and/or page number": "Enter tags and/or page number",
"No tag in mind? Type a page number": "No tag in mind? Type a page number",
"Quick scripts": "Quick scripts",
"Change screen resolution": "Change screen resolution",
"Update packages": "Update packages",
"Trim system generations to 5": "Trim system generations to 5",
"Trim home manager generations to 5": "Trim home manager generations to 5",
"Remove orphan packages": "Remove orphan packages",
"Uninstall unused flatpak packages": "Uninstall unused flatpak packages",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Inaccurate</span> Color picker",
"Result": "Result",
"Type to search": "Type to search",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "RAM Usage",
"Swap Usage": "Swap Usage",
"CPU Usage": "CPU Usage",
"Uptime:": "Uptime:",
"Screen snip": "Screen snip",
"Color picker": "Color picker",
"Toggle on-screen keyboard": "Toggle on-screen keyboard",
"Night Light": "Night Light",
"Color inversion": "Color inversion",
"Keep system awake": "Keep system awake",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "Session",
"Bluetooth | Right-click to configure": "Bluetooth | Right-click to configure",
"Wifi | Right-click to configure": "Wifi | Right-click to configure",
"Right-click to configure": "Right-click to configure",
"Unknown": "Unknown",
"Reload Environment config": "Reload Environment config",
"Open Settings": "Open Settings",
"Notifications": "Notifications",
"Audio controls": "Audio controls",
"Bluetooth": "Bluetooth",
"Wifi networks": "Wifi networks",
"Quick config": "Quick config",
"Silence": "Silence",
"Clear": "Clear",
"No notifications": "No notifications",
"notifications": "notifications",
"Close": "Close",
"Now": "Now",
"Yesterday": "Yesterday",
"No audio source": "No audio source",
"Remove device": "Remove device",
"Connected": "Connected",
"Paired": "Paired",
"More": "More",
"Selected": "Selected",
"Connecting to": "Connecting to",
"Current network": "Current network",
"Authentication": "Authentication",
"Authentication failed": "Authentication failed",
"Enter network password": "Enter network password",
"Properties": "Properties",
"Forget": "Forget",
"Effects": "Effects",
"Transparency": "Transparency",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this",
"Blur": "Blur",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.",
"X-ray": "X-ray",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ",
"Size": "Size",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread",
"Passes": "Passes",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.",
"Animations": "Animations",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nEnable animations",
"Choreography delay": "Choreography delay",
"In milliseconds, the delay between animations of a series": "In milliseconds, the delay between animations of a series",
"Developer": "Developer",
"Show FPS": "Show FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nShow FPS overlay on top-left corner",
"Log to stdout": "Log to stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console",
"Damage tracking": "Damage tracking",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work",
"Damage blink": "Damage blink",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes",
"Not all changes are saved": "Not all changes are saved",
"Mo": "Mo",
"Tu": "Tu",
"We": "We",
"Th": "Th",
"Fr": "Fr",
"Sa": "Sa",
"Su": "Su",
"Calendar": "Calendar",
"To Do": "To Do",
"Unfinished": "Unfinished",
"Done": "Done",
"Finished tasks will go here": "Finished tasks will go here",
"Nothing here!": "Nothing here!",
"+ New task": "+ New task",
"Add a task...": "Add a task...",
"Collapse calendar": "Collapse calendar",
"Expand calendar": "Expand calendar",
"To do tasks": "To do tasks",
"Color scheme": "Color scheme",
"Options": "Options",
"Dark Mode": "Dark Mode",
"Ya should go to sleep!": "Ya should go to sleep!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)",
"Scheme styles": "Scheme styles",
"Vibrant": "Vibrant",
"Vibrant+": "Vibrant+",
"Expressive": "Expressive",
"Monochrome": "Monochrome",
"Rainbow": "Rainbow",
"Fidelity": "Fidelity",
"Fruit Salad": "Fruit Salad",
"Tonal Spot": "Tonal Spot",
"Content": "Content",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Use arrow keys to navigate.\nEnter to select, Esc to cancel.",
"Lock": "Lock",
"Logout": "Logout",
"Sleep": "Sleep",
"Hibernate": "Hibernate",
"Shutdown": "Shutdown",
"Reboot": "Reboot",
"Cancel": "Cancel",
"Cheat sheet": "Cheat sheet",
"Keybinds": "Keybinds",
"Periodic table": "Periodic table",
"Essentials for beginners": "Essentials for beginners",
"Make shell elements transparent": "Make shell elements transparent",
"Actions": "Actions",
"Window management": "Window management",
"Window arrangement": "Window arrangement",
"Workspace management": "Workspace management",
"Workspace navigation": "Workspace navigation",
"Widgets": "Widgets",
"Media": "Media",
"Apps": "Apps",
"Neutral": "Neutral",
"Launch foot (terminal)": "Launch foot (terminal)",
"Open app launcher": "Open app launcher",
"Change wallpaper": "Change wallpaper",
"Clipboard history >> clipboard": "Clipboard history >> clipboard",
"Pick emoji >> clipboard": "Pick emoji >> clipboard",
"Screen snip >> edit": "Screen snip >> edit",
"Screen snip to text >> clipboard": "Screen snip to text >> clipboard",
"Pick color (Hex) >> clipboard": "Pick color (Hex) >> clipboard",
"Screenshot >> clipboard": "Screenshot >> clipboard",
"Screenshot >> clipboard & file": "Screenshot >> clipboard & file",
"Record region (no sound)": "Record region (no sound)",
"Record screen (with sound)": "Record screen (with sound)",
"Suspend system": "Suspend system",
"Move focus in direction": "Move focus in direction",
"Move window": "Move window",
"Resize window": "Resize window",
"Close window": "Close window",
"Pick and kill a window": "Pick and kill a window",
"Window: move in direction": "Window: move in direction",
"Window: split ratio +/- 0.1": "Window: split ratio +/- 0.1",
"Float/unfloat window": "Float/unfloat window",
"Toggle fake fullscreen": "Toggle fake fullscreen",
"Toggle fullscreen": "Toggle fullscreen",
"Toggle maximization": "Toggle maximization",
"Focus workspace # (1, 2, 3, 4, ...)": "Focus workspace # (1, 2, 3, 4, ...)",
"Workspace: focus left/right": "Workspace: focus left/right",
"Workspace: toggle special": "Workspace: toggle special",
"Window: move to workspace # (1, 2, 3, 4, ...)": "Window: move to workspace # (1, 2, 3, 4, ...)",
"Window: move to workspace left/right": "Window: move to workspace left/right",
"Window: move to workspace special": "Window: move to workspace special",
"Window: pin (show on all workspaces)": "Window: pin (show on all workspaces)",
"Restart widgets": "Restart widgets",
"Cycle bar mode (normal, focus)": "Cycle bar mode (normal, focus)",
"Toggle overview/launcher": "Toggle overview/launcher",
"Show cheatsheet": "Show cheatsheet",
"Toggle left sidebar": "Toggle left sidebar",
"Toggle right sidebar": "Toggle right sidebar",
"Toggle music controls": "Toggle music controls",
"View color scheme and options": "View color scheme and options",
"Toggle power menu": "Toggle power menu",
"Toggle crosshair": "Toggle crosshair",
"Next track": "Next track",
"Previous track": "Previous track",
"Play/pause media": "Play/pause media",
"Launch Zed (editor)": "Launch Zed (editor)",
"Launch VSCode (editor)": "Launch VSCode (editor)",
"Launch Nautilus (file manager)": "Launch Nautilus (file manager)",
"Launch Firefox (browser)": "Launch Firefox (browser)",
"Launch GNOME Text Editor": "Launch GNOME Text Editor",
"Launch WPS Office": "Launch WPS Office",
"Launch GNOME Settings": "Launch GNOME Settings",
"Launch pavucontrol (volume mixer)": "Launch pavucontrol (volume mixer)",
"Launch EasyEffects (equalizer & other audio effects)": "Launch EasyEffects (equalizer & other audio effects)",
"Launch GNOME System monitor": "Launch GNOME System monitor",
"Toggle fallback launcher: anyrun": "Toggle fallback launcher: anyrun",
"Toggle fallback launcher: fuzzel": "Toggle fallback launcher: fuzzel",
"Initialization complete!": "Initialization complete!",
"Not found": "Not found:",
"Calling API": "Calling API",
"Downloading image": "Downloading image",
"Finished!": "Finished!",
"Error": "Error",
"Not found!": "Not found!",
"Go to file url": "Go to file url",
"Save image": "Save image",
"Hoard": "Hoard",
"Open externally": "Open externally",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!",
"Feels like": "Feels like"
}
-238
View File
@@ -1,238 +0,0 @@
{
"No media": "بدون رسانه",
"Powered by Google": "قدرت گرفته از گوگل",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "بدون وابستگی تأیید شده یا حمایت شده توسط گوگل.\n\nحریم خصوصی: پیام‌های گفتگو به حساب شما مرتبط نیستند،\nاما توسط بازبینی‌کنندگان انسانی برای بهبود مدل خوانده خواهند شد.",
"Precise": "دقیق",
"Balanced": "متعادل",
"Creative": "خلاق",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "مقدار دما در Gemini.\n دقیق = 0\n متعادل = 0.5\n خلاق = 1",
"Enhancements": "بهبودها",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "به Gemini می‌گوید:\n- این یک دستیار نوار کناری لینوکس است\n- مختصر باشید و از فهرست کردن کمک بگیرید",
"Safety": "ایمنی",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "زمانی که خاموش باشد، به API (نه مدل) می‌گوید که \nمحتوای مضر/صریح را مسدود نکند",
"History": "پیشینه",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "پیشینه گفتگو را نگه‌داری می‌کند\nپیام‌های گفتگو‌های پیشین به‌طور خودکار نمایش داده نمی‌شوند، اما وجود دارند",
"Key stored in:": "کلید نگه‌داری شده در:",
"To update this key, type": "برای به‌روزرسانی این کلید، بنویسید",
"Updated API Key at": "کلید API به‌روزرسانی شده در",
"Currently using": "هم‌اینک بکار گرفته میشود",
"Select ChatGPT-compatible API provider": "انتخاب ارائه‌دهنده API سازگار با ChatGPT",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "API رسمی OpenAI.\nقیمت‌گذاری: رایگان برای اولین 5 دلار یا 3 ماه، هر کدام که کمتر باشد.",
"Official Ollama API.\nPricing: Free.": "API رسمی Ollama.\nقیمت‌گذاری: رایگان.",
"A unified interface for LLMs": "یک رابط یکپارچه برای LLMها",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "API از Tornado Softwares\nقیمت‌گذاری: رایگان: 100 در روز\nنیاز به پیوستن به دیسکورد آنها برای دریافت کلید دارد",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "API از @zukixa در گیت‌هاب.\nتوجه: کلیدها قفل IP هستند بنابراین گاهی اوقات باگ دارند\nقیمت‌گذاری: رایگان: 10 در دقیقه، 800 در روز.\nنیاز به پیوستن به دیسکورد آنها برای دریافت کلید دارد",
"Provider shown above": "ارائه‌دهنده در بالا نشان داده شده است",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "مقدار دما در مدل.\n دقیق = 0\n متعادل = 0.5\n خلاق = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "یک کلید API مورد نیاز است\nشما می‌توانید یکی را <u>اینجا</u> بگیرید، سپس آن را پایین وارد کنید",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "به مدل می‌گوید:\n- این یک دستیار نوار کناری لینوکس است\n- گزافه‌گو نباشید و نقاط فهرست بکار ببرید",
"Powered by waifu.im + other APIs": "قدرت گرفته از waifu.im + سایر APIها",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "برچسب‌ها را برای یک تصویر تصادفی بنویسید.\nمحتوای NSFW بازگردانده نخواهد شد مگر اینکه\nشما به‌طور صریح چنین برچسبی را درخواست کنید.\n\nتوجه: بدون وابستگی ارائه‌دهندگان\nو مسئول هیچ‌یک از محتوای آنها نیست.",
"Tags →": "برچسب‌ها →",
"Invalid command.": "دستور نامعتبر.",
"Anime booru": "انیمه بورو",
"Powered by yande.re and konachan": "قدرت گرفته از yande.re و konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "یک تصویر بورو. ممکن است محتوای NSFW داشته باشد.\nمواظب باشید.\n\nتوجه: بدون وابستگی به ارائه‌دهنده\nو مسئول هیچ‌یک از محتوای آن نیست.",
"Lewds": "محتوای نامناسب",
"Shows naughty stuff when enabled": "محتوای نامناسب را زمانی که فعال باشد نشان می‌دهد",
"Saves images in folders by their tags": "تصاویر را در پوشه‌ها بر اساس برچسب‌هایشان نگه‌داری می‌کند",
"Message Gemini...": "پیام به Gemini...",
"Enter Google AI API Key...": "کلید API گوگل AI را وارد کنید...",
"Message the model...": "پیام به مدل...",
"Enter API Key...": "کلید API را وارد کنید...",
"Enter tags": "برچسب‌ها را وارد کنید",
"Quick scripts": "اسکریپت‌های سریع",
"Change screen resolution": "تغییر وضوح صفحه",
"Update packages": "به‌روزرسانی بسته‌ها",
"Trim system generations to 5": "تعداد نسل‌های سامانه را به 5 کاهش دهید",
"Trim home manager generations to 5": "تعداد نسل‌های مدیر خانه را به 5 کاهش دهید",
"Remove orphan packages": "بسته‌های ناکارآمد را پاک کنید",
"Uninstall unused flatpak packages": "بسته‌های فلت‌پک بکار گرفته نشده را پاک کنید",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">نادرست</span> انتخاب‌گر رنگ",
"Result": "نتیجه",
"Type to search": "برای جستجو بنویسید",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "کارکرد RAM",
"Swap Usage": "کارکرد Swap",
"CPU Usage": "کارکرد CPU",
"Uptime:": "در حال کار:",
"Screen snip": "برش صفحه",
"Color picker": "انتخاب‌گر رنگ",
"Toggle on-screen keyboard": "کیبورد روی صفحه را فعال/غیرفعال کنید",
"Night Light": "نور شب",
"Color inversion": "وارونگی رنگ",
"Keep system awake": "سامانه را بیدار نگه‌دارید",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "نشست",
"Bluetooth | Right-click to configure": "بلوتوث | برای پیکربندی راست کلیک کنید ",
"Wifi | Right-click to configure": "وای‌فای | برای پیکربندی راست کلیک کنید ",
"Right-click to configure": "برای پیکربندی راست کلیک کنید",
"Unknown": "ناشناخته",
"Reload Environment config": "پیکربندی محیط را دوباره بارگذاری کنید",
"Open Settings": "تنظیمات را باز کنید",
"Notifications": "آگاه‌سازها",
"Audio controls": "کنترل‌های صدا",
"Bluetooth": "بلوتوث",
"Wifi networks": "شبکه‌های وای‌فای",
"Quick config": "پیکربندی زنده",
"Silence": "سکوت",
"Clear": "پاک کردن",
"No notifications": "بدون آگاه‌ساز",
"notifications": "آگاه‌سازها",
"Close": "بستن",
"Now": "اینک",
"Yesterday": "دیروز",
"No audio source": "هیچ منبع صوتی",
"Remove device": "پاک‌کردن دستگاه",
"Connected": "متصل",
"Paired": "جفت شده",
"More": "بیشتر",
"Selected": "انتخاب شده",
"Current network": "شبکه کنونی",
"Authentication": "احراز هویت",
"Effects": "جلوه‌ها",
"Transparency": "شفافیت",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nعناصر شل را شفاف کنید\nهمچنین اگر این را فعال کنید، تاری نیز توصیه می‌شود",
"Blur": "تاری",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nفعال کردن تاری بر روی عناصر شفاف\nبر عملکرد/مصرف برق تأثیر نمی‌گذارد مگر اینکه پنجره‌های شفاف داشته باشید.",
"X-ray": "اشعه ایکس",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nهمه چیز را پشت یک پنجره/لایه به جز پس‌زمینه بر روی سطح تاری آن رندر نکنید\nتوصیه می‌شود برای بهبود عملکرد (اگر از شفافیت/تاری سوءاستفاده نکنید)",
"Size": "اندازه",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nشعاع تاری را تنظیم کنید. به طور کلی بر عملکرد تأثیر نمی‌گذارد\nبیشتر = پخش رنگ بیشتر",
"Passes": "عبور",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] تعداد عبورهای الگوریتم تاری را تنظیم کنید\nعبورهای بیشتر = پخش بیشتر و مصرف برق بیشتر\n4 توصیه می‌شود\n2- عجیب به نظر می‌رسد و 6+ بی‌مزه خواهد بود.",
"Animations": "پویانمایی‌ها",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nفعال کردن پویانمایی‌ها",
"Choreography delay": "درنگ در پویایی",
"In milliseconds, the delay between animations of a series": "به میلی‌ثانیه، درنگ بین پویانمایی‌های یک سری",
"Developer": "توسعه‌دهنده",
"Show FPS": "نمایش FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nنمایش پوشش FPS در گوشه بالا سمت چپ",
"Log to stdout": "ثبت در stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nپیام‌های LOG، ERR، WARN و دیگر را به کنسول چاپ کنید",
"Damage tracking": "ردیابی آسیب",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nفعال کردن ردیابی آسیب\nبه طور کلی، آن را روشن بگذارید.\nفقط زمانی که یک سایه‌زن(شیدر) کار نمی‌کند، خاموش کنید",
"Damage blink": "چشمک آسیب",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [هشدار صرع!]\nنمایش چشمک‌های آسیب صفحه",
"Not all changes are saved": "همه تغییرات نگه‌داری نشده‌اند",
"Mo": "دو",
"Tu": "سه",
"We": "چهار",
"Th": "پنج",
"Fr": "جمعه",
"Sa": "شنبه",
"Su": "یک",
"Calendar": "تقویم",
"To Do": "کارها",
"Unfinished": "مانده",
"Done": "پایان یافته",
"Finished tasks will go here": "کارهای پایان یافته اینجا خواهند بود",
"Nothing here!": "هیچ چیز اینجا نیست!",
"+ New task": "+ کار جدید",
"Add a task...": "افزودن یک کار...",
"Color scheme": "طرح رنگ",
"Options": "گزینه‌ها",
"Dark Mode": "حالت تاریک",
"Ya should go to sleep!": "پاشو برو بخواب!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "برنامه‌های GTK را با بکارگیری رنگ تأکید پوسته گذاری کنید\n(معایب: تغییر حالت تاریک/روشن نیاز به باز راه‌اندازی دارد)",
"Scheme styles": "سبک‌های طرح",
"Vibrant": "زنده",
"Vibrant+": "زنده+",
"Expressive": "بیانگر",
"Monochrome": "تک‌رنگ",
"Rainbow": "رنگین کمان",
"Fidelity": "وفاداری",
"Fruit Salad": "سالاد میوه",
"Tonal Spot": "نقطه تنال",
"Content": "محتوا",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "برای ناوبری کلیدهای جهت‌دار را بکار ببرید.\nبرای انتخاب Enter و برای رد کردن Esc را بزنید.",
"Lock": "قفل",
"Logout": "خروج",
"Sleep": "خواب",
"Hibernate": "خواب زمستانی",
"Shutdown": "خاموش",
"Reboot": "باز راه‌اندازی",
"Cancel": "رد کردن",
"Cheat sheet": "برگه تقلب",
"Keybinds": "کلیدهای میانبر",
"Periodic table": "جدول تناوبی",
"Essentials for beginners": "اساس برای مبتدیان",
"Make shell elements transparent": "عناصر شل را شفاف کنید",
"Actions": "کنش",
"Window management": "مدیریت پنجره",
"Window arrangement": "چیدمان پنجره",
"Workspace management": "مدیریت فضای کاری",
"Workspace navigation": "ناوبری فضای کاری",
"Widgets": "ابزارک‌ها",
"Media": "رسانه",
"Apps": "برنامه‌ها",
"Neutral": "خنثی",
"Launch foot (terminal)": "اجرای foot (ترمینال)",
"Open app launcher": "باز کردن راه‌انداز برنامه",
"Change wallpaper": "تغییر پس‌زمینه",
"Clipboard history >> clipboard": "پیشینه کلیپ بورد >> کلیپ بورد",
"Pick emoji >> clipboard": "انتخاب ایموجی >> کلیپ بورد",
"Screen snip >> edit": "برش صفحه >> ویرایش",
"Screen snip to text >> clipboard": "برش صفحه به متن >> کلیپ بورد",
"Pick color (Hex) >> clipboard": "انتخاب رنگ (Hex) >> کلیپ بورد",
"Screenshot >> clipboard": "عکس صفحه >> کلیپ بورد",
"Screenshot >> clipboard & file": "عکس صفحه >> کلیپ بورد و فایل",
"Record region (no sound)": "ضبط منطقه (بدون صدا)",
"Record screen (with sound)": "ضبط صفحه (با صدا)",
"Suspend system": "تعلیق سامانه",
"Move focus in direction": "جابه‌جایی تمرکز در جهت",
"Move window": "جابه‌جایی پنجره",
"Resize window": "تغییر اندازه پنجره",
"Close window": "بستن پنجره",
"Pick and kill a window": "انتخاب و بستن یک پنجره",
"Window: move in direction": "پنجره: جابه‌جایی در جهت",
"Window: split ratio +/- 0.1": "پنجره: نسبت تقسیم +/- 0.1",
"Float/unfloat window": "پنجره را شناور/نا شناور کنید",
"Toggle fake fullscreen": "تغییر حالت تمام صفحه ساختگی",
"Toggle fullscreen": "تغییر حالت تمام صفحه",
"Toggle maximization": "تغییر حالت بزرگ‌نمایی",
"Focus workspace # (1, 2, 3, 4, ...)": "تمرکز بر فضای کاری # (1، 2، 3، 4، ...)",
"Workspace: focus left/right": "فضای کاری: تمرکز به چپ/راست",
"Workspace: toggle special": "فضای کاری: تغییر حالت خاص",
"Window: move to workspace # (1, 2, 3, 4, ...)": "پنجره: رفتن به فضای کاری # (1، 2، 3، 4، ...)",
"Window: move to workspace left/right": "پنجره: رفتن به فضای کاری چپ/راست",
"Window: move to workspace special": "پنجره: رفتن به فضای کاری خاص",
"Window: pin (show on all workspaces)": "پنجره: سنجاق (نمایش در همه فضاهای کاری)",
"Restart widgets": "باز راه‌اندازی ابزارک‌ها",
"Cycle bar mode (normal, focus)": "چرخش حالت نوار (عادی، تمرکز)",
"Toggle overview/launcher": "تغییر حالت نمای کلی/راه‌انداز",
"Show cheatsheet": "نمایش برگه تقلب",
"Toggle left sidebar": "تغییر حالت نوار کناری چپ",
"Toggle right sidebar": "تغییر حالت نوار کناری راست",
"Toggle music controls": "تغییر حالت کنترل‌های موسیقی",
"View color scheme and options": "مشاهده طرح رنگ و گزینه‌ها",
"Toggle power menu": "تغییر حالت فهرست قدرت",
"Toggle crosshair": "تغییر حالت نشانه‌گذاری",
"Next track": "ترانه پسین",
"Previous track": "ترانه پیشین",
"Play/pause media": "پخش/مکث رسانه",
"Launch Zed (editor)": "اجرای Zed (ویرایشگر)",
"Launch VSCode (editor)": "اجرای VSCode (ویرایشگر)",
"Launch Nautilus (file manager)": "اجرای Nautilus (مدیر فایل)",
"Launch Firefox (browser)": "اجرای Firefox (مرورگر)",
"Launch GNOME Text Editor": "اجرای ویرایشگر متن GNOME",
"Launch WPS Office": "اجرای WPS Office",
"Launch GNOME Settings": "اجرای تنظیمات GNOME",
"Launch pavucontrol (volume mixer)": "اجرای pavucontrol (میکسر صدا)",
"Launch EasyEffects (equalizer & other audio effects)": "اجرای EasyEffects (اکولایزر و سایر جلوه‌های صوتی)",
"Launch GNOME System monitor": "اجرای مانیتور سامانه GNOME",
"Toggle fallback launcher: anyrun": "بکارگیری راه‌انداز پشتیبان: anyrun",
"Toggle fallback launcher: fuzzel": "بکارگیری راه‌انداز پشتیبان: fuzzel",
"Initialization complete!": "راه‌اندازی کامل شد!",
"Not found": "یافت نشد:",
"Calling API": "در حال تماس با API",
"Downloading image": "در حال دریافت تصویر",
"Finished!": "پایان یافت!",
"Error": "خطا",
"Not found!": "یافت نشد!",
"Go to file url": "رفتن به URL فایل",
"Save image": "نگه‌داری تصویر",
"Hoard": "نگه‌داری",
"Open externally": "باز کردن در",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nIf user talks to you in Persian and you can also respond in Persian, definitely respond in Persian. Thanks!"
}
-240
View File
@@ -1,240 +0,0 @@
{
"No media": "Aucun média",
"Powered by Google": "Fourni par Google",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "Non affilié, approuvé ou sponsorisé par Google.\n\nConfidentialité : Les messages de chat ne sont pas liés à votre compte,\nmais seront lus par des examinateurs humains pour améliorer le modèle.",
"Precise": "Précis",
"Balanced": "Équilibré",
"Creative": "Créatif",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Température de Gemini.\n Précis = 0\n Équilibré = 0.5\n Créatif = 1",
"Enhancements": "Améliorations",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Indique à Gemini :\n- C'est un assistant de panneau latéral pour Linux\n- Sois concis et utilise des puces",
"Safety": "Sécurité",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "Quand désactivé, indique à l'API (et non au modèle)\nde ne pas bloquer le contenu nuisible/explicite",
"History": "Historique",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Sauvegarde l'historique des discussions\nLes messages des conversations précédentes ne s'affichent pas automatiquement, mais ils existent",
"Key stored in:": "Clé stockée dans :",
"To update this key, type": "Pour mettre à jour cette clé, tapez",
"Updated API Key at": "Clé API mise à jour le",
"Currently using": "Actuellement utilisé",
"Select ChatGPT-compatible API provider": "Sélectionnez un fournisseur d'API compatible ChatGPT",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "API officielle d'OpenAI.\nTarification : Gratuit pour les premiers 5 $ ou 3 mois, selon le moindre des deux.",
"Official Ollama API.\nPricing: Free.": "API officielle d'Ollama.\nTarification : Gratuit.",
"A unified interface for LLMs": "Une interface unifiée pour les LLM",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "Une API de Tornado Softwares\nTarification : Gratuit : 100 par jour\nNécessite de rejoindre leur Discord pour obtenir une clé",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "Une API de @zukixa sur GitHub.\nNote : Les clés sont verrouillées par IP, ce qui peut provoquer des bugs\nTarification : Gratuit : 10/min, 800/jour.\nNécessite de rejoindre leur Discord pour obtenir une clé",
"Provider shown above": "Fournisseur indiqué ci-dessus",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "La valeur de température du modèle.\n Précis = 0\n Équilibré = 0.5\n Créatif = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "Une clé API est requise\nVous pouvez en obtenir une <u>ici</u>, puis la saisir ci-dessous",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Indique au modèle :\n- C'est un assistant de barre latérale pour Linux\n- Sois concis et utilise des puces",
"Powered by waifu.im + other APIs": "Propulsé par waifu.im + d'autres API",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Tapez des tags pour une image aléatoire.\nLe contenu NSFW ne sera pas affiché à moins que\nvous ne demandiez explicitement un tel tag.\n\nAvertissement : Pas affilié aux fournisseurs\net pas responsable de leur contenu.",
"Tags →": "Tags →",
"Invalid command.": "Commande invalide.",
"Anime booru": "Booru d'anime",
"Powered by yande.re and konachan": "Propulsé par yande.re et konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "Un booru d'images. Peut contenir du contenu NSFW.\nFais attention.\n\nAvertissement : Pas affilié au fournisseur\net pas responsable de son contenu.",
"Lewds": "Contenu osé",
"Shows naughty stuff when enabled": "Affiche du contenu osé lorsqu'il est activé",
"Saves images in folders by their tags": "Enregistre les images dans des dossiers selon leurs tags",
"Message Gemini...": "Envoyer un message à Gemini...",
"Enter Google AI API Key...": "Saisissez la clé API de Google AI...",
"Message the model...": "Envoyer un message au modèle...",
"Enter API Key...": "Saisissez la clé API...",
"Enter tags": "Saisissez les tags",
"Quick scripts": "Scripts rapides",
"Change screen resolution": "Changer la résolution de l'écran",
"Update packages": "Mettre à jour les paquets",
"Trim system generations to 5": "Limiter les générations système à 5",
"Trim home manager generations to 5": "Limiter les générations de home-manager à 5",
"Remove orphan packages": "Supprimer les paquets orphelins",
"Uninstall unused flatpak packages": "Désinstaller les paquets Flatpak inutilisés",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Inexact</span> Sélecteur de couleur",
"Result": "Résultat",
"Type to search": "Tapez pour rechercher",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "Utilisation de la RAM",
"Swap Usage": "Utilisation du swap",
"CPU Usage": "Utilisation du CPU",
"Uptime:": "Temps de fonctionnement :",
"Screen snip": "Capture d'écran",
"Color picker": "Sélecteur de couleur",
"Toggle on-screen keyboard": "Activer/désactiver le clavier virtuel",
"Night Light": "Lumière nocturne",
"Color inversion": "Inversion des couleurs",
"Keep system awake": "Empêcher la mise en veille du système",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "Session",
"Bluetooth | Right-click to configure": "Bluetooth | Clic droit pour configurer",
"Wifi | Right-click to configure": "Wifi | Clic droit pour configurer",
"Right-click to configure": "Clic droit pour configurer",
"Unknown": "Inconnu",
"Reload Environment config": "Recharger la configuration de l'environnement",
"Open Settings": "Ouvrir les paramètres",
"Notifications": "Notifications",
"Audio controls": "Contrôles audio",
"Bluetooth": "Bluetooth",
"Wifi networks": "Réseaux Wifi",
"Quick config": "Configuration",
"Silence": "Silence",
"Clear": "Effacer",
"No notifications": "Aucune notification",
"notifications": "notifications",
"Close": "Fermer",
"Now": "Maintenant",
"Yesterday": "Hier",
"No audio source": "Aucune source audio",
"Remove device": "Retirer l'appareil",
"Connected": "Connecté",
"Paired": "Appairé",
"More": "Plus",
"Selected": "Sélectionné",
"Current network": "Réseau actuel",
"Authentication": "Authentification",
"Effects": "Effets",
"Transparency": "Transparence",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nRendre les éléments de l'interface transparents\nLe flou est également recommandé si vous l'activez.\nChoisissez un fond d'écran avant d'activer cette option.",
"Blur": "Flou",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nActiver le flou sur les éléments transparents\nN'affecte pas les performances ou la consommation d'énergie, sauf en cas de fenêtres transparentes.",
"X-ray": "Rayon X",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nNe pas afficher ce qui se trouve derrière une fenêtre ou une couche (sauf le fond d'écran) sur sa surface floue\nRecommandé pour améliorer les performances (si vous n'abusez pas de la transparence/flou) ",
"Size": "Taille",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nAjustez le rayon du flou. En général, cela n'affecte pas les performances\nPlus le rayon est grand, plus la diffusion des couleurs est importante",
"Passes": "Passes",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Ajustez le nombre d'exécutions de l'algorithme de flou\nPlus il y a de passes, plus la diffusion et la consommation d'énergie augmentent\n4 est recommandé\n2 ou moins paraîtraient étranges et 6 ou plus sembleraient médiocres.",
"Animations": "Animations",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nActiver les animations",
"Choreography delay": "Délai de chorégraphie",
"In milliseconds, the delay between animations of a series": "En millisecondes, le délai entre les animations d'une série",
"Developer": "Développeur",
"Show FPS": "Afficher les FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nAfficher une superposition FPS en haut à gauche",
"Log to stdout": "Journaliser vers stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nAfficher les messages LOG, ERR, WARN, etc. dans la console",
"Damage tracking": "Suivi des dégâts",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nActiver le suivi des dégâts\nEn général, laissez-le activé.\nDésactivez-le uniquement si un shader ne fonctionne pas",
"Damage blink": "Clignotement des dégâts",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Avertissement épilepsie !]\nAfficher des flashs lors des modifications de l'écran",
"Not all changes are saved": "Tous les changements ne sont pas enregistrés",
"Mo": "Lu",
"Tu": "Ma",
"We": "Me",
"Th": "Je",
"Fr": "Ve",
"Sa": "Sa",
"Su": "Di",
"Calendar": "Calendrier",
"To Do": "À faire",
"Unfinished": "Non terminé",
"Done": "Terminé",
"Finished tasks will go here": "Les tâches terminées apparaîtront ici",
"Nothing here!": "Rien ici !",
"+ New task": "+ Nouvelle tâche",
"Add a task...": "Ajouter une tâche...",
"Color scheme": "Schéma de couleurs",
"Options": "Options",
"Dark Mode": "Mode sombre",
"Ya should go to sleep!": "Tu devrais aller dormir !",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Thématiser les applications GTK avec la couleur d'accent\n(inconvénient : le changement de mode sombre/clair nécessite un redémarrage)",
"Scheme styles": "Styles de schéma",
"Vibrant": "Vibrant",
"Vibrant+": "Vibrant+",
"Expressive": "Expressif",
"Monochrome": "Monochrome",
"Rainbow": "Arc-en-ciel",
"Fidelity": "Fidélité",
"Fruit Salad": "Salade de fruits",
"Tonal Spot": "Tonal Spot",
"Content": "Contenu",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Utilise les flèches pour naviguer.\nEntrée pour sélectionner, Échap pour annuler.",
"Lock": "Verrouiller",
"Logout": "Se déconnecter",
"Sleep": "Mettre en veille",
"Hibernate": "Hibernation",
"Shutdown": "Éteindre",
"Reboot": "Redémarrer",
"Cancel": "Annuler",
"Cheat sheet": "Aide-mémoire",
"Keybinds": "Raccourcis clavier",
"Periodic table": "Tableau périodique",
"Essentials for beginners": "Notions essentielles pour débutants",
"Make shell elements transparent": "Rendre les éléments de l'interface transparents",
"Actions": "Actions",
"Window management": "Gestion des fenêtres",
"Window arrangement": "Disposition des fenêtres",
"Workspace management": "Gestion des espaces de travail",
"Workspace navigation": "Navigation entre espaces de travail",
"Widgets": "Widgets",
"Media": "Médias",
"Apps": "Applications",
"Neutral": "Neutre",
"Launch foot (terminal)": "Lancer foot (terminal)",
"Open app launcher": "Ouvrir le lanceur d'applications",
"Change wallpaper": "Changer le fond d'écran",
"Clipboard history >> clipboard": "Historique du presse-papiers >> presse-papiers",
"Pick emoji >> clipboard": "Choisir un emoji >> presse-papiers",
"Screen snip >> edit": "Capture d'écran >> éditer",
"Screen snip to text >> clipboard": "Capture d'écran en texte >> presse-papiers",
"Pick color (Hex) >> clipboard": "Choisir une couleur (Hex) >> presse-papiers",
"Screenshot >> clipboard": "Capture d'écran >> presse-papiers",
"Screenshot >> clipboard & file": "Capture d'écran >> presse-papiers & fichier",
"Record region (no sound)": "Enregistrer une région (sans son)",
"Record screen (with sound)": "Enregistrer l'écran (avec son)",
"Suspend system": "Suspendre le système",
"Move focus in direction": "Déplacer le focus dans la direction",
"Move window": "Déplacer la fenêtre",
"Resize window": "Redimensionner la fenêtre",
"Close window": "Fermer la fenêtre",
"Pick and kill a window": "Sélectionner et fermer une fenêtre",
"Window: move in direction": "Fenêtre : déplacer dans la direction",
"Window: split ratio +/- 0.1": "Fenêtre : ajuster le ratio de partage +/- 0.1",
"Float/unfloat window": "Basculer la fenêtre en mode flottant/non flottant",
"Toggle fake fullscreen": "Basculer en faux plein écran",
"Toggle fullscreen": "Basculer le plein écran",
"Toggle maximization": "Basculer la maximisation",
"Focus workspace # (1, 2, 3, 4, ...)": "Sélectionner l'espace de travail n° (1, 2, 3, 4, ...)",
"Workspace: focus left/right": "Espace de travail : se déplacer à gauche/droite",
"Workspace: toggle special": "Espace de travail : basculer spécial",
"Window: move to workspace # (1, 2, 3, 4, ...)": "Fenêtre : déplacer vers l'espace de travail n° (1, 2, 3, 4, ...)",
"Window: move to workspace left/right": "Fenêtre : déplacer vers l'espace de travail à gauche/droite",
"Window: move to workspace special": "Fenêtre : déplacer vers l'espace de travail spécial",
"Window: pin (show on all workspaces)": "Fenêtre : épingler (afficher sur tous les espaces de travail)",
"Restart widgets": "Redémarrer les widgets",
"Cycle bar mode (normal, focus)": "Cycler le mode de la barre (normal, focus)",
"Toggle overview/launcher": "Basculer l'aperçu/le lanceur",
"Show cheatsheet": "Afficher l'aide-mémoire",
"Toggle left sidebar": "Basculer la barre latérale gauche",
"Toggle right sidebar": "Basculer la barre latérale droite",
"Toggle music controls": "Basculer les contrôles de musique",
"View color scheme and options": "Voir le schéma de couleurs et les options",
"Toggle power menu": "Basculer le menu d'alimentation",
"Toggle crosshair": "Basculer le viseur",
"Next track": "Piste suivante",
"Previous track": "Piste précédente",
"Play/pause media": "Lire/metre en pause le média",
"Launch Zed (editor)": "Lancer Zed (éditeur)",
"Launch VSCode (editor)": "Lancer VSCode (éditeur)",
"Launch Nautilus (file manager)": "Lancer Nautilus (gestionnaire de fichiers)",
"Launch Firefox (browser)": "Lancer Firefox (navigateur)",
"Launch GNOME Text Editor": "Lancer GNOME Text Editor",
"Launch WPS Office": "Lancer WPS Office",
"Launch GNOME Settings": "Lancer les paramètres GNOME",
"Launch pavucontrol (volume mixer)": "Lancer pavucontrol (contrôleur de volume)",
"Launch EasyEffects (equalizer & other audio effects)": "Lancer EasyEffects (égaliseur et autres effets audio)",
"Launch GNOME System monitor": "Lancer le moniteur système GNOME",
"Toggle fallback launcher: anyrun": "Basculer le lanceur de secours : anyrun",
"Toggle fallback launcher: fuzzel": "Basculer le lanceur de secours : fuzzel",
"Initialization complete!": "Initialisation terminée !",
"Not found": "Non trouvé :",
"Calling API": "Appel de l'API",
"Downloading image": "Téléchargement de l'image",
"Finished!": "Terminé !",
"Error": "Erreur",
"Not found!": "Non trouvé !",
"Go to file url": "Aller à l'URL du fichier",
"Save image": "Enregistrer l'image",
"Hoard": "Accumuler",
"Open externally": "Ouvrir avec une application externe",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “I'm not sure.”. \nThanks!": "Tu es un assistant dans un panneau latéral d'un bureau Linux sous Wayland. Veilles à toujours adopter un ton décontracté lorsque tu réponds, sauf indication contraire ou lors de suggestions d'écriture. Voici les étapes à suivre pour répondre aux requêtes de l'utilisateur :\n1. S'il s'agit d'une question liée à l'écriture ou à la grammaire, ou d'une phrase entre guillemets, signales les erreurs et corriges-les si nécessaire en utilisant des soulignements, et rends l'écriture plus naturelle lorsque cela est approprié sans apporter de modifications trop importantes. Si on te fournit une phrase entre guillemets mais grammaticalement correcte, expliques brièvement des concepts peu communs.\n2. S'il s'agit d'une question concernant des tâches système, fournis une commande bash dans un bloc de code avec une brève explication.\n3. Sinon, lorsqu'on te demande de résumer des informations ou d'expliquer des concepts, utilises des puces et des titres. Pour les expressions mathématiques, tu *dois* utiliser LaTeX dans un bloc de code avec la langue définie sur \"latex\".\nNote : Utilises un langage décontracté, sois bref, tout en garantissant l'exactitude des informations de ta réponse. Si tu n'es pas sûr ou si tu ne disposes pas d'assez d'informations pour fournir une réponse convaincante, dis simplement \"Je ne sais pas\" ou \"Je ne suis pas sûr\".\nMerci !",
"Feels like": "Ressenti"
}
-238
View File
@@ -1,238 +0,0 @@
{
"No media": "Nessun media",
"Powered by Google": "Offerto da Google",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "Non affiliato, approvato o sponsorizzato da Google.\n\nPrivacy: I messaggi della chat non sono collegati al tuo account,\n ma saranno letti da revisori umani per migliorare il modello.",
"Precise": "Preciso",
"Balanced": "Bilanciato",
"Creative": "Creativo",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Valore di temperatura di Gemini.\n Preciso = 0\n Bilanciato = 0.5\n Creativo = 1",
"Enhancements": "Miglioramenti",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Dice a Gemini:\n- È un assistente laterale per Linux\n- Sii breve e usa punti elenco",
"Safety": "Sicurezza",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "Quando disattivato, dice all'API (non al modello) \n di non bloccare contenuti dannosi/espliciti",
"History": "Cronologia",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Salva la cronologia della chat\nI messaggi nelle chat precedenti non verranno mostrati automaticamente, ma sono lì",
"Key stored in:": "Chiave memorizzata in:",
"To update this key, type": "Per aggiornare questa chiave, digita",
"Updated API Key at": "Chiave API aggiornata alle",
"Currently using": "Attualmente in uso",
"Select ChatGPT-compatible API provider": "Seleziona un provider API compatibile con ChatGPT",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "API ufficiale di OpenAI.\nPrezzi: Gratuito per i primi $5 o 3 mesi, a seconda di quale sia inferiore.",
"Official Ollama API.\nPricing: Free.": "API ufficiale di Ollama.\nPrezzi: Gratuito.",
"A unified interface for LLMs": "Un'interfaccia unificata per LLM",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "Un'API di Tornado Softwares\nPrezzi: Gratuito: 100/giorno\nRichiede di unirsi al loro Discord per una chiave",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "Un'API di @zukixa su GitHub.\nNota: Le chiavi sono bloccate per IP, quindi a volte è instabile\nPrezzi: Gratuito: 10/min, 800/giorno.\nRichiede di unirsi al loro Discord per una chiave",
"Provider shown above": "Provider mostrato sopra",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Valore di temperatura del modello.\n Preciso = 0\n Bilanciato = 0.5\n Creativo = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "È necessaria una chiave API\nPuoi ottenerne una <u>qui</u>, quindi inserirla qui sotto",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Dice al modello:\n- È un assistente laterale per Linux\n- Sii breve e usa punti elenco",
"Powered by waifu.im + other APIs": "Offerto da waifu.im + altre API",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Digita i tag per un'immagine casuale.\nIl contenuto NSFW non verrà restituito a meno che\nnon richiedi esplicitamente un tale tag.\n\nDisclaimer: Non affiliato ai provider\nné responsabile per alcun loro contenuto.",
"Tags →": "Tag →",
"Invalid command.": "Comando non valido.",
"Anime booru": "Anime booru",
"Powered by yande.re and konachan": "Offerto da yande.re e konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "Un booru di immagini. Potrebbe contenere contenuti NSFW.\nFai attenzione.\n\nDisclaimer: Non affiliato al provider\nné responsabile per alcun suo contenuto.",
"Lewds": "Contenuti osé",
"Shows naughty stuff when enabled": "Mostra contenuti osé quando abilitato",
"Saves images in folders by their tags": "Salva le immagini in cartelle in base ai loro tag",
"Message Gemini...": "Messaggia Gemini...",
"Enter Google AI API Key...": "Inserisci la chiave API di Google AI...",
"Message the model...": "Messaggia il modello...",
"Enter API Key...": "Inserisci la chiave API...",
"Enter tags": "Inserisci i tag",
"Quick scripts": "Script rapidi",
"Change screen resolution": "Cambia risoluzione dello schermo",
"Update packages": "Aggiorna i pacchetti",
"Trim system generations to 5": "Riduci le generazioni del sistema a 5",
"Trim home manager generations to 5": "Riduci le generazioni del gestore di casa a 5",
"Remove orphan packages": "Rimuovi i pacchetti orfani",
"Uninstall unused flatpak packages": "Disinstalla i pacchetti flatpak non utilizzati",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Impreciso</span> Selettore di colore",
"Result": "Risultato",
"Type to search": "Digita per cercare",
"illogical-impulse": "impulso illogico",
"RAM Usage": "Utilizzo della RAM",
"Swap Usage": "Utilizzo dello Swap",
"CPU Usage": "Utilizzo della CPU",
"Uptime:": "Tempo di attività:",
"Screen snip": "Ritaglio dello schermo",
"Color picker": "Selettore di colore",
"Toggle on-screen keyboard": "Attiva/disattiva tastiera su schermo",
"Night Light": "Luce notturna",
"Color inversion": "Inversione di colore",
"Keep system awake": "Mantieni il sistema sveglio",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "Sessione",
"Bluetooth | Right-click to configure": "Bluetooth | Clic destro per configurare",
"Wifi | Right-click to configure": "Wifi | Clic destro per configurare",
"Right-click to configure": "Clic destro per configurare",
"Unknown": "Sconosciuto",
"Reload Environment config": "Ricarica la configurazione dell'ambiente",
"Open Settings": "Apri Impostazioni",
"Notifications": "Notifiche",
"Audio controls": "Controlli audio",
"Bluetooth": "Bluetooth",
"Wifi networks": "Reti Wifi",
"Quick config": "Configurazione",
"Silence": "Silenzio",
"Clear": "Cancella",
"No notifications": "Nessuna notifica",
"notifications": "notifiche",
"Close": "Chiudi",
"Now": "Ora",
"Yesterday": "Ieri",
"No audio source": "Nessuna sorgente audio",
"Remove device": "Rimuovi dispositivo",
"Connected": "Connesso",
"Paired": "Abbinato",
"More": "Altro",
"Selected": "Selezionato",
"Current network": "Rete corrente",
"Authentication": "Autenticazione",
"Effects": "Effetti",
"Transparency": "Trasparenza",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nRendi trasparenti gli elementi della shell\nSi consiglia anche il blur se abiliti questa opzione",
"Blur": "Blur",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nAbilita il blur sugli elementi trasparenti\nNon influisce sulle prestazioni/consumo energetico a meno che non si abbiano finestre trasparenti.",
"X-ray": "Raggi X",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nRendi tutto dietro una finestra/livello, tranne lo sfondo, non renderizzato sulla sua superficie sfocata\nConsigliato per migliorare le prestazioni (se non abusi di trasparenza/blur) ",
"Size": "Dimensione",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nRegola il raggio del blur. Generalmente non influisce sulle prestazioni\nPiù alto = più diffusione del colore",
"Passes": "Passaggi",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Regola il numero di esecuzioni dell'algoritmo di blur\nPiù passaggi = più diffusione e consumo energetico\nSi consigliano 4\n2- sembrerebbe strano e 6+ sembrerebbe scadente.",
"Animations": "Animazioni",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nAbilita le animazioni",
"Choreography delay": "Ritardo della coreografia",
"In milliseconds, the delay between animations of a series": "In millisecondi, il ritardo tra le animazioni di una serie",
"Developer": "Sviluppatore",
"Show FPS": "Mostra FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nMostra l'overlay degli FPS nell'angolo in alto a sinistra",
"Log to stdout": "Log su stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nStampa i messaggi LOG, ERR, WARN, ecc. sulla console",
"Damage tracking": "Tracciamento dei danni",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nAbilita il tracciamento dei danni\nGeneralmente, lascialo acceso.\nDisattivalo solo quando uno shader non funziona",
"Damage blink": "Lampeggio dei danni",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Avviso epilessia!]\nMostra i lampeggi dei danni dello schermo",
"Not all changes are saved": "Non tutte le modifiche sono state salvate",
"Mo": "Lu",
"Tu": "Ma",
"We": "Me",
"Th": "Gi",
"Fr": "Ve",
"Sa": "Sa",
"Su": "Do",
"Calendar": "Calendario",
"To Do": "Da fare",
"Unfinished": "Incompleto",
"Done": "Fatto",
"Finished tasks will go here": "Le attività completate andranno qui",
"Nothing here!": "Niente qui!",
"+ New task": "+ Nuova attività",
"Add a task...": "Aggiungi un'attività...",
"Color scheme": "Schema di colori",
"Options": "Opzioni",
"Dark Mode": "Modalità scura",
"Ya should go to sleep!": "Dovresti andare a dormire!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Tema le app GTK usando il colore di accento\n(svantaggio: il passaggio tra modalità scura/chiara richiede un riavvio)",
"Scheme styles": "Stili dello schema",
"Vibrant": "Vivace",
"Vibrant+": "Vivace+",
"Expressive": "Espressivo",
"Monochrome": "Monocromatico",
"Rainbow": "Arcobaleno",
"Fidelity": "Fedeltà",
"Fruit Salad": "Macedonia di frutta",
"Tonal Spot": "Punto tonale",
"Content": "Contenuto",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Usa i tasti freccia per navigare.\nInvio per selezionare, Esc per annullare.",
"Lock": "Blocca",
"Logout": "Esci",
"Sleep": "Sospendi",
"Hibernate": "Iberna",
"Shutdown": "Spegni",
"Reboot": "Riavvia",
"Cancel": "Annulla",
"Cheat sheet": "Foglio di riferimento",
"Keybinds": "Scorciatoie da tastiera",
"Periodic table": "Tavola periodica",
"Essentials for beginners": "Essenziali per principianti",
"Make shell elements transparent": "Rendi trasparenti gli elementi della shell",
"Actions": "Azioni",
"Window management": "Gestione delle finestre",
"Window arrangement": "Disposizione delle finestre",
"Workspace management": "Gestione degli spazi di lavoro",
"Workspace navigation": "Navigazione degli spazi di lavoro",
"Widgets": "Widget",
"Media": "Media",
"Apps": "App",
"Neutral": "Neutro",
"Launch foot (terminal)": "Avvia foot (terminale)",
"Open app launcher": "Apri il launcher delle app",
"Change wallpaper": "Cambia lo sfondo",
"Clipboard history >> clipboard": "Cronologia degli appunti >> appunti",
"Pick emoji >> clipboard": "Scegli emoji >> appunti",
"Screen snip >> edit": "Ritaglio dello schermo >> modifica",
"Screen snip to text >> clipboard": "Ritaglio dello schermo in testo >> appunti",
"Pick color (Hex) >> clipboard": "Scegli colore (Hex) >> appunti",
"Screenshot >> clipboard": "Screenshot >> appunti",
"Screenshot >> clipboard & file": "Screenshot >> appunti e file",
"Record region (no sound)": "Registra regione (senza audio)",
"Record screen (with sound)": "Registra schermo (con audio)",
"Suspend system": "Sospendi il sistema",
"Move focus in direction": "Sposta il focus nella direzione",
"Move window": "Sposta la finestra",
"Resize window": "Ridimensiona la finestra",
"Close window": "Chiudi la finestra",
"Pick and kill a window": "Scegli e chiudi una finestra",
"Window: move in direction": "Finestra: sposta nella direzione",
"Window: split ratio +/- 0.1": "Finestra: rapporto di divisione +/- 0.1",
"Float/unfloat window": "Finestra libera/agganciata",
"Toggle fake fullscreen": "Attiva/disattiva falso fullscreen",
"Toggle fullscreen": "Attiva/disattiva fullscreen",
"Toggle maximization": "Attiva/disattiva massimizzazione",
"Focus workspace # (1, 2, 3, 4, ...)": "Focalizza spazio di lavoro # (1, 2, 3, 4, ...)",
"Workspace: focus left/right": "Spazio di lavoro: focalizza sinistra/destra",
"Workspace: toggle special": "Spazio di lavoro: attiva/disattiva speciale",
"Window: move to workspace # (1, 2, 3, 4, ...)": "Finestra: sposta in spazio di lavoro # (1, 2, 3, 4, ...)",
"Window: move to workspace left/right": "Finestra: sposta in spazio di lavoro sinistra/destra",
"Window: move to workspace special": "Finestra: sposta in spazio di lavoro speciale",
"Window: pin (show on all workspaces)": "Finestra: fissa (mostra su tutti gli spazi di lavoro)",
"Restart widgets": "Riavvia widget",
"Cycle bar mode (normal, focus)": "Cicla modalità barra (normale, focus)",
"Toggle overview/launcher": "Attiva/disattiva panoramica/lanciatore",
"Show cheatsheet": "Mostra cheatsheet",
"Toggle left sidebar": "Attiva/disattiva barra laterale sinistra",
"Toggle right sidebar": "Attiva/disattiva barra laterale destra",
"Toggle music controls": "Attiva/disattiva controlli musicali",
"View color scheme and options": "Visualizza schema colori e opzioni",
"Toggle power menu": "Attiva/disattiva menu di spegnimento",
"Toggle crosshair": "Attiva/disattiva mirino",
"Next track": "Traccia successiva",
"Previous track": "Traccia precedente",
"Play/pause media": "Riproduci/pausa media",
"Launch Zed (editor)": "Avvia Zed (editor)",
"Launch VSCode (editor)": "Avvia VSCode (editor)",
"Launch Nautilus (file manager)": "Avvia Nautilus (gestore file)",
"Launch Firefox (browser)": "Avvia Firefox (browser)",
"Launch GNOME Text Editor": "Avvia GNOME Text Editor",
"Launch WPS Office": "Avvia WPS Office",
"Launch GNOME Settings": "Avvia Impostazioni GNOME",
"Launch pavucontrol (volume mixer)": "Avvia pavucontrol (mixer volume)",
"Launch EasyEffects (equalizer & other audio effects)": "Avvia EasyEffects (equalizzatore & altri effetti audio)",
"Launch GNOME System monitor": "Avvia monitor di sistema GNOME",
"Toggle fallback launcher: anyrun": "Attiva/disattiva lanciatore di riserva: anyrun",
"Toggle fallback launcher: fuzzel": "Attiva/disattiva lanciatore di riserva: fuzzel",
"Initialization complete!": "Inizializzazione completata!",
"Not found": "Non trovato",
"Calling API": "Chiamata API",
"Downloading image": "Scaricamento immagine",
"Finished!": "Completato!",
"Error": "Errore",
"Not found!": "Non trovato!",
"Go to file url": "Vai all'url del file",
"Save image": "Salva immagine",
"Hoard": "Accumula",
"Open externally": "Apri esternamente",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "Sei un assistente nella barra laterale di un desktop Wayland Linux. Usa sempre un tono informale quando rispondi alle domande, a meno che non venga richiesto diversamente o quando fai suggerimenti di scrittura. Ecco i passaggi che devi seguire per rispondere alle domande dell'utente:\n1. Se si tratta di una domanda sulla scrittura o sulla grammatica o di una frase tra virgolette, segnala gli errori e correggi quando necessario utilizzando sottolineature, e rendi la scrittura più naturale dove appropriato senza fare modifiche troppo importanti. Se ti viene data una frase tra virgolette ma è grammaticalmente corretta, spiega brevemente concetti che sono poco comuni.\n2. Se è una domanda su attività di sistema, fornisci un comando bash in un blocco di codice con una breve spiegazione.\n3. Altrimenti, quando ti viene chiesto di riassumere informazioni o spiegare concetti, usa punti elenco e titoli. Per espressioni matematiche, *devi* usare LaTeX all'interno di un blocco di codice con il linguaggio impostato su \"latex\". \nNota: usa un linguaggio informale, sii breve, assicurandoti della correttezza fattuale della tua risposta. Se non sei sicuro o non hai abbastanza informazioni per fornire una risposta sicura, semplicemente dici “Non lo so” o “Non sono sicuro”. \nGrazie!"
}
-239
View File
@@ -1,239 +0,0 @@
{
"No media": "无媒体活动",
"Powered by Google": "由 Google 提供技术支持",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "不隶属于、不受 Google 赞助或支持。\n\n隐私:聊天信息不会与你的账户关联,\n但会被人类审阅者阅读,用于改进模型。",
"Precise": "精确",
"Balanced": "平衡",
"Creative": "创意",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini 的 temperature 值\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1",
"Enhancements": "增强功能",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉 Gemini\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号",
"Safety": "安全",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "当关闭时,告诉 API(而不是模型)\n不要屏蔽有害/显露的内容",
"History": "历史",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "保存聊天历史\n以前聊天中的消息不会自动显示,但它们仍然存在",
"Key stored in:": "密钥值储存在:",
"To update this key, type": "要更新此密钥,请输入",
"Updated API Key at": "更新了 API 密钥于",
"Currently using": "当前使用",
"Select ChatGPT-compatible API provider": "选择与 ChatGPT 兼容的 API 提供商",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "官方 OpenAI API。\n定价:前 $5 或前 3 个月免费,取较小者。",
"Official Ollama API.\nPricing: Free.": "官方 Ollama API。\n定价:免费。",
"A unified interface for LLMs": "LLM 的统一接口",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "来自 Tornado Softwares 的 API\n定价:免费:每天 100 次请求\n需要加入他们的 Discord 以获取密钥",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "来自 GitHub 上的 @zukixa 的 API。\n注意:密钥与 IP 绑定,所以有时会出错。\n定价:免费:每分钟 10 次,每天 800 次。\n需要加入他们的 Discord 才能获得密钥。",
"Provider shown above": "上述显示的提供商",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "模型的 temperature 值。\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "需要 API 密钥\n您可以在<u>这里</u>获取一个,然后在下面输入",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉模型:\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号",
"Powered by waifu.im + other APIs": "由 waifu.im + 其他 API 提供支持",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "输入标签以获取随机图片。\n除非您明确请求,否则不会返回 NSFW 内容。\n\n免责声明:与提供商无关联\n我也不对他们的任何内容负责。",
"Tags →": "标签 →",
"Invalid command.": "无效命令。",
"Anime booru": "动漫图库",
"Powered by yande.re and konachan": "由 yande.re 和 konachan 提供支持",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "一个图片图库。可能包含 NSFW 内容。\n小心。\n\n免责声明:与提供商无关联\n也不对它的任何内容负责。",
"Lewds": "不雅内容",
"Shows naughty stuff when enabled": "启用时显示不雅内容",
"Saves images in folders by their tags": "按标签将图片保存到文件夹中",
"Message Gemini...": "向 Gemini 发送消息...",
"Enter Google AI API Key...": "输入 Google AI API 密钥...",
"Message the model...": "向模型发送消息...",
"Enter API Key...": "输入 API 密钥...",
"Enter tags": "输入标签",
"Quick scripts": "快速脚本",
"Change screen resolution": "更改屏幕分辨率",
"Update packages": "更新软件包",
"Trim system generations to 5": "将系统代数修剪为 5",
"Trim home manager generations to 5": "将 home manager 代数修剪为 5",
"Remove orphan packages": "移除孤立软件包",
"Uninstall unused flatpak packages": "卸载未使用的 Flatpak 软件包",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">不准确</span> 颜色选择器",
"Result": "结果",
"Type to search": "输入以搜索",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "RAM 使用情况",
"Swap Usage": "Swap 使用情况",
"CPU Usage": "CPU 使用情况",
"Uptime:": "运行时间:",
"Screen snip": "屏幕截图",
"Color picker": "颜色选择器",
"Toggle on-screen keyboard": "切换屏幕键盘",
"Night Light": "夜灯",
"Color inversion": "颜色反转",
"Keep system awake": "保持系统唤醒",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "会话",
"Bluetooth | Right-click to configure": "蓝牙 | 右键单击以配置",
"Wifi | Right-click to configure": "Wi-Fi | 右键单击以配置",
"Right-click to configure": "右键单击以配置",
"Unknown": "未知",
"Reload Environment config": "重新加载环境配置",
"Open Settings": "打开设置",
"Notifications": "通知",
"Audio controls": "音频控制",
"Bluetooth": "蓝牙",
"Wifi networks": "Wi-Fi 网络",
"Quick config": "实时配置",
"Silence": "静音",
"Clear": "清除",
"No notifications": "无通知",
"notifications": "条通知",
"Close": "关闭",
"Now": "现在",
"Yesterday": "昨天",
"No audio source": "没有音频源",
"Remove device": "移除设备",
"Connected": "已连接",
"Paired": "已配对",
"More": "更多",
"Selected": "已选中",
"Current network": "当前网络",
"Authentication": "身份验证",
"Effects": "效果",
"Transparency": "透明度",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\n使外壳元素透明\n如果启用此功能,也建议使用模糊效果",
"Blur": "模糊",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\n在透明元素上启用模糊效果\n除非您有透明窗口,否则不会影响性能/功耗。",
"X-ray": "X-ray",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\n使窗口/图层后面的所有内容(除了壁纸)在其模糊表面上不渲染\n建议提高性能(如果您不滥用透明度/模糊)",
"Size": "大小",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\n调整模糊半径。通常不会影响性能\n数值越高 = 颜色扩散越大",
"Passes": "次数",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland]\n调整模糊算法的运行次数\n次数越多 = 扩散越大,功耗越高\n建议使用 4 次\n2 次看起来很奇怪,6 次以上看起来很糟糕。",
"Animations": "动画",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\n启用动画",
"Choreography delay": "间隔",
"In milliseconds, the delay between animations of a series": "以毫秒为单位,一系列动画之间的延迟",
"Developer": "开发者选项",
"Show FPS": "显示 FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\n在左上角显示 FPS 叠加层",
"Log to stdout": "输出日志",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\n将 LOG、ERR、WARN 等消息打印到控制台",
"Damage tracking": "Damage tracking",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\n启用 Damage tracking \n通常情况下,保持启用状态\n仅当着色器无法正常工作时才禁用",
"Damage blink": "显示视图更新",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [癫痫警告!]\n屏幕视图更新时闪烁",
"Not all changes are saved": "并非所有更改都已保存",
"Mo": "一",
"Tu": "二",
"We": "三",
"Th": "四",
"Fr": "五",
"Sa": "六",
"Su": "日",
"Calendar": "日历",
"To Do": "待办",
"Unfinished": "未完成",
"Done": "已完成",
"Finished tasks will go here": "已完成的任务将显示在此处",
"Nothing here!": "这里什么也没有!",
"+ New task": "+ 新任务",
"Add a task...": "添加任务...",
"Color scheme": "配色方案",
"Options": "选项",
"Dark Mode": "深色模式",
"Ya should go to sleep!": "你应该去睡觉!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "使用强调色对 GTK 应用程序进行主题化\n(缺点:深色/浅色模式切换需要重启)",
"Scheme styles": "样式方案",
"Vibrant": "鲜艳",
"Vibrant+": "鲜艳+",
"Expressive": "表现力",
"Monochrome": "黑白",
"Rainbow": "彩虹",
"Fidelity": "保真度",
"Fruit Salad": "水果沙拉",
"Tonal Spot": "色调点",
"Content": "内容",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "使用箭头键导航。\n回车键选择,Esc 键取消。",
"Lock": "锁屏",
"Logout": "注销",
"Sleep": "睡眠",
"Hibernate": "休眠",
"Shutdown": "关机",
"Reboot": "重启",
"Cancel": "取消",
"Cheat sheet": "备忘单",
"Keybinds": "按键绑定",
"Periodic table": "元素周期表",
"Essentials for beginners": "初学者必备",
"Make shell elements transparent": "使外壳元素透明",
"Actions": "操作",
"Window management": "窗口管理",
"Window arrangement": "窗口排列",
"Workspace management": "工作区管理",
"Workspace navigation": "工作区导航",
"Widgets": "小部件",
"Media": "媒体",
"Apps": "应用程序",
"Neutral": "中性",
"Launch foot (terminal)": "启动终端(foot",
"Open app launcher": "打开应用程序启动器",
"Change wallpaper": "更改壁纸",
"Clipboard history >> clipboard": "剪贴板历史 >> 剪贴板",
"Pick emoji >> clipboard": "选择表情符号 >> 剪贴板",
"Screen snip >> edit": "屏幕截图 >> 编辑",
"Screen snip to text >> clipboard": "屏幕截图转文字 >> 剪贴板",
"Pick color (Hex) >> clipboard": "选择颜色(十六进制)>> 剪贴板",
"Screenshot >> clipboard": "屏幕截图 >> 剪贴板",
"Screenshot >> clipboard & file": "屏幕截图 >> 剪贴板和文件",
"Record region (no sound)": "录制区域(无声音)",
"Record screen (with sound)": "录制屏幕(带声音)",
"Suspend system": "挂起系统",
"Move focus in direction": "在方向上移动焦点",
"Move window": "移动窗口",
"Resize window": "调整窗口大小",
"Close window": "关闭窗口",
"Pick and kill a window": "选择并关闭一个窗口",
"Window: move in direction": "窗口:在方向上移动",
"Window: split ratio +/- 0.1": "窗口:分割比例 +/- 0.1",
"Float/unfloat window": "浮动/取消浮动窗口",
"Toggle fake fullscreen": "切换伪全屏",
"Toggle fullscreen": "切换全屏",
"Toggle maximization": "切换最大化",
"Focus workspace # (1, 2, 3, 4, ...)": "聚焦工作区 #1, 2, 3, 4, ...",
"Workspace: focus left/right": "工作区:聚焦左右",
"Workspace: toggle special": "工作区:切换特殊工作区",
"Window: move to workspace # (1, 2, 3, 4, ...)": "窗口:移动到工作区 #1, 2, 3, 4, ...",
"Window: move to workspace left/right": "窗口:移动到左右工作区",
"Window: move to workspace special": "窗口:移动到特殊工作区",
"Window: pin (show on all workspaces)": "窗口:固定(在所有工作区显示)",
"Restart widgets": "重启小部件",
"Cycle bar mode (normal, focus)": "循环栏模式(正常,聚焦)",
"Toggle overview/launcher": "切换概览/启动器",
"Show cheatsheet": "显示快捷键表",
"Toggle left sidebar": "切换左侧边栏",
"Toggle right sidebar": "切换右侧边栏",
"Toggle music controls": "切换音乐控制",
"View color scheme and options": "查看配色方案和选项",
"Toggle power menu": "切换电源菜单",
"Toggle crosshair": "切换准星",
"Next track": "下一曲目",
"Previous track": "上一曲目",
"Play/pause media": "播放/暂停媒体",
"Launch Zed (editor)": "启动 Zed(编辑器)",
"Launch VSCode (editor)": "启动 VSCode(编辑器)",
"Launch Nautilus (file manager)": "启动 Nautilus(文件管理器)",
"Launch Firefox (browser)": "启动 Firefox(浏览器)",
"Launch GNOME Text Editor": "启动 GNOME 文本编辑器",
"Launch WPS Office": "启动 WPS 办公软件",
"Launch GNOME Settings": "启动 GNOME 设置",
"Launch pavucontrol (volume mixer)": "启动 pavucontrol(音量混合器)",
"Launch EasyEffects (equalizer & other audio effects)": "启动 EasyEffects(均衡器和其他音频效果)",
"Launch GNOME System monitor": "启动 GNOME 系统监视器",
"Toggle fallback launcher: anyrun": "切换备用启动器:anyrun",
"Toggle fallback launcher: fuzzel": "切换备用启动器:fuzzel",
"Initialization complete!": "初始化完成!",
"Not found": "未找到",
"Calling API": "调用 API",
"Downloading image": "正在下载图片",
"Finished!": "完成!",
"Error": "错误",
"Not found!": "未找到!",
"Go to file url": "前往文件链接",
"Save image": "保存图片",
"Hoard": "保存",
"Open externally": "在外部打开",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "你是 Wayland Linux 桌面侧边栏上的助手。除非有其他要求或提供建议,否则请始终保持轻松的语气回答问题。这是你回答用户查询的步骤:\n1. 如果是写作或语法相关的问题,或者引号中的句子,请指出错误并在必要时进行更正,使用下划线,并在适当的地方使写作更自然,不要进行太大更改。如果你给出的句子在引号中但语法正确,请简要解释不常见概念。\n2. 如果是关于系统任务的问题,请给出bash命令,并在代码块中简要说明。\n3. 否则,在总结信息或解释概念时,你应该使用项目符号和标题。对于数学表达式,你必须在代码块中使用 LaTeX,并将语言设置为\"latex\"。\n注意:使用轻松的语言,简洁,同时确保回答的事实正确性。如果你不确定或没有足够的信息来提供自信的答案,只需说“我不知道”或“我不确定”。\n谢谢!",
"Feels like": "体感温度"
}
-53
View File
@@ -1,53 +0,0 @@
const { Gio, GLib } = imports.gi;
import GtkSource from "gi://GtkSource?version=3.0";
import App from 'resource:///com/github/Aylur/ags/app.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import { darkMode } from './modules/.miscutils/system.js';
const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/assets/themes/sourceviewtheme${darkMode.value ? '' : '-light'}.xml`;
export const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
function loadSourceViewColorScheme(filePath) {
// Read the XML file content
const file = Gio.File.new_for_path(filePath);
const [success, contents] = file.load_contents(null);
if (!success) {
logError('Failed to load the XML file.');
return;
}
// Parse the XML content and set the Style Scheme
const schemeManager = GtkSource.StyleSchemeManager.get_default();
schemeManager.append_search_path(file.get_parent().get_path());
}
globalThis['handleStyles'] = (resetMusic) => {
// Reset
Utils.exec(`mkdir -p "${GLib.get_user_state_dir()}/ags/scss"`);
if (resetMusic) {
Utils.exec(`bash -c 'echo "" > ${GLib.get_user_state_dir()}/ags/scss/_musicwal.scss'`); // reset music styles
Utils.exec(`bash -c 'echo "" > ${GLib.get_user_state_dir()}/ags/scss/_musicmaterial.scss'`); // reset music styles
}
// Generate overrides
let lightdark = darkMode.value ? "dark" : "light";
Utils.writeFileSync(
`
@mixin symbolic-icon {
-gtk-icon-theme: '${userOptions.icons.symbolicIconTheme[lightdark]}';
}
`,
`${GLib.get_user_state_dir()}/ags/scss/_lib_mixins_overrides.scss`)
// Compile and apply
async function applyStyle() {
Utils.exec(`mkdir -p ${COMPILED_STYLE_DIR}`);
Utils.exec(`sass -I "${GLib.get_user_state_dir()}/ags/scss" -I "${App.configDir}/scss/fallback" "${App.configDir}/scss/main.scss" "${COMPILED_STYLE_DIR}/style.css"`);
App.resetCss();
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`);
console.log('[LOG] Styles loaded')
}
applyStyle().then(() => {
loadSourceViewColorScheme(CUSTOM_SOURCEVIEW_SCHEME_PATH);
}).catch(print);
}
@@ -1,33 +0,0 @@
const { Gdk } = imports.gi;
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
export let monitors;
// Mixes with Gdk monitor size cuz it reports monitor size scaled
async function updateStuff() {
monitors = JSON.parse(exec('hyprctl monitors -j'))
const display = Gdk.Display.get_default();
monitors.forEach((monitor, i) => {
const gdkMonitor = display.get_monitor(i);
monitor.realWidth = monitor.width;
monitor.realHeight = monitor.height;
if (userOptions.monitors.scaleMethod.toLowerCase == "gdk") {
monitor.width = gdkMonitor.get_geometry().width;
monitor.height = gdkMonitor.get_geometry().height;
}
else { // == "division"
if (monitor.transform % 2 == 1) { // Vertical monitors (or horizontal monitor that's vertical by default...)
monitor.width = Math.floor(monitor.realHeight / monitor.scale);
monitor.height = Math.floor(monitor.realWidth / monitor.scale);
}
else {
monitor.width = Math.ceil(monitor.realWidth / monitor.scale);
monitor.height = Math.ceil(monitor.realHeight / monitor.scale);
}
}
});
}
updateStuff().catch(print);
-14
View File
@@ -1,14 +0,0 @@
export const quotes = [
{
quote: 'Nvidia, fuck you',
author: 'Linus Torvalds',
},
{
quote: 'reproducible system? cock and vagina?',
author: 'vaxry',
},
{
quote: "haha pointers hee hee i love pointe-\\\nProcess Vaxry exited with signal SIGSEGV",
author: 'vaxry',
}
];
@@ -1,94 +0,0 @@
export const WWO_CODE = {
"113": "Sunny",
"116": "PartlyCloudy",
"119": "Cloudy",
"122": "VeryCloudy",
"143": "Fog",
"176": "LightShowers",
"179": "LightSleetShowers",
"182": "LightSleet",
"185": "LightSleet",
"200": "ThunderyShowers",
"227": "LightSnow",
"230": "HeavySnow",
"248": "Fog",
"260": "Fog",
"263": "LightShowers",
"266": "LightRain",
"281": "LightSleet",
"284": "LightSleet",
"293": "LightRain",
"296": "LightRain",
"299": "HeavyShowers",
"302": "HeavyRain",
"305": "HeavyShowers",
"308": "HeavyRain",
"311": "LightSleet",
"314": "LightSleet",
"317": "LightSleet",
"320": "LightSnow",
"323": "LightSnowShowers",
"326": "LightSnowShowers",
"329": "HeavySnow",
"332": "HeavySnow",
"335": "HeavySnowShowers",
"338": "HeavySnow",
"350": "LightSleet",
"353": "LightShowers",
"356": "HeavyShowers",
"359": "HeavyRain",
"362": "LightSleetShowers",
"365": "LightSleetShowers",
"368": "LightSnowShowers",
"371": "HeavySnowShowers",
"374": "LightSleetShowers",
"377": "LightSleet",
"386": "ThunderyShowers",
"389": "ThunderyHeavyRain",
"392": "ThunderySnowShowers",
"395": "HeavySnowShowers",
}
export const WEATHER_SYMBOL = {
"Unknown": "air",
"Cloudy": "cloud",
"Fog": "foggy",
"HeavyRain": "rainy",
"HeavyShowers": "rainy",
"HeavySnow": "snowing",
"HeavySnowShowers": "snowing",
"LightRain": "rainy",
"LightShowers": "rainy",
"LightSleet": "rainy",
"LightSleetShowers": "rainy",
"LightSnow": "cloudy_snowing",
"LightSnowShowers": "cloudy_snowing",
"PartlyCloudy": "partly_cloudy_day",
"Sunny": "clear_day",
"ThunderyHeavyRain": "thunderstorm",
"ThunderyShowers": "thunderstorm",
"ThunderySnowShowers": "thunderstorm",
"VeryCloudy": "cloud",
}
export const NIGHT_WEATHER_SYMBOL = {
"Unknown": "air",
"Cloudy": "cloud",
"Fog": "foggy",
"HeavyRain": "rainy",
"HeavyShowers": "rainy",
"HeavySnow": "snowing",
"HeavySnowShowers": "snowing",
"LightRain": "rainy",
"LightShowers": "rainy",
"LightSleet": "rainy",
"LightSleetShowers": "rainy",
"LightSnow": "cloudy_snowing",
"LightSnowShowers": "cloudy_snowing",
"PartlyCloudy": "partly_cloudy_night",
"Sunny": "clear_night",
"ThunderyHeavyRain": "thunderstorm",
"ThunderyShowers": "thunderstorm",
"ThunderySnowShowers": "thunderstorm",
"VeryCloudy": "cloud",
}
@@ -1,106 +0,0 @@
const { Gtk } = imports.gi;
const Lang = imports.lang;
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
// -- Styling --
// min-height for diameter
// min-width for trough stroke
// padding for space between trough and progress
// margin for space between widget and parent
// background-color for trough color
// color for progress color
// -- Usage --
// font size for progress value (0-100px) (hacky i know, but i want animations)
export const AnimatedCircProg = ({
initFrom = 0,
initTo = 0,
initAnimTime = 2900,
initAnimPoints = 1,
extraSetup = () => { },
...rest
}) => Widget.DrawingArea({
...rest,
css: `${initFrom != initTo ? 'font-size: ' + initFrom + 'px; transition: ' + initAnimTime + 'ms linear;' : ''}`,
setup: (area) => {
const styleContext = area.get_style_context();
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
area.connect('draw', Lang.bind(area, (area, cr) => {
const styleContext = area.get_style_context();
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
const progressValue = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100.0;
const bg_stroke = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const fg_stroke = bg_stroke - padding;
const radius = Math.min(width, height) / 2.0 - Math.max(bg_stroke, fg_stroke) / 2.0;
const center_x = width / 2.0 + marginLeft;
const center_y = height / 2.0 + marginTop;
const start_angle = -Math.PI / 2.0;
const end_angle = start_angle + (2 * Math.PI * progressValue);
const start_x = center_x + Math.cos(start_angle) * radius;
const start_y = center_y + Math.sin(start_angle) * radius;
const end_x = center_x + Math.cos(end_angle) * radius;
const end_y = center_y + Math.sin(end_angle) * radius;
// Draw background
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
cr.arc(center_x, center_y, radius, 0, 2 * Math.PI);
cr.setLineWidth(bg_stroke);
cr.stroke();
if (progressValue == 0) return;
// Draw progress
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
cr.arc(center_x, center_y, radius, start_angle, end_angle);
cr.setLineWidth(fg_stroke);
cr.stroke();
// Draw rounded ends for progress arcs
cr.setLineWidth(0);
cr.arc(start_x, start_y, fg_stroke / 2, 0, 0 - 0.01);
cr.fill();
cr.arc(end_x, end_y, fg_stroke / 2, 0, 0 - 0.01);
cr.fill();
}));
// Init animation
if (initFrom != initTo) {
area.css = `font-size: ${initFrom}px; transition: ${initAnimTime}ms linear;`;
Utils.timeout(20, () => {
area.css = `font-size: ${initTo}px;`;
}, area)
const transitionDistance = initTo - initFrom;
const oneStep = initAnimTime / initAnimPoints;
area.css = `
font-size: ${initFrom}px;
transition: ${oneStep}ms linear;
`;
for (let i = 0; i < initAnimPoints; i++) {
Utils.timeout(Math.max(10, i * oneStep), () => {
if(!area) return;
area.css = `${initFrom != initTo ? 'font-size: ' + (initFrom + (transitionDistance / initAnimPoints * (i + 1))) + 'px;' : ''}`;
});
}
}
else area.css = 'font-size: 0px;';
extraSetup(area);
},
})
@@ -1,71 +0,0 @@
const { Gtk } = imports.gi;
const Lang = imports.lang;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
// min-height/min-width for height/width
// background-color/color for background/indicator color
// padding for pad of indicator
// font-size for selected index (0-based)
export const NavigationIndicator = ({count, vertical, ...props}) => Widget.DrawingArea({
...props,
setup: (area) => {
const styleContext = area.get_style_context();
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
area.set_size_request(width, height);
area.connect('draw', Lang.bind(area, (area, cr) => {
const styleContext = area.get_style_context();
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
// console.log('allocated width/height:', area.get_allocated_width(), '/', area.get_allocated_height())
area.set_size_request(width, height);
const paddingLeft = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const paddingRight = styleContext.get_padding(Gtk.StateFlags.NORMAL).right;
const paddingTop = styleContext.get_padding(Gtk.StateFlags.NORMAL).top;
const paddingBottom = styleContext.get_padding(Gtk.StateFlags.NORMAL).bottom;
const selectedCell = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
let cellWidth = width;
let cellHeight = height;
if (vertical) cellHeight /= count;
else cellWidth /= count;
const indicatorWidth = cellWidth - paddingLeft - paddingRight;
const indicatorHeight = cellHeight - paddingTop - paddingBottom;
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
cr.setLineWidth(2);
// Background
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
cr.rectangle(0, 0, width, height);
cr.fill();
// The indicator line
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
if (vertical) {
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
cr.stroke();
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
cr.fill();
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth / 2, Math.PI, 2 * Math.PI);
cr.fill();
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorHeight - indicatorWidth / 2, indicatorWidth / 2, 0, Math.PI);
cr.fill();
}
else {
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
cr.stroke();
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
cr.fill();
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorWidth - indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
}))
},
})
@@ -1,50 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
export const RoundedCorner = (place, props) => Widget.DrawingArea({
...props,
hpack: place.includes('left') ? 'start' : 'end',
vpack: place.includes('top') ? 'start' : 'end',
setup: (widget) => Utils.timeout(1, () => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
widget.set_size_request(r, r);
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
// const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
// const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
widget.set_size_request(r, r);
switch (place) {
case 'topleft':
cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
cr.lineTo(0, 0);
break;
case 'topright':
cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
cr.lineTo(r, 0);
break;
case 'bottomleft':
cr.arc(r, 0, r, Math.PI / 2, Math.PI);
cr.lineTo(0, r);
break;
case 'bottomright':
cr.arc(0, 0, r, 0, Math.PI / 2);
cr.lineTo(r, r);
break;
}
cr.closePath();
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
cr.fill();
// cr.setLineWidth(borderWidth);
// cr.setSourceRGBA(borderColor.red, borderColor.green, borderColor.blue, borderColor.alpha);
// cr.stroke();
}));
}),
});
@@ -1,49 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
export const AnimatedSlider = ({
className,
value,
...rest
}) => {
return Widget.DrawingArea({
className: `${className}`,
setup: (self) => {
self.connect('draw', Lang.bind(self, (self, cr) => {
const styleContext = self.get_style_context();
const allocatedWidth = self.get_allocated_width();
const allocatedHeight = self.get_allocated_height();
console.log(allocatedHeight, allocatedWidth)
const minWidth = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const minHeight = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const radius = styleContext.get_property('border-radius', Gtk.StateFlags.NORMAL);
const bg = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const fg = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
const value = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100;
self.set_size_request(-1, minHeight);
const width = allocatedHeight;
const height = minHeight;
cr.arc(radius, radius, radius, -1 * Math.PI, -0.5 * Math.PI); // Top-left
cr.arc(width - radius, radius, radius, -0.5 * Math.PI, 0); // Top-right
cr.arc(width - radius, height - radius, radius, 0, 0.5 * Math.PI); // Bottom-left
cr.arc(radius, height - radius, radius, 0.5 * Math.PI, 1 * Math.PI); // Bottom-right
cr.setSourceRGBA(bg.red, bg.green, bg.blue, bg.alpha);
cr.closePath();
cr.fill();
// const valueWidth = width * value;
// cr.arc(radius, radius, radius, -1 * Math.PI, -0.5 * Math.PI); // Top-left
// cr.arc(valueWidth - radius, radius, radius, -0.5 * Math.PI, 0); // Top-right
// cr.arc(valueWidth - radius, height - radius, radius, 0, 0.5 * Math.PI); // Bottom-left
// cr.arc(radius, height - radius, radius, 0.5 * Math.PI, 1 * Math.PI); // Bottom-right
// cr.setSourceRGBA(fg.red, fg.green, fg.blue, fg.alpha);
// cr.closePath();
// cr.fill();
}));
},
...rest,
})
}
@@ -1,23 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { monitors } from '../.commondata/hyprlanddata.js';
const { Box, EventBox } = Widget;
export const clickCloseRegion = ({ name, multimonitor = true, monitor = 0, expand = true, fillMonitor = '' }) => {
return EventBox({
child: Box({
expand: expand,
css: `
min-width: ${fillMonitor.includes('h') ? monitors[monitor].width : 0}px;
min-height: ${fillMonitor.includes('v') ? monitors[monitor].height : 0}px;
`,
}),
setup: (self) => self.on('button-press-event', (self, event) => { // Any mouse button
if (multimonitor) closeWindowOnAllMonitors(name);
else App.closeWindow(name);
}),
})
}
export default clickCloseRegion;
@@ -1,298 +0,0 @@
const { Gtk } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js';
import { setupCursorHover, setupCursorHoverHResize } from '../.widgetutils/cursorhover.js';
const { Box, Button, EventBox, Label, Revealer, SpinButton } = Widget;
// Basically M3 Switch
// https://m3.material.io/components/switch/overview
// onReset must be async
export const ConfigToggle = ({
icon, name, desc = '', initValue,
expandWidget = true, resetButton = false,
onChange = () => { }, extraSetup = () => { },
onReset = () => { }, fetchValue = () => { },
...rest
}) => {
const enabled = Variable(initValue);
const toggleIcon = Label({
className: `icon-material txt-bold ${enabled.value ? '' : 'txt-poof'}`,
label: `${enabled.value ? 'check' : ''}`,
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-fg-toggling-false', false);
if (!enabled.value) {
self.label = '';
self.toggleClassName('txt-poof', true);
}
else Utils.timeout(1, () => {
toggleIcon.label = 'check';
toggleIcon.toggleClassName('txt-poof', false);
})
}),
})
const toggleButtonIndicator = Box({
className: `switch-fg ${enabled.value ? 'switch-fg-true' : ''}`,
vpack: 'center',
hpack: 'start',
homogeneous: true,
children: [toggleIcon,],
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-fg-true', enabled.value);
}),
});
const toggleButton = Box({
hpack: 'end',
vpack: 'center',
className: `switch-bg ${enabled.value ? 'switch-bg-true' : ''}`,
homogeneous: true,
children: [toggleButtonIndicator],
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-bg-true', enabled.value);
}),
});
const widgetContent = Box({
tooltipText: desc,
className: 'txt spacing-h-5',
children: [
...(icon !== undefined ? [MaterialIcon(icon, 'norm', {vpack: 'center'})] : []),
...(name !== undefined ? [Label({
vpack: 'center',
className: 'txt txt-small',
label: name,
})] : []),
...(expandWidget ? [Box({ hexpand: true })] : []),
toggleButton,
]
});
const interactionWrapper = Button({
attribute: {
enabled: enabled,
toggle: (newValue) => {
enabled.value = !enabled.value;
onChange(interactionWrapper, enabled.value);
}
},
child: widgetContent,
onClicked: (self) => self.attribute.toggle(self),
onHoverLost: () => { // mouse away
toggleIcon.toggleClassName('switch-fg-toggling-false', false);
if (enabled.value) toggleIcon.toggleClassName('txt-poof', false);
},
setup: (self) => {
setupCursorHover(self);
self.connect('pressed', () => { // mouse down
toggleIcon.toggleClassName('txt-poof', true);
toggleIcon.toggleClassName('switch-fg-true', false);
if (!enabled.value) toggleIcon.toggleClassName('switch-fg-toggling-false', true);
});
extraSetup(self)
},
...rest,
});
const wholeThing = Box({
attribute: {
'enabled': enabled,
},
className: 'configtoggle-box spacing-h-5',
children: [
interactionWrapper,
...(resetButton ? [Button({
className: 'configtoggle-reset',
onClicked: (self) => {
onReset(self).then(() => {
enabled.value = fetchValue();
}).catch(print);
},
child: MaterialIcon('settings_backup_restore', 'small'),
setup: setupCursorHover,
})] : []),
]
});
wholeThing.enabled = enabled;
return wholeThing;
}
export const ConfigSegmentedSelection = ({
icon, name, desc = '',
options = [{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
initIndex = 0,
onChange,
...rest
}) => {
let lastSelected = initIndex;
let value = options[initIndex].value;
const widget = Box({
tooltipText: desc,
className: 'segment-container',
// homogeneous: true,
children: options.map((option, id) => {
const selectedIcon = Revealer({
revealChild: id == initIndex,
transition: 'slide_right',
transitionDuration: userOptions.animations.durationSmall,
child: MaterialIcon('check', 'norm')
});
return Button({
setup: setupCursorHover,
className: `segment-btn ${id == initIndex ? 'segment-btn-enabled' : ''}`,
child: Box({
hpack: 'center',
className: 'spacing-h-5',
children: [
selectedIcon,
Label({
label: option.name,
})
]
}),
onClicked: (self) => {
value = option.value;
const kids = widget.get_children();
kids[lastSelected].toggleClassName('segment-btn-enabled', false);
kids[lastSelected].get_children()[0].get_children()[0].revealChild = false;
lastSelected = id;
self.toggleClassName('segment-btn-enabled', true);
selectedIcon.revealChild = true;
onChange(option.value, option.name);
}
})
}),
...rest,
});
return widget;
}
export const ConfigMulipleSelection = ({
icon, name, desc = '',
optionsArr = [
[{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
[{ name: 'Option 3', value: 0 }, { name: 'Option 4', value: 1 }],
],
initIndex = [0, 0],
onChange,
...rest
}) => {
let lastSelected = initIndex;
const widget = Box({
tooltipText: desc,
className: 'multipleselection-container spacing-v-3',
vertical: true,
children: optionsArr.map((options, grp) => Box({
className: 'spacing-h-5',
hpack: 'center',
children: options.map((option, id) => Button({
setup: setupCursorHover,
className: `multipleselection-btn ${id == initIndex[1] && grp == initIndex[0] ? 'multipleselection-btn-enabled' : ''}`,
label: option.name,
onClicked: (self) => {
const kidsg = widget.get_children();
const kids = kidsg.flatMap(widget => widget.get_children());
kids.forEach(kid => {
kid.toggleClassName('multipleselection-btn-enabled', false);
});
lastSelected = id;
self.toggleClassName('multipleselection-btn-enabled', true);
onChange(option.value, option.name);
}
})),
})),
...rest,
});
return widget;
}
export const ConfigGap = ({ vertical = true, size = 5, ...rest }) => Box({
className: `gap-${vertical ? 'v' : 'h'}-${size}`,
...rest,
})
// Gtk SpinButton with value scrubbing gesture
// scrubRatio is the ratio of changed value to drag distance in pixels
// onReset must be async
export const ConfigSpinButton = ({
icon, name, desc = '', initValue,
minValue = 0, maxValue = 100, step = 1,
expandWidget = true, resetButton = false,
scrubRatio = 1 / 20, roundValue = true,
onChange = () => { }, extraSetup = () => { },
onReset = () => { }, fetchValue = () => { },
...rest
}) => {
let resetLock = false;
const value = Variable(initValue);
const spinButton = SpinButton({
className: 'spinbutton',
range: [minValue, maxValue],
increments: [step, step],
onValueChanged: ({ value: newValue }) => {
if (resetLock) return;
value.value = newValue;
onChange(spinButton, newValue);
},
// This funny line means: set value of the spinbutton to the value of the
// Variable object called value that tracks the value of the widget
value: value.value,
});
const widgetContent = Box({
tooltipText: desc,
className: 'txt spacing-h-5 configtoggle-box',
children: [
...(icon !== undefined ? [MaterialIcon(icon, 'norm')] : []),
...(name !== undefined ? [Label({
className: 'txt txt-small',
label: name,
})] : []),
...(expandWidget ? [Box({ hexpand: true })] : []),
spinButton,
...(resetButton ? [Button({
className: 'spinbutton-reset',
onClicked: (self) => {
onReset(self).then(() => {
resetLock = true;
const newValue = fetchValue();
spinButton.value = newValue;
value.value = newValue;
resetLock = false;
}).catch(print);
},
child: MaterialIcon('settings_backup_restore', 'small'),
setup: setupCursorHover,
})] : []),
],
setup: (self) => {
extraSetup(self);
},
...rest,
});
const interactionWrapper = EventBox({
child: widgetContent,
setup: setupCursorHoverHResize,
})
const gesture = Gtk.GestureDrag.new(interactionWrapper);
let gestureValueOnDragBegin;
const wholeThing = Box({
children: [interactionWrapper],
setup: (self) => self
.hook(gesture, (self) => {
gestureValueOnDragBegin = value.value;
}, 'drag-begin')
.hook(gesture, (self) => {
var offset_x = gesture.get_offset()[1];
var offset_y = gesture.get_offset()[2];
let newValue = gestureValueOnDragBegin + (offset_x * scrubRatio);
if (roundValue) newValue = Math.round(newValue);
if (newValue !== spinButton.value) {
spinButton.value = newValue;
}
}, 'drag-update')
.hook(gesture, (self) => {
}, 'drag-end')
});
wholeThing.enabled = value;
return wholeThing;
}
@@ -1,154 +0,0 @@
const { GLib } = imports.gi;
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
import { getNestedProperty, updateNestedProperty } from "../.miscutils/objects.js";
import { ConfigSpinButton, ConfigToggle } from "./configwidgets.js";
const AGS_CONFIG_FILE = `${App.configDir}/user_options.jsonc`;
const HYPRLAND_CONFIG_FILE = `${GLib.get_user_config_dir()}/hypr/custom/general.conf`;
export const AgsToggle = ({
icon, name, desc = null,
option, resetButton = true, save = true,
extraOnChange = () => { }, extraOnReset = () => { },
...rest
}) => ConfigToggle({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${AGS_CONFIG_FILE}`,
resetButton: resetButton,
initValue: getNestedProperty(userOptions, option),
fetchValue: () => getNestedProperty(userOptions, option),
onChange: (self, newValue) => {
updateNestedProperty(userOptions, option, newValue);
if (save) execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--value ${newValue} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
extraOnChange(self, newValue);
},
onReset: async (self) => {
updateNestedProperty(userOptions, option,
getNestedProperty(userOptionsDefaults, option));
if (save) exec(`bash -c '${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--reset \
--file ${AGS_CONFIG_FILE}'`);
extraOnReset(self);
},
...rest
});
export const AgsSpinButton = ({
icon, name, desc = null,
option, resetButton = true,
save = true, extraOnChange = () => { }, extraOnReset = () => { },
...rest
}) => ConfigSpinButton({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${AGS_CONFIG_FILE}`,
resetButton: resetButton,
initValue: getNestedProperty(userOptions, option),
fetchValue: () => getNestedProperty(userOptions, option),
step: 10, minValue: 0, maxValue: 1000,
onChange: (self, newValue) => {
updateNestedProperty(userOptions, option, newValue);
if (save) execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--value ${newValue} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
extraOnChange(self, newValue);
},
onReset: async () => {
updateNestedProperty(userOptions, option,
getNestedProperty(userOptionsDefaults, option));
if (save) exec(`bash -c '${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--reset \
--file ${AGS_CONFIG_FILE}'`);
extraOnReset(self);
},
...rest,
});
export const HyprlandToggle = ({
icon, name, desc = null,
option, resetButton = true,
enableValue = 1, disableValue = 0,
extraOnChange = () => { }, extraOnReset = () => { }, save = true
}) => ConfigToggle({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${HYPRLAND_CONFIG_FILE}`,
resetButton: resetButton,
initValue: JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"] != 0,
fetchValue: () => JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"] != 0,
onChange: (self, newValue) => {
if (save)
execAsync(['bash', '-c', `${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--value ${newValue ? enableValue : disableValue} \
--file ${HYPRLAND_CONFIG_FILE}`
]).catch(print);
else
execAsync(['hyprctl', 'keyword', option, `${newValue ? enableValue : disableValue}`]).catch(print);
extraOnChange(self, newValue);
},
onReset: async (self) => {
if (save)
exec(`bash -c '${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--reset \
--file "${HYPRLAND_CONFIG_FILE}"'`);
else
exec('hyprctl reload');
extraOnReset(self);
},
});
export const HyprlandSpinButton = ({
icon, name, desc = null,
option, resetButton = true, save = true,
extraOnChange = () => { }, extraOnReset = () => { },
...rest
}) => ConfigSpinButton({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${HYPRLAND_CONFIG_FILE}`,
resetButton: resetButton,
initValue: Number(JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"]),
fetchValue: () => Number(JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"]),
onChange: (self, newValue) => {
if (save)
execAsync(['bash', '-c', `${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--value ${newValue} \
--file ${HYPRLAND_CONFIG_FILE}`
]).catch(print);
else
execAsync(['hyprctl', 'keyword', option, `${newValue}`]).catch(print);
extraOnChange(self, newValue);
},
onReset: async (self) => {
if (save)
exec(`bash -c '${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--reset \
--file "${HYPRLAND_CONFIG_FILE}"'`);
else
exec('hyprctl reload');
extraOnReset(self);
},
...rest,
});
@@ -1,7 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
export const MaterialIcon = (icon, size, props = {}) => Widget.Label({
className: `icon-material txt-${size}`,
label: icon,
...props,
})
@@ -1,505 +0,0 @@
// This file is for the actual widget for each single notification
const { GLib, Gdk, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
const { Box, EventBox, Icon, Overlay, Label, Button, Revealer } = Widget;
import { MaterialIcon } from './materialicon.js';
import { setupCursorHover } from "../.widgetutils/cursorhover.js";
import { AnimatedCircProg } from "./cairo_circularprogress.js";
function guessMessageType(summary) {
const keywordsToTypes = {
'reboot': 'restart_alt',
'recording': 'screen_record',
'battery': 'power',
'power': 'power',
'screenshot': 'screenshot_monitor',
'welcome': 'waving_hand',
'time': 'scheduleb',
'installed': 'download',
'update': 'update',
'ai response': 'neurology',
'startswith:file': 'folder_copy', // Declarative startsWith check
};
const lowerSummary = summary.toLowerCase();
for (const [keyword, type] of Object.entries(keywordsToTypes)) {
if (keyword.startsWith('startswith:')) {
const startsWithKeyword = keyword.replace('startswith:', '');
if (lowerSummary.startsWith(startsWithKeyword)) {
return type;
}
} else if (lowerSummary.includes(keyword)) {
return type;
}
}
return 'chat';
}
function processNotificationBody(body, appEntry) {
// Only process Chrome/Chromium notifications
if (appEntry?.toLowerCase().includes('chrome')) {
// Remove the first line
return body.split('\n\n').slice(1).join('\n\n');
}
return body;
}
const getFriendlyNotifTimeString = (timeObject) => {
const messageTime = GLib.DateTime.new_from_unix_local(timeObject);
const oneMinuteAgo = GLib.DateTime.new_now_local().add_seconds(-60);
if (messageTime.compare(oneMinuteAgo) > 0)
return getString('Now');
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year())
return messageTime.format(userOptions.time.format);
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1)
return getString('Yesterday');
else
return messageTime.format(userOptions.time.dateFormat);
}
const NotificationIcon = (notifObject) => {
if (notifObject.hints?.image_path?.deepUnpack) {
const imagePath = notifObject.hints.image_path.deepUnpack();
return Box({
valign: Gtk.Align.CENTER,
hexpand: false,
className: 'notif-icon',
css: `
background-image: url("${imagePath}");
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center;
`,
});
}
if (notifObject.image) {
return Box({
valign: Gtk.Align.CENTER,
hexpand: false,
className: 'notif-icon',
css: `
background-image: url("${notifObject.image}");
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center;
`,
});
}
let icon = 'NO_ICON';
if (Utils.lookUpIcon(notifObject.appIcon))
icon = notifObject.appIcon;
if (Utils.lookUpIcon(notifObject.appEntry))
icon = notifObject.appEntry;
return Box({
vpack: 'center',
hexpand: false,
className: `notif-icon notif-icon-material-${notifObject.urgency}`,
homogeneous: true,
children: [
(icon != 'NO_ICON' ?
Icon({
vpack: 'center',
icon: icon,
})
:
MaterialIcon(`${notifObject.urgency == 'critical' ? 'release_alert' : guessMessageType(notifObject.summary.toLowerCase())}`, 'hugerass', {
hexpand: true,
})
)
],
});
};
export default ({
notifObject,
isPopup = false,
props = {},
} = {}) => {
const popupTimeout = notifObject.timeout || (notifObject.urgency == 'critical' ? 8000 : 3000);
const command = (isPopup ?
() => notifObject.dismiss() :
() => notifObject.close()
)
const destroyWithAnims = () => {
widget.sensitive = false;
notificationBox.setCss(middleClickClose);
Utils.timeout(userOptions.animations.durationSmall, () => {
if (wholeThing) wholeThing.revealChild = false;
}, wholeThing);
Utils.timeout(userOptions.animations.durationSmall * 2, () => {
command();
if (wholeThing) {
wholeThing.destroy();
wholeThing = null;
}
}, wholeThing);
}
const widget = EventBox({
onHover: (self) => {
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
if (!wholeThing.attribute.hovered)
wholeThing.attribute.hovered = true;
},
onHoverLost: (self) => {
self.window.set_cursor(null);
if (wholeThing.attribute.hovered)
wholeThing.attribute.hovered = false;
if (isPopup) {
command();
}
},
onMiddleClick: (self) => {
destroyWithAnims();
},
onSecondaryClick: (self) => {
expanded = !expanded;
notifTextPreview.revealChild = !expanded;
notifTextExpanded.revealChild = expanded;
notifExpandButton.child.label = `expand_${expanded ? 'less' : 'more'}`;
},
setup: (self) => {
self.on("button-press-event", () => {
wholeThing.attribute.held = true;
notificationContent.toggleClassName(`${isPopup ? 'popup-' : ''}notif-clicked-${notifObject.urgency}`, true);
Utils.timeout(800, () => {
if (wholeThing?.attribute.held) {
Utils.execAsync(['wl-copy', `${notifObject.body}`]).catch(print);
notifTextSummary.label = notifObject.summary + " (copied)";
Utils.timeout(3000, () => notifTextSummary.label = notifObject.summary)
}
})
}).on("button-release-event", () => {
wholeThing.attribute.held = false;
notificationContent.toggleClassName(`${isPopup ? 'popup-' : ''}notif-clicked-${notifObject.urgency}`, false);
})
}
});
let wholeThing = Revealer({
attribute: {
'close': undefined,
'destroyWithAnims': destroyWithAnims,
'dragging': false,
'held': false,
'hovered': false,
'id': notifObject.id,
},
revealChild: false,
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: Box({ // Box to make sure css-based spacing works
homogeneous: true,
}),
});
const display = Gdk.Display.get_default();
const notifTextPreview = Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationSmall,
revealChild: true,
child: Label({
xalign: 0,
className: `txt-smallie notif-body-${notifObject.urgency}`,
useMarkup: true,
xalign: 0,
justify: Gtk.Justification.LEFT,
maxWidthChars: 1,
truncate: 'end',
label: processNotificationBody(notifObject.body, notifObject.appEntry).split("\n")[0]
}),
});
const notifTextExpanded = Revealer({
transition: 'slide_up',
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
child: Box({
vertical: true,
className: 'spacing-v-10',
children: [
Label({
xalign: 0,
className: `txt-smallie notif-body-${notifObject.urgency}`,
useMarkup: true,
xalign: 0,
justify: Gtk.Justification.LEFT,
maxWidthChars: 1,
wrap: true,
label: processNotificationBody(notifObject.body, notifObject.appEntry)
}),
Box({
className: 'notif-actions spacing-h-5',
children: [
Button({
hexpand: true,
className: `notif-action notif-action-${notifObject.urgency}`,
onClicked: () => destroyWithAnims(),
setup: setupCursorHover,
child: Label({
label: getString('Close'),
}),
}),
...notifObject.actions.map(action => Widget.Button({
hexpand: true,
className: `notif-action notif-action-${notifObject.urgency}`,
onClicked: () => notifObject.invoke(action.id),
setup: setupCursorHover,
child: Label({
label: action.label,
}),
}))
],
})
]
}),
});
const notifIcon = Box({
vpack: 'start',
homogeneous: true,
children: [
Overlay({
child: NotificationIcon(notifObject),
overlays: isPopup ? [AnimatedCircProg({
className: `notif-circprog-${notifObject.urgency}`,
vpack: 'center', hpack: 'center',
initFrom: (isPopup ? 100 : 0),
initTo: 0,
initAnimTime: popupTimeout,
})] : [],
}),
]
});
const notifTextSummary = Label({
xalign: 0,
className: 'txt-small txt-semibold titlefont',
justify: Gtk.Justification.LEFT,
hexpand: true,
maxWidthChars: 1,
truncate: 'end',
ellipsize: 3,
useMarkup: notifObject.summary.startsWith('<'),
label: notifObject.summary,
});
const initTimeString = getFriendlyNotifTimeString(notifObject.time);
const notifTextBody = Label({
vpack: 'center',
justification: 'right',
className: 'txt-smaller txt-semibold',
label: initTimeString,
setup: initTimeString == 'Now' ? (self) => {
let id = Utils.timeout(60000, () => {
self.label = getFriendlyNotifTimeString(notifObject.time);
id = null;
});
self.connect('destroy', () => { if (id) GLib.source_remove(id) });
} : () => { },
});
const notifText = Box({
valign: Gtk.Align.CENTER,
vertical: true,
hexpand: true,
children: [
Box({
children: [
notifTextSummary,
notifTextBody,
]
}),
notifTextPreview,
notifTextExpanded,
]
});
const notifExpandButton = Button({
vpack: 'start',
className: 'notif-expand-btn',
onClicked: (self) => {
if (notifTextPreview.revealChild) { // Expanding...
notifTextPreview.revealChild = false;
notifTextExpanded.revealChild = true;
self.child.label = 'expand_less';
expanded = true;
}
else {
notifTextPreview.revealChild = true;
notifTextExpanded.revealChild = false;
self.child.label = 'expand_more';
expanded = false;
}
},
child: MaterialIcon('expand_more', 'norm', {
vpack: 'center',
}),
setup: setupCursorHover,
});
const notificationContent = Box({
...props,
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
children: [
notifIcon,
Box({
className: 'spacing-h-5',
children: [
notifText,
notifExpandButton,
]
})
]
})
// Gesture stuff
const gesture = Gtk.GestureDrag.new(widget);
var initDirX = 0;
var initDirVertical = -1; // -1: unset, 0: horizontal, 1: vertical
var expanded = false;
// in px
const startMargin = 0;
const MOVE_THRESHOLD = 10;
const DRAG_CONFIRM_THRESHOLD = 100;
// in rem
const maxOffset = 10.227;
const endMargin = 20.455;
const disappearHeight = 6.818;
const leftAnim1 = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: -${Number(maxOffset + endMargin)}rem;
margin-right: ${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const rightAnim1 = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: ${Number(maxOffset + endMargin)}rem;
margin-right: -${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const middleClickClose = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.85, 0, 0.15, 1);
margin-left: ${Number(maxOffset + endMargin)}rem;
margin-right: -${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const notificationBox = Box({
attribute: {
'leftAnim1': leftAnim1,
'rightAnim1': rightAnim1,
'middleClickClose': middleClickClose,
'ready': false,
},
homogeneous: true,
children: [notificationContent],
setup: (self) => self
.hook(gesture, self => {
var offset_x = gesture.get_offset()[1];
var offset_y = gesture.get_offset()[2];
// Which dir?
if (initDirVertical == -1) {
if (Math.abs(offset_y) > MOVE_THRESHOLD)
initDirVertical = 1;
if (initDirX == 0 && Math.abs(offset_x) > MOVE_THRESHOLD) {
initDirVertical = 0;
initDirX = (offset_x > 0 ? 1 : -1);
}
}
// Horizontal drag
if (initDirVertical == 0 && offset_x > MOVE_THRESHOLD) {
if (initDirX < 0)
self.setCss(`margin-left: 0px; margin-right: 0px;`);
else
self.setCss(`
margin-left: ${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
margin-right: -${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
`);
}
else if (initDirVertical == 0 && offset_x < -MOVE_THRESHOLD) {
if (initDirX > 0)
self.setCss(`margin-left: 0px; margin-right: 0px;`);
else {
offset_x = Math.abs(offset_x);
self.setCss(`
margin-right: ${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
margin-left: -${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
`);
}
}
// Update dragging
wholeThing.attribute.dragging = Math.abs(offset_x) > MOVE_THRESHOLD;
if (Math.abs(offset_x) > MOVE_THRESHOLD ||
Math.abs(offset_y) > MOVE_THRESHOLD) wholeThing.attribute.held = false;
widget.window?.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
// Vertical drag
if (initDirVertical == 1 && offset_y > MOVE_THRESHOLD && !expanded) {
notifTextPreview.revealChild = false;
notifTextExpanded.revealChild = true;
expanded = true;
notifExpandButton.child.label = 'expand_less';
}
else if (initDirVertical == 1 && offset_y < -MOVE_THRESHOLD && expanded) {
notifTextPreview.revealChild = true;
notifTextExpanded.revealChild = false;
expanded = false;
notifExpandButton.child.label = 'expand_more';
}
}, 'drag-update')
.hook(gesture, self => {
if (!self.attribute.ready) {
wholeThing.revealChild = true;
self.attribute.ready = true;
return;
}
const offset_h = gesture.get_offset()[1];
if (Math.abs(offset_h) > DRAG_CONFIRM_THRESHOLD && offset_h * initDirX > 0) {
if (offset_h > 0) {
self.setCss(rightAnim1);
widget.sensitive = false;
}
else {
self.setCss(leftAnim1);
widget.sensitive = false;
}
Utils.timeout(userOptions.animations.durationSmall, () => {
if (wholeThing) wholeThing.revealChild = false;
}, wholeThing);
Utils.timeout(userOptions.animations.durationSmall * 2, () => {
command();
if (wholeThing) {
wholeThing.destroy();
wholeThing = null;
}
}, wholeThing);
}
else {
self.setCss(`transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1), opacity ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: ${startMargin}px;
margin-right: ${startMargin}px;
margin-bottom: unset; margin-top: unset;
opacity: 1;`);
if (widget.window)
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
wholeThing.attribute.dragging = false;
}
initDirX = 0;
initDirVertical = -1;
}, 'drag-end')
,
})
widget.add(notificationBox);
wholeThing.child.children = [widget];
if (isPopup) Utils.timeout(popupTimeout, () => {
if (wholeThing && !wholeThing.attribute.hovered) {
wholeThing.revealChild = false;
Utils.timeout(userOptions.animations.durationSmall, () => {
if (wholeThing) {
wholeThing.destroy();
wholeThing = null;
}
command();
}, wholeThing);
}
})
return wholeThing;
}
@@ -1,316 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js';
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
import { languages } from './statusicons_languages.js';
// A guessing func to try to support langs not listed in data/languages.js
function isLanguageMatch(abbreviation, word) {
const lowerAbbreviation = abbreviation.toLowerCase();
const lowerWord = word.toLowerCase();
let j = 0;
for (let i = 0; i < lowerWord.length; i++) {
if (lowerWord[i] === lowerAbbreviation[j]) {
j++;
}
if (j === lowerAbbreviation.length) {
return true;
}
}
return false;
}
export const MicMuteIndicator = () => Widget.Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
setup: (self) => self.hook(Audio, (self) => {
self.revealChild = Audio.microphone?.stream?.isMuted;
}),
child: MaterialIcon('mic_off', 'norm'),
});
export const NotificationIndicator = (notifCenterName = 'sideright') => {
const widget = Widget.Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
setup: (self) => self
.hook(Notifications, (self, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
self.revealChild = true;
}, 'notified')
.hook(App, (self, currentName, visible) => {
if (visible && currentName === notifCenterName) {
self.revealChild = false;
}
})
,
child: Widget.Box({
children: [
MaterialIcon('notifications', 'norm'),
Widget.Label({
className: 'txt-small titlefont',
attribute: {
unreadCount: 0,
update: (self) => self.label = `${self.attribute.unreadCount}`,
},
setup: (self) => self
.hook(Notifications, (self, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
self.attribute.unreadCount++;
self.attribute.update(self);
}, 'notified')
.hook(App, (self, currentName, visible) => {
if (visible && currentName === notifCenterName) {
self.attribute.unreadCount = 0;
self.attribute.update(self);
}
})
,
})
]
})
});
return widget;
}
export const BluetoothIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'disabled': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_disabled' }),
'enabled': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth' }),
'connected': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_connected' }),
},
setup: (self) =>
self.hook(Bluetooth, (stack) => {
if (!Bluetooth.enabled) {
stack.shown = 'disabled';
} else if (Bluetooth.connected_devices.length === 0) {
stack.shown = 'enabled';
} else if (Bluetooth.connected_devices.length > 0) {
stack.shown = 'connected';
}
}),
});
const BluetoothDevices = () => Widget.Box({
className: 'spacing-h-5',
setup: self => self.hook(Bluetooth, self => {
self.children = Bluetooth.connected_devices.map((device) => {
return Widget.Box({
className: 'bar-bluetooth-device spacing-h-5',
vpack: 'center',
tooltipText: device.name,
children: [
Widget.Icon(`${device.iconName}-symbolic`),
...(device.batteryPercentage ? [Widget.Label({
className: 'txt-smallie',
label: `${device.batteryPercentage}`,
setup: (self) => {
self.hook(device, (self) => {
self.label = `${device.batteryPercentage}`;
}, 'notify::batteryPercentage')
}
})] : []),
]
});
});
self.visible = Bluetooth.connected_devices.length > 0;
}, 'notify::connected-devices'),
})
const NetworkWiredIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'fallback': SimpleNetworkIndicator(),
'unknown': Widget.Label({ className: 'txt-norm icon-material', label: 'wifi_off' }),
'disconnected': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' }),
'connected': Widget.Label({ className: 'txt-norm icon-material', label: 'lan' }),
'connecting': Widget.Label({ className: 'txt-norm icon-material', label: 'settings_ethernet' }),
},
setup: (self) => self.hook(Network, stack => {
if (!Network.wired)
return;
const { internet } = Network.wired;
if (['connecting', 'connected'].includes(internet))
stack.shown = internet;
else if (Network.connectivity !== 'full')
stack.shown = 'disconnected';
else
stack.shown = 'fallback';
}),
});
const SimpleNetworkIndicator = () => Widget.Icon({
setup: (self) => self.hook(Network, self => {
const icon = Network[Network.primary || 'wifi']?.iconName;
self.icon = icon || '';
self.visible = icon;
}),
});
const NetworkWifiIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'disabled': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' }),
'disconnected': Widget.Label({
className: 'txt-norm icon-material',
label: 'signal_wifi_statusbar_not_connected',
}),
'connecting': Widget.Label({ className: 'txt-norm icon-material', label: 'settings_ethernet' }),
'0': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_0_bar' }),
'1': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_1_bar' }),
'2': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_2_bar' }),
'3': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_3_bar' }),
'4': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_4_bar' }),
},
setup: (self) => self.hook(Network, (stack) => {
if (!Network.wifi) {
return;
}
if (!Network.wifi.enabled) {
stack.shown = 'disabled';
} else if (Network.wifi.internet == 'connected') {
stack.shown = String(Math.ceil(Network.wifi.strength / 25));
} else if (['disconnected', 'connecting'].includes(Network.wifi.internet)) {
stack.shown = Network.wifi.internet;
}
}),
});
export const NetworkIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'fallback': SimpleNetworkIndicator(),
'wifi': NetworkWifiIndicator(),
'wired': NetworkWiredIndicator(),
},
setup: (self) => self.hook(Network, stack => {
if (!Network.primary) {
stack.shown = 'wifi';
return;
}
const primary = Network.primary || 'fallback';
if (['wifi', 'wired'].includes(primary))
stack.shown = primary;
else
stack.shown = 'fallback';
}),
});
const HyprlandXkbKeyboardLayout = async ({ useFlag } = {}) => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
var languageStackArray = [];
const updateCurrentKeyboards = () => {
var initLangs = [];
JSON.parse(Utils.exec('hyprctl -j devices')).keyboards
.forEach(keyboard => {
initLangs.push(...keyboard.layout.split(',').map(lang => lang.trim()));
});
initLangs = [...new Set(initLangs)];
languageStackArray = Array.from({ length: initLangs.length }, (_, i) => {
const lang = languages.find(lang => lang.layout == initLangs[i]);
// if (!lang) return [
// initLangs[i],
// Widget.Label({ label: initLangs[i] })
// ];
// return [
// lang.layout,
// Widget.Label({ label: (useFlag ? lang.flag : lang.layout) })
// ];
// Object
if (!lang) return {
[initLangs[i]]: Widget.Label({ label: initLangs[i] })
};
return {
[lang.layout]: Widget.Label({ label: (useFlag ? lang.flag : lang.layout) })
};
});
};
updateCurrentKeyboards();
const widgetRevealer = Widget.Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationSmall,
revealChild: languageStackArray.length > 1,
});
const widgetKids = {
...languageStackArray.reduce((obj, lang) => {
return { ...obj, ...lang };
}, {}),
'undef': Widget.Label({ label: '?' }),
}
const widgetContent = Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: widgetKids,
setup: (self) => self.hook(Hyprland, (stack, kbName, layoutName) => {
if (!kbName) {
return;
}
var lang = languages.find(lang => layoutName.includes(lang.name));
if (lang) {
widgetContent.shown = lang.layout;
}
else { // Attempt to support langs not listed
lang = languageStackArray.find(lang => isLanguageMatch(lang[0], layoutName));
if (!lang) stack.shown = 'undef';
else stack.shown = lang[0];
}
}, 'keyboard-layout'),
});
widgetRevealer.child = widgetContent;
return widgetRevealer;
} catch {
return null;
}
}
const OptionalKeyboardLayout = async () => {
try {
return await HyprlandXkbKeyboardLayout({ useFlag: userOptions.appearance.keyboardUseFlag });
} catch {
return null;
}
};
const createKeyboardLayoutInstances = async () => {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
const monitorsCount = Hyprland.monitors.length
const instances = await Promise.all(
Array.from({ length: monitorsCount }, () => OptionalKeyboardLayout())
);
return instances;
};
const optionalKeyboardLayoutInstances = await createKeyboardLayoutInstances()
export const StatusIcons = (props = {}, monitor = 0) => Widget.Box({
...props,
child: Widget.Box({
className: 'spacing-h-15',
children: [
MicMuteIndicator(),
optionalKeyboardLayoutInstances[monitor],
NotificationIndicator(),
NetworkIndicator(),
Widget.Box({
className: 'spacing-h-5',
children: [BluetoothIndicator(), BluetoothDevices()]
})
]
})
});
@@ -1,62 +0,0 @@
// For keyboard layout in statusicons.js
// This list is not exhaustive. It just includes known/possible languages of users of my dotfiles
// Add your language here if you use multi-lang xkb input. Else, ignore
// Note that something like "French (Canada)" should go before "French"
// and "English (US)" should go before "English"
export const languages = [
{
layout: 'us',
name: 'English (US)',
flag: '🇺🇸'
},
{
layout: 'ru',
name: 'Russian',
flag: '🇷🇺',
},
{
layout: 'pl',
name: 'Polish',
flag: '🇷🇵🇵🇱',
},
{
layout: 'ro',
name: 'Romanian',
flag: '🇷🇴',
},
{
layout: 'ca',
name: 'French (Canada)',
flag: '🇫🇷',
},
{
layout: 'fr',
name: 'French',
flag: '🇫🇷',
},
{
layout: 'tr',
name: 'Turkish',
flag: '🇹🇷',
},
{
layout: 'jp',
name: 'Japanese',
flag: '🇯🇵',
},
{
layout: 'cn',
name: 'Chinese',
flag: '🇨🇳',
},
{
layout: 'vn',
name: 'Vietnamese',
flag: '🇻🇳',
},
{
layout: 'undef',
name: 'Undefined',
flag: '🧐',
},
]
@@ -1,299 +0,0 @@
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Button, EventBox, Label, Overlay, Stack } = Widget;
import { MaterialIcon } from './materialicon.js';
import { NavigationIndicator } from './cairo_navigationindicator.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { DoubleRevealer } from '../.widgethacks/advancedrevealers.js';
export const TabContainer = ({
icons, names, children, initIndex = 0,
className = '', setup = () => { },
onChange = () => { },
extraTabStripWidgets = [],
...rest
}) => {
const shownIndex = Variable(initIndex);
let previousShownIndex = 0;
const count = Math.min(icons.length, names.length, children.length);
const tabs = Box({
homogeneous: true,
children: Array.from({ length: count }, (_, i) => Button({ // Tab button
className: 'tab-btn',
onClicked: () => shownIndex.value = i,
setup: setupCursorHover,
child: Box({
hpack: 'center',
vpack: 'center',
className: 'spacing-h-5 txt-small',
children: [
MaterialIcon(icons[i], 'norm'),
Label({
label: names[i],
})
]
})
})),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleClassName('tab-btn-active', false);
self.children[shownIndex.value].toggleClassName('tab-btn-active', true);
previousShownIndex = shownIndex.value;
}),
});
const tabIndicatorLine = Box({
vertical: true,
homogeneous: true,
setup: (self) => self.hook(shownIndex, (self) => {
self.children[0].css = `font-size: ${shownIndex.value}px;`;
}),
children: [NavigationIndicator({
className: 'tab-indicator',
count: count,
css: `font-size: ${shownIndex.value}px;`,
})],
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
className: 'spacing-h-5',
children: [
Box({
vertical: true,
hexpand: true,
children: [
tabs,
tabIndicatorLine
]
}),
...extraTabStripWidgets,
]
})
})]
});
shownIndex.setValue(initIndex)
const contentStack = Stack({
transition: 'slide_left_right',
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
return mainBox;
}
export const IconTabContainer = ({
iconWidgets, names, children, className = '',
initIndex = 0,
setup = () => { }, onChange = () => { },
tabsHpack = 'center', tabSwitcherClassName = '',
...rest
}) => {
const shownIndex = Variable(initIndex);
let previousShownIndex = 0;
const count = Math.min(iconWidgets.length, names.length, children.length);
const tabs = Box({
hpack: tabsHpack,
className: `spacing-h-5 ${tabSwitcherClassName}`,
children: iconWidgets.map((icon, i) => Button({
className: 'tab-icon',
tooltipText: names[i],
child: icon,
setup: setupCursorHover,
onClicked: () => shownIndex.value = i,
})),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleClassName('tab-icon-active', false);
self.children[shownIndex.value].toggleClassName('tab-icon-active', true);
previousShownIndex = shownIndex.value;
}),
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
vertical: true,
hexpand: true,
children: [
tabs,
]
})
})]
});
const contentStack = Stack({
transition: 'slide_left_right',
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
mainBox.shown = shownIndex;
return mainBox;
}
export const ExpandingIconTabContainer = ({
icons, names, children, className = '',
setup = () => { }, onChange = () => { },
tabsHpack = 'center', tabSwitcherClassName = '',
transitionDuration = userOptions.animations.durationLarge,
...rest
}) => {
const shownIndex = Variable(0);
let previousShownIndex = 0;
const count = Math.min(icons.length, names.length, children.length);
const tabs = Box({
hpack: tabsHpack,
className: `spacing-h-5 ${tabSwitcherClassName}`,
children: icons.map((icon, i) => {
const tabIcon = MaterialIcon(icon, 'norm', { hexpand: true });
const tabName = DoubleRevealer({
transition1: 'slide_right',
transition2: 'crossfade',
duration1: 0,
duration2: 0,
// duration1: userOptions.animations.durationSmall,
// duration2: userOptions.animations.durationSmall,
child: Label({
className: 'margin-left-5 txt-small',
label: names[i],
}),
revealChild: i === shownIndex.value,
})
const button = Button({
className: 'tab-icon-expandable',
tooltipText: names[i],
child: Box({
homogeneous: true,
children: [Box({
hpack: 'center',
children: [
tabIcon,
tabName,
]
})],
}),
setup: setupCursorHover,
onClicked: () => shownIndex.value = i,
});
button.toggleFocus = (value) => {
tabIcon.hexpand = !value;
button.toggleClassName('tab-icon-expandable-active', value);
tabName.toggleRevealChild(value);
}
return button;
}),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleFocus(false);
self.children[shownIndex.value].toggleFocus(true);
previousShownIndex = shownIndex.value;
}),
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
vertical: true,
hexpand: true,
children: [
tabs,
]
})
})]
});
const contentStack = Stack({
transition: 'slide_left_right',
transitionDuration: transitionDuration,
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
mainBox.focusName = (name) => {
const focusIndex = names.indexOf(name);
if (focusIndex !== -1) {
shownIndex.value = focusIndex;
}
}
mainBox.shown = shownIndex;
return mainBox;
}
@@ -1,290 +0,0 @@
// This file is parsed with a custom JSONC parser.
// Don't expect every JSONC feature in... say, vscode, to work.
{
// General stuff
"ai": {
"defaultGPTProvider": "ollama_llama_3_2",
"defaultTemperature": 0.5,
"enhancements": true,
"charsEachUpdate": 50, // Lower = smoother update rate, but more update lag
"keep_alive": -1, // For ollama. -1 means forever
"useHistory": false,
"safety": true,
"writingCursor": " ...", // Warning: Using weird characters can mess up Markdown rendering
"proxyUrl": null, // Can be "socks5://127.0.0.1:9050" or "http://127.0.0.1:8080" for example. Leave it blank if you don't need it.
"extraGptModels": {
// Below is an example. Copy to user_options.jsonc and edit it
// The base url is conveniently ollama's btw
// "model_id": {
// "name": "User-added model",
// "logo_name": "ollama-symbolic",
// "description": "A model added by the user",
// "base_url": "http://localhost:11434/v1/chat/completions",
// "key_get_url": "",
// "requires_key": false,
// "key_file": "api_key_file.txt",
// "model": "model-name"
// },
}
},
"animations": {
"choreographyDelay": 35,
"durationSmall": 110,
"durationLarge": 180
},
"appearance": {
"autoDarkMode": { // Turns on dark mode in certain hours. Time in 24h format
"enabled": false,
"from": "18:10",
"to": "6:10"
},
"borderless": false, // Uhm experimental...
"keyboardUseFlag": false, // Use flag emoji instead of abbreviation letters
"layerSmoke": false,
"layerSmokeStrength": 0.2,
"barRoundCorners": 1, // 0: No, 1: Yes
"fakeScreenRounding": 2 // 0: None | 1: Always | 2: When not fullscreen
},
"apps": {
"bluetooth": "blueberry",
"imageViewer": "loupe",
"network": "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center wifi",
"settings": "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center",
"taskManager": "gnome-usage",
"terminal": "foot" // This is only for shell actions
},
"bar": {
// Whether to show Swap and CPU usage when there's media. RAM is always shown.
"alwaysShowFullResources": false,
// Array of bar modes for each monitor. Hit Ctrl+Alt+Slash to cycle.
// Modes: "normal", "focus" (workspace indicator only), "nothing"
// Example for four monitors: ["normal", "focus", "normal", "nothing"]
"modes": [
"normal"
]
},
"battery": {
"low": 20,
"critical": 10,
"warnLevels": [
20,
15,
5
],
"warnTitles": [
"Low battery",
"Very low battery",
"Critical Battery"
],
"warnMessages": [
"Plug in the charger",
"You there?",
"PLUG THE CHARGER ALREADY"
],
"suspendThreshold": 3
},
"brightness": {
// Object of controller names for each monitor, either "brightnessctl" or "ddcutil" or "auto"
// "default" one will be used if unspecified
// Examples
// "eDP-1": "brightnessctl",
// "DP-1": "ddcutil",
"controllers": {
"default": "auto"
}
},
"cheatsheet": {
"keybinds": {
"configPath": "" // Path to hyprland keybind config file. Leave empty for default (~/.config/hypr/hyprland/keybinds.conf)
}
},
"gaming": {
"crosshair": {
"size": 20,
"color": "rgba(113,227,32,0.9)"
}
},
"i18n": {
"langCode": "", //Customize the locale, such as zh_CN,Optional value references "~/.config/ags/i18n/locales/"
"extraLogs": false
},
"monitors": {
"scaleMethod": "division" // Either "division" [default] or "gdk"
},
"music": {
"preferredPlayer": "plasma-browser-integration"
},
"onScreenKeyboard": {
"layout": "qwerty_full" // See modules/onscreenkeyboard/onscreenkeyboard.js for available layouts
},
"overview": {
"scale": 0.18, // Relative to screen size
"numOfRows": 2,
"numOfCols": 5,
"wsNumScale": 0.09,
"wsNumMarginScale": 0.07
},
"sidebar": {
"image": {
"columns": 2,
"batchCount": 20,
"allowNsfw": false
},
"pages": {
"order": [
"apis",
"tools"
],
"defaultPage": "apis",
"apis": {
"order": [
"gemini",
"gpt",
"waifu",
"booru"
],
"defaultPage": "gemini"
}
},
"quickToggles": {
"order": [
"wifi",
"bluetooth",
"nightlight",
"gamemode",
"idleinhibitor",
"cloudflarewarp"
]
},
"calendar": {
"expandByDefault": true
}
},
"search": {
"enableFeatures": {
"actions": true,
"commands": true,
"mathResults": true,
"directorySearch": true,
"aiSearch": true,
"webSearch": true
},
"engineBaseUrl": "https://www.google.com/search?q=",
"excludedSites": [
"quora.com"
]
},
"time": {
// See https://docs.gtk.org/glib/method.DateTime.format.html
// Here's the 12h format: "%I:%M%P"
// For seconds, add "%S" and set interval to 1000
"format": "%H:%M",
"interval": 5000,
"dateFormatLong": "%A, %d/%m", // On bar
"dateInterval": 5000,
"dateFormat": "%d/%m", // On notif time
"calendarDateFormat": "%d %B %Y"
},
"weather": {
"city": "",
"preferredUnit": "C" // Either C or F
},
"workspaces": {
"shown": 10
},
"dock": {
"enabled": false,
"hiddenThickness": 5,
"pinnedApps": [
"firefox",
"org.gnome.Nautilus"
],
"layer": "top",
"monitorExclusivity": true, // Dock will move to other monitor along with focus if enabled
"searchPinnedAppIcons": false, // Try to search for the correct icon if the app class isn't an icon name
"trigger": [
"client-added",
"client-removed"
], // client_added, client_move, workspace_active, client_active
// Automatically hide dock after `interval` ms since trigger
"autoHide": [
{
"trigger": "client-added",
"interval": 500
},
{
"trigger": "client-removed",
"interval": 500
}
]
},
// Longer stuff
"icons": {
// Find the window's icon by its class with levenshteinDistance
// The file names are processed at startup, so if there
// are too many files in the search path it'll affect performance
// Example: ["/usr/share/icons/Tela-nord/scalable/apps"]
"searchPaths": [
""
],
"symbolicIconTheme": {
"dark": "Adwaita",
"light": "Adwaita"
},
"substitutions": {
"code-url-handler": "visual-studio-code",
"Code": "visual-studio-code",
"GitHub Desktop": "github-desktop",
"Minecraft* 1.20.1": "minecraft",
"gnome-tweaks": "org.gnome.tweaks",
"pavucontrol-qt": "pavucontrol",
"wps": "wps-office2019-kprometheus",
"wpsoffice": "wps-office2019-kprometheus",
"footclient": "foot",
"zen": "zen-browser",
"": "image-missing"
},
"regexSubstitutions": [
{
"regex": "/^steam_app_(\\d+)$/",
"replace": "steam_icon_$1"
}
]
},
"keybinds": {
// Format: "Modifier_1+...+Modifier_n+key". The key is CaSe SeNsItIvE!
// Modifiers: Shift Ctrl Alt Hyper Meta
// See https://docs.gtk.org/gdk3/index.html#constants for keys (listed as KEY_key)
// You can assign multiple keybinds for the same action. Just split them with a comma
// Example: "Ctrl+Page_Down, ctrl+Tab"
"overview": {
"altMoveLeft": "Ctrl+B",
"altMoveRight": "Ctrl+F",
"deleteToEnd": "Ctrl+K"
},
"sidebar": {
"apis": {
"nextTab": "Page_Down",
"prevTab": "Page_Up"
},
"options": { // Right sidebar
"nextTab": "Page_Down",
"prevTab": "Page_Up"
},
"expand": "Ctrl+E",
"pin": "Ctrl+P",
"cycleTab": "Ctrl+Tab",
"nextTab": "Ctrl+Page_Down",
"prevTab": "Ctrl+Page_Up"
},
"cheatsheet": {
"keybinds": {
"nextTab": "Page_Down",
"prevTab": "Page_Up"
},
"nextTab": "Ctrl+Page_Down",
"prevTab": "Ctrl+Page_Up",
"cycleTab": "Ctrl+Tab"
}
}
}
@@ -1,36 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import { parseJSONC } from '../.miscutils/jsonc.js';
function overrideConfigRecursive(userOverrides, configOptions = {}) {
for (const [key, value] of Object.entries(userOverrides)) {
if (typeof value === 'object'
&& !(value instanceof Array)
&& configOptions[key]) {
overrideConfigRecursive(value, configOptions[key]);
}
else {
configOptions[key] = value;
}
}
}
// Load default options from ~/.config/ags/modules/.configuration/default_options.jsonc
const defaultConfigFile = `${App.configDir}/modules/.configuration/default_options.jsonc`;
const defaultConfigFileContents = Utils.readFile(defaultConfigFile);
const defaultConfigOptions = parseJSONC(defaultConfigFileContents);
// Clone the default config to avoid modifying the original
let configOptions = JSON.parse(JSON.stringify(defaultConfigOptions));
// Load user overrides
const userOverrideFile = `${App.configDir}/user_options.jsonc`;
const userOverrideContents = Utils.readFile(userOverrideFile);
const userOverrides = parseJSONC(userOverrideContents);
// Override defaults with user's options
overrideConfigRecursive(userOverrides, configOptions);
globalThis['userOptionsDefaults'] = defaultConfigOptions;
globalThis['userOptions'] = configOptions;
export default configOptions;
-14
View File
@@ -1,14 +0,0 @@
const { Gio, GLib, Gtk } = imports.gi;
export function fileExists(filePath) {
let file = Gio.File.new_for_path(filePath);
return file.query_exists(null);
}
export function expandTilde(path) {
if (path.startsWith('~')) {
return GLib.get_home_dir() + path.slice(1);
} else {
return path;
}
}
-28
View File
@@ -1,28 +0,0 @@
const { Gtk } = imports.gi;
export function iconExists(iconName) {
let iconTheme = Gtk.IconTheme.get_default();
return iconTheme.has_icon(iconName);
}
export function substitute(str) {
// Normal substitutions
if (userOptions.icons.substitutions[str])
return userOptions.icons.substitutions[str];
// Regex substitutions
for (let i = 0; i < userOptions.icons.regexSubstitutions.length; i++) {
const substitution = userOptions.icons.regexSubstitutions[i];
const replacedName = str.replace(
substitution.regex,
substitution.replace,
);
if (replacedName != str) return replacedName;
}
// Guess: convert to kebab case
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, "-");
// Original string
return str;
}
-58
View File
@@ -1,58 +0,0 @@
export function parseJSONC(jsoncString) {
let result = "";
let inString = false;
let inSingleQuote = false;
let inMultiLineComment = false;
let inSingleLineComment = false;
for (let i = 0; i < jsoncString.length; i++) {
let char = jsoncString[i];
let nextChar = jsoncString[i + 1];
// Handle string start/end
if (!inSingleLineComment && !inMultiLineComment) {
if (char === '"' && !inSingleQuote) {
inString = !inString;
} else if (char === "'" && !inString) {
inSingleQuote = !inSingleQuote;
}
}
// Handle single-line comments //
if (!inString && !inSingleQuote && !inMultiLineComment && char === '/' && nextChar === '/') {
inSingleLineComment = true;
i++; // Skip next '/'
continue;
}
// Handle multi-line comments /*
if (!inString && !inSingleQuote && !inSingleLineComment && char === '/' && nextChar === '*') {
inMultiLineComment = true;
i++; // Skip next '*'
continue;
}
// End single-line comment at newline
if (inSingleLineComment && (char === '\n' || char === '\r')) {
inSingleLineComment = false;
}
// End multi-line comment */
if (inMultiLineComment && char === '*' && nextChar === '/') {
inMultiLineComment = false;
i++; // Skip next '/'
continue;
}
// Only append characters if not inside a comment
if (!inSingleLineComment && !inMultiLineComment) {
result += char;
}
}
// Remove trailing commas from objects and arrays
result = result.replace(/,\s*([\]}])/g, '$1');
// Parse as JSON
return JSON.parse(result);
}
@@ -1,16 +0,0 @@
export function clamp(x, min, max) {
return Math.min(Math.max(x, min), max);
}
export function truncateToPrecision(value, precision) {
const factor = Math.pow(10, precision);
const result = Math.round(value * factor) / factor;
return result;
}
export function distance(x1, y1, x2, y2) {
const distanceX = Math.abs(x1 - x2);
const distanceY = Math.abs(y1 - y2);
return Math.sqrt(distanceX * distanceX + distanceY * distanceY)
}
@@ -1,98 +0,0 @@
// Converts from Markdown to Pango. This does not support code blocks.
// For illogical-impulse, code blocks are treated separately, in their own GtkSourceView widgets.
// Partly inherited from https://github.com/ubunatic/md2pango
const monospaceFonts = 'JetBrains Mono NF, JetBrains Mono Nerd Font, JetBrains Mono NL, SpaceMono NF, SpaceMono Nerd Font, monospace';
const codeBlockRegex = /^\s*```([a-zA-Z0-9]+)?\n?/;
const replacements = {
'indents': [
{ name: 'BULLET', re: /^(\s*)([\*\-]\s)(.*)(\s*)$/, sub: ' $1- $3' },
{ name: 'NUMBERING', re: /^(\s*[0-9]+\.\s)(.*)(\s*)$/, sub: ' $1 $2' },
],
'escapes': [
{ name: 'COMMENT', re: /<!--[\s\S]*?-->/, sub: '' },
{ name: 'AMPERSTAND', re: /&/g, sub: '&amp;' },
{ name: 'LESSTHAN', re: /</g, sub: '&lt;' },
{ name: 'GREATERTHAN', re: />/g, sub: '&gt;' },
],
'sections': [
{ name: 'H1', re: /^(#\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="170%">$2</span>' },
{ name: 'H2', re: /^(##\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="150%">$2</span>' },
{ name: 'H3', re: /^(###\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="125%">$2</span>' },
{ name: 'H4', re: /^(####\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="100%">$2</span>' },
{ name: 'H5', re: /^(#####\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="90%">$2</span>' },
],
'styles': [
{ name: 'BOLD', re: /(\*\*)(\S[\s\S]*?\S)(\*\*)/g, sub: "<b>$2</b>" },
{ name: 'UND', re: /(__)(\S[\s\S]*?\S)(__)/g, sub: "<u>$2</u>" },
{ name: 'EMPH', re: /\*(\S.*?\S)\*/g, sub: "<i>$1</i>" },
// { name: 'EMPH', re: /_(\S.*?\S)_/g, sub: "<i>$1</i>" },
{ name: 'HEXCOLOR', re: /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/g, sub: '<span bgcolor="#$1" fgcolor="#000000" font_family="' + monospaceFonts + '">#$1</span>' },
{ name: 'INLCODE', re: /(`)([^`]*)(`)/g, sub: '<span font_weight="bold" font_family="' + monospaceFonts + '">$2</span>' },
// { name: 'UND', re: /(__|\*\*)(\S[\s\S]*?\S)(__|\*\*)/g, sub: "<u>$2</u>" },
],
'forceLatex': [
{ name: 'LATEX_INLINE_SQUARE', re: /\\\[(.*?)\\\]/g, sub: '\n```latex\n$1\n```' },
{ name: 'LATEX_INLINE_ROUND', re: /\\\((.*?)\\\)/g, sub: '\n```latex\n$1\n```' },
{ name: 'LATEX_INLINE_DOLLAR', re: /\$(.*?)\$/g, sub: '\n```latex\n$1\n```' }
]
}
const replaceCategory = (text, replaces) => {
for (const type of replaces) {
text = text.replace(type.re, type.sub);
}
return text;
}
// Main function
export function replaceInlineLatexWithCodeBlocks(text) {
return text.replace(/\\\[(.*?)\\\]|\\\((.*?)\\\)|\$\$(.*?)\$\$|(?:^|[^\w])\$(.*?[^\\])\$(?!\w)/gs, (match, square, round, double, single) => {
const latex = square || round || double || single;
return `\n\`\`\`latex\n${latex}\n\`\`\`\n`;
});
}
export default (text) => {
let lines = text.split('\n')
let output = [];
let inCode = false;
// Replace
for (const line of lines) {
let result = line;
if (codeBlockRegex.test(line)) inCode = !inCode;
if (inCode) continue;
result = replaceCategory(result, replacements.indents);
result = replaceCategory(result, replacements.escapes);
result = replaceCategory(result, replacements.sections);
result = replaceCategory(result, replacements.styles);
output.push(result)
}
// Remove trailing whitespaces
output = output.map(line => line.replace(/ +$/, ''))
return output.join('\n');
}
export const markdownTest = `## Inline formatting
- **Bold** *Italics* __Underline__
- \`Monospace text\` 🤓
- Colors
- Nvidia green #7ABB08
- Soundcloud orange #FF5500
## Code block
\`\`\`cpp
#include <bits/stdc++.h>
const std::string GREETING = "UwU";
int main(int argc, char* argv[]) {
std::cout << GREETING;
}
\`\`\`
## LaTeX
- Inline LaTeX: \\[ \\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\]
- Block LaTeX:
\`\`\`latex
\\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\\\\\\\ cos(2x) = 2cos^2(x) - 1 = 1 - 2sin^2(x) = cos^2(x) - sin^2(x)
\`\`\`
`;
-33
View File
@@ -1,33 +0,0 @@
export function getNestedProperty(obj, path) {
return path.split('.').reduce((current, key) => {
return (current && typeof current === 'object' && current.hasOwnProperty(key)) ? current[key] : undefined;
}, obj);
}
export function updateNestedProperty(obj, path, newValue) {
const pathArray = path.split('.');
const lastKeyIndex = pathArray.length - 1;
let current = obj;
for (let i = 0; i < lastKeyIndex; i++) {
const key = pathArray[i];
if (!current || typeof current !== 'object') {
return false; // Previous part of path is not an object
}
if (!current.hasOwnProperty(key)) {
current[key] = {}; // Create the missing object
}
current = current[key];
}
const lastKey = pathArray[lastKeyIndex];
if (!current || typeof current !== 'object') {
return false; // Parent is not an object
}
current[lastKey] = newValue;
return true;
}
-61
View File
@@ -1,61 +0,0 @@
const { GLib } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
export const distroID = exec(`bash -c 'cat /etc/os-release | grep "^ID=" | cut -d "=" -f 2 | sed "s/\\"//g"'`).trim();
export const isDebianDistro = (distroID == 'linuxmint' || distroID == 'ubuntu' || distroID == 'debian' || distroID == 'zorin' || distroID == 'popos' || distroID == 'raspbian' || distroID == 'kali');
export const isArchDistro = (distroID == 'arch' || distroID == 'endeavouros' || distroID == 'cachyos');
export const hasFlatpak = !!exec(`bash -c 'command -v flatpak'`);
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
export const darkMode = Variable(!(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light'));
darkMode.connect('changed', ({ value }) => {
let lightdark = value ? "dark" : "light";
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "1s/.*/${lightdark}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.then(execAsync(['bash', '-c', `command -v darkman && darkman set ${lightdark}`])) // Optional darkman integration
.catch(print);
});
globalThis['darkMode'] = darkMode;
export const hasPlasmaIntegration = !!Utils.exec('bash -c "command -v plasma-browser-integration-host"');
export const getDistroIcon = () => {
// Arches
if(distroID == 'arch') return 'arch-symbolic';
if(distroID == 'endeavouros') return 'endeavouros-symbolic';
if(distroID == 'cachyos') return 'cachyos-symbolic';
// Funny flake
if(distroID == 'nixos') return 'nixos-symbolic';
// Cool thing
if(distroID == 'fedora') return 'fedora-symbolic';
// Debians
if(distroID == 'linuxmint') return 'ubuntu-symbolic';
if(distroID == 'ubuntu') return 'ubuntu-symbolic';
if(distroID == 'debian') return 'debian-symbolic';
if(distroID == 'zorin') return 'ubuntu-symbolic';
if(distroID == 'popos') return 'ubuntu-symbolic';
if(distroID == 'raspbian') return 'debian-symbolic';
if(distroID == 'kali') return 'debian-symbolic';
return 'linux-symbolic';
}
export const getDistroName = () => {
// Arches
if(distroID == 'arch') return 'Arch Linux';
if(distroID == 'endeavouros') return 'EndeavourOS';
if(distroID == 'cachyos') return 'CachyOS';
// Funny flake
if(distroID == 'nixos') return 'NixOS';
// Cool thing
if(distroID == 'fedora') return 'Fedora';
// Debians
if(distroID == 'linuxmint') return 'Linux Mint';
if(distroID == 'ubuntu') return 'Ubuntu';
if(distroID == 'debian') return 'Debian';
if(distroID == 'zorin') return 'Zorin';
if(distroID == 'popos') return 'Pop!_OS';
if(distroID == 'raspbian') return 'Raspbian';
if(distroID == 'kali') return 'Kali Linux';
return 'Linux';
}
@@ -1,86 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Revealer, Scrollable } = Widget;
export const MarginRevealer = ({
transition = 'slide_down',
child,
revealChild,
showClass = 'element-show', // These are for animation curve, they don't really hide
hideClass = 'element-hide', // Don't put margins in these classes!
extraSetup = () => { },
...rest
}) => {
const widget = Scrollable({
...rest,
attribute: {
'revealChild': true, // It'll be set to false after init if it's supposed to hide
'transition': transition,
'show': () => {
if (widget.attribute.revealChild) return;
widget.hscroll = 'never';
widget.vscroll = 'never';
child.toggleClassName(hideClass, false);
child.toggleClassName(showClass, true);
widget.attribute.revealChild = true;
child.css = 'margin: 0px;';
},
'hide': () => {
if (!widget.attribute.revealChild) return;
child.toggleClassName(hideClass, true);
child.toggleClassName(showClass, false);
widget.attribute.revealChild = false;
if (widget.attribute.transition == 'slide_left')
child.css = `margin-right: -${child.get_allocated_width()}px;`;
else if (widget.attribute.transition == 'slide_right')
child.css = `margin-left: -${child.get_allocated_width()}px;`;
else if (widget.attribute.transition == 'slide_up')
child.css = `margin-bottom: -${child.get_allocated_height()}px;`;
else if (widget.attribute.transition == 'slide_down')
child.css = `margin-top: -${child.get_allocated_height()}px;`;
},
'toggle': () => {
if (widget.attribute.revealChild) widget.attribute.hide();
else widget.attribute.show();
},
},
child: child,
hscroll: `${revealChild ? 'never' : 'always'}`,
vscroll: `${revealChild ? 'never' : 'always'}`,
setup: (self) => {
extraSetup(self);
}
});
child.toggleClassName(`${revealChild ? showClass : hideClass}`, true);
return widget;
}
// TODO: Allow reveal update. Currently this just helps at declaration
export const DoubleRevealer = ({
transition1 = 'slide_right',
transition2 = 'slide_left',
duration1 = 150,
duration2 = 150,
child,
revealChild,
...rest
}) => {
const r2 = Revealer({
transition: transition2,
transitionDuration: duration2,
revealChild: revealChild,
child: child,
});
const r1 = Revealer({
transition: transition1,
transitionDuration: duration1,
revealChild: revealChild,
child: r2,
...rest,
})
r1.toggleRevealChild = (value) => {
r1.revealChild = value;
r2.revealChild = value;
}
return r1;
}
@@ -1,36 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Window } = Widget;
export default ({
name,
child,
showClassName = "",
hideClassName = "",
...props
}) => {
return Window({
name,
visible: false,
layer: 'top',
...props,
child: Box({
setup: (self) => {
self.keybind("Escape", () => closeEverything());
if (showClassName != "" && hideClassName !== "") {
self.hook(App, (self, currentName, visible) => {
if (currentName === name) {
self.toggleClassName(hideClassName, !visible);
}
});
if (showClassName !== "" && hideClassName !== "")
self.className = `${showClassName} ${hideClassName}`;
}
},
child: child,
}),
});
}
@@ -1,4 +0,0 @@
import Cairo from 'gi://cairo?version=1.0';
export const dummyRegion = new Cairo.Region();
export const enableClickthrough = (self) => self.input_shape_combine_region(dummyRegion);
@@ -1,36 +0,0 @@
// Cursor names reference: https://docs.gtk.org/gdk4/ctor.Cursor.new_from_name.html
const { Gdk } = imports.gi;
export function setupCursorHover(button, cursorName = 'pointer') { // Hand pointing cursor on hover
const display = Gdk.Display.get_default();
button.connect('enter-notify-event', () => {
const cursor = Gdk.Cursor.new_from_name(display, cursorName);
button.get_window().set_cursor(cursor);
});
button.connect('leave-notify-event', () => {
const cursor = Gdk.Cursor.new_from_name(display, 'default');
button.get_window().set_cursor(cursor);
});
}
export function setupCursorHoverAim(button) { // Crosshair cursor on hover
setupCursorHover(button, 'crosshair');
}
export function setupCursorHoverGrab(button) { // Hand ready to grab on hover
setupCursorHover(button, 'grab');
}
export function setupCursorHoverInfo(button) { // "?" mark cursor on hover
setupCursorHover(button, 'help');
}
export function setupCursorHoverHResize(button) { // Resize left right
setupCursorHover(button, 'ew-resize');
}
export function setupCursorHoverVResize(button) { // Resize up down
setupCursorHover(button, 'ns-resize');
}
@@ -1,34 +0,0 @@
const { Gdk } = imports.gi;
const MODS = {
'shift': Gdk.ModifierType.SHIFT_MASK,
'ctrl': Gdk.ModifierType.CONTROL_MASK,
'alt': Gdk.ModifierType.ALT_MASK,
'hyper': Gdk.ModifierType.HYPER_MASK,
'meta': Gdk.ModifierType.META_MASK
}
const checkSingleKeybind = (event, keybind) => {
const pressedModMask = event.get_state()[1];
const pressedKey = event.get_keyval()[1];
const keys = keybind.split('+');
for (let i = 0; i < keys.length; i++) {
if (keys[i].toLowerCase() in MODS) {
if (!(pressedModMask & MODS[keys[i].toLowerCase()])) {
return false;
}
} else if (pressedKey !== Gdk[`KEY_${keys[i]}`] && pressedKey !== Gdk[`KEY_${keys[i].toLowerCase()}`]) {
return false;
}
}
return true;
}
export const checkKeybind = (event, keybind) => {
const keybinds = keybind.replace(' ', '').split(',');
for (let i = 0; i < keybinds.length; i++) {
if (checkSingleKeybind(event, keybinds[i])) {
return true;
}
}
}
@@ -1,213 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, DrawingArea, EventBox } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
const dummyWs = Box({ className: 'bar-ws-focus' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws-focus bar-ws-focus-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws-focus bar-ws-focus-occupied' }); // Not shown. Only for getting size props
const WS_TAKEN_WIDTH_MULTIPLIER = 1.4;
const floor = Math.floor;
const ceil = Math.ceil;
// Font size = workspace id
const WorkspaceContents = (count = 10) => {
return DrawingArea({
className: 'menu-decel',
attribute: {
lastImmediateActiveWs: 0,
immediateActiveWs: 0,
initialized: false,
workspaceMask: 0,
workspaceGroup: 0,
updateMask: (self) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
// if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Hyprland.workspaces;
let workspaceMask = 0;
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
if (ws.id <= offset || ws.id > offset + count) continue; // Out of range, ignore
if (workspaces[i].windows > 0)
workspaceMask |= (1 << (ws.id - offset));
}
// console.log('Mask:', workspaceMask.toString(2));
self.attribute.workspaceMask = workspaceMask;
// self.attribute.initialized = true;
self.queue_draw();
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
self.queue_draw();
},
},
setup: (area) => area
.hook(Hyprland.active.workspace, (self) => {
const newActiveWs = (Hyprland.active.workspace.id - 1) % count + 1;
self.setCss(`font-size: ${newActiveWs}px;`);
self.attribute.lastImmediateActiveWs = self.attribute.immediateActiveWs;
self.attribute.immediateActiveWs = newActiveWs;
const previousGroup = self.attribute.workspaceGroup;
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / count);
if (currentGroup !== previousGroup) {
self.attribute.updateMask(self);
self.attribute.workspaceGroup = currentGroup;
}
})
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
.on('draw', Lang.bind(area, (area, cr) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activeWorkspaceWidth = activeWorkspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
// const activeWorkspaceWidth = 100;
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const lastImmediateActiveWs = area.attribute.lastImmediateActiveWs;
const immediateActiveWs = area.attribute.immediateActiveWs;
// Draw
area.set_size_request(workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth, -1);
for (let i = 1; i <= count; i++) {
if (i == immediateActiveWs) continue;
let colors = {};
if (area.attribute.workspaceMask & (1 << i)) colors = occupiedbg;
else colors = wsbg;
// if ((i == immediateActiveWs + 1 && immediateActiveWs < activeWs) ||
// (i == immediateActiveWs + 1 && immediateActiveWs < activeWs)) {
// const widthPercentage = (i == immediateActiveWs - 1) ?
// 1 - (immediateActiveWs - activeWs) :
// activeWs - immediateActiveWs;
// cr.setSourceRGBA(colors.red * widthPercentage + activebg.red * (1 - widthPercentage),
// colors.green * widthPercentage + activebg.green * (1 - widthPercentage),
// colors.blue * widthPercentage + activebg.blue * (1 - widthPercentage),
// colors.alpha);
// }
// else
cr.setSourceRGBA(colors.red, colors.green, colors.blue, colors.alpha)
const centerX = (i <= activeWs) ?
(-workspaceRadius + (workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * i))
: -workspaceRadius + workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth - ((count - i) * workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER);
cr.arc(centerX, height / 2, workspaceRadius, 0, 2 * Math.PI);
cr.fill();
// What if shrinking
if (i == floor(activeWs) && immediateActiveWs > activeWs) { // To right
const widthPercentage = 1 - (ceil(activeWs) - activeWs);
const leftX = centerX;
const wsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * (1 - widthPercentage);
cr.rectangle(leftX, height / 2 - workspaceRadius, wsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX + wsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
else if (i == ceil(activeWs) && immediateActiveWs < activeWs) { // To left
const widthPercentage = activeWs - floor(activeWs);
const rightX = centerX;
const wsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * widthPercentage;
const leftX = rightX - wsWidth;
cr.rectangle(leftX, height / 2 - workspaceRadius, wsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
}
let widthPercentage, leftX, rightX, activeWsWidth;
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
if (immediateActiveWs > activeWs) { // To right
const immediateActiveWs = ceil(activeWs);
widthPercentage = immediateActiveWs - activeWs;
rightX = -workspaceRadius + workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth - ((count - immediateActiveWs) * workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER);
activeWsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * (1 - widthPercentage);
leftX = rightX - activeWsWidth;
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2); // Should be 0.5 * Math.PI, 1.5 * Math.PI in theory but it leaves a weird 1px gap
cr.fill();
cr.rectangle(leftX, height / 2 - workspaceRadius, activeWsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX + activeWsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
else { // To left
const immediateActiveWs = floor(activeWs);
widthPercentage = 1 - (activeWs - immediateActiveWs);
leftX = -workspaceRadius + (workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * immediateActiveWs);
activeWsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * widthPercentage
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2); // Should be 0.5 * Math.PI, 1.5 * Math.PI in theory but it leaves a weird 1px gap
cr.fill();
cr.rectangle(leftX, height / 2 - workspaceRadius, activeWsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX + activeWsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
}))
,
})
}
export default () => EventBox({
onScrollUp: () => Hyprland.messageAsync(`dispatch workspace r-1`).catch(print),
onScrollDown: () => Hyprland.messageAsync(`dispatch workspace r+1`).catch(print),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: {
clicked: false,
ws_group: 0,
},
child: Box({
homogeneous: true,
// className: 'bar-group-margin',
children: [Box({
// className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [WorkspaceContents(userOptions.workspaces.shown)],
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
// const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_PER_GROUP / widgetWidth) + self.attribute.ws_group * NUM_OF_WORKSPACES_PER_GROUP;
// Hyprland.messageAsync(`dispatch workspace ${wsId}`).catch(print);
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
})
@@ -1,183 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import Widget from "resource:///com/github/Aylur/ags/widget.js";
import Sway from "../../../services/sway.js";
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
const { execAsync, exec } = Utils;
const { Box, DrawingArea, EventBox } = Widget;
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
const switchToWorkspace = (arg) => Utils.execAsync(`swaymsg workspace ${arg}`).catch(print);
const switchToRelativeWorkspace = (self, num) =>
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
const WorkspaceContents = (count = 10) => {
return DrawingArea({
css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`,
attribute: {
initialized: false,
workspaceMask: 0,
updateMask: (self) => {
if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Sway.workspaces;
let workspaceMask = 0;
// console.log('----------------')
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
// console.log(ws.name, ',', ws.num);
if (!Number(ws.name)) return;
const id = Number(ws.name);
if (id <= 0) continue; // Ignore scratchpads
if (id > count) return; // Not rendered
if (workspaces[i].windows > 0) {
workspaceMask |= (1 << id);
}
}
self.attribute.workspaceMask = workspaceMask;
self.attribute.initialized = true;
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
},
},
setup: (area) => area
.hook(Sway.active.workspace, (area) => {
area.setCss(`font-size: ${Sway.active.workspace.name}px;`)
})
.hook(Sway, (self) => self.attribute.updateMask(self), 'notify::workspaces')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, true, name), 'workspace-added')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, false, name), 'workspace-removed')
.on('draw', Lang.bind(area, (area, cr) => {
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
area.set_size_request(workspaceDiameter * count, -1);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
const activeWsCenterY = height / 2;
// Font
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius
const indicatorGap = workspaceRadius - indicatorRadius;
// Draw workspace numbers
for (let i = 1; i <= count; i++) {
if (area.attribute.workspaceMask & (1 << i)) {
// Draw bg highlight
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
const wsCenterY = height / 2;
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
// Set color for text
cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha);
}
else
cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha);
layout.set_text(`${i}`, -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
const y = (height - layoutHeight) / 2;
cr.moveTo(x, y);
// cr.showText(text);
PangoCairo.show_layout(cr, layout);
cr.stroke();
}
// Draw active ws
// base
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
cr.fill();
// inner decor
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
cr.fill();
}))
,
})
}
export default () => EventBox({
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: { clicked: false },
child: Box({
homogeneous: true,
className: 'bar-group-margin',
children: [Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [
WorkspaceContents(10),
]
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
});
-129
View File
@@ -1,129 +0,0 @@
const { Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
import WindowTitle from "./normal/spaceleft.js";
import Indicators from "./normal/spaceright.js";
import Music from "./normal/music.js";
import System from "./normal/system.js";
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js";
import { currentShellMode } from '../../variables.js';
const NormalOptionalWorkspaces = async () => {
try {
return (await import('./normal/workspaces_hyprland.js')).default();
} catch {
try {
return (await import('./normal/workspaces_sway.js')).default();
} catch {
return null;
}
}
};
const FocusOptionalWorkspaces = async () => {
try {
return (await import('./focus/workspaces_hyprland.js')).default();
} catch {
try {
return (await import('./focus/workspaces_sway.js')).default();
} catch {
return null;
}
}
};
export const Bar = async (monitor = 0) => {
const SideModule = (children) => Widget.Box({
className: 'bar-sidemodule',
children: children,
});
const normalBarContent = Widget.CenterBox({
className: 'bar-bg',
setup: (self) => {
const styleContext = self.get_style_context();
const minHeight = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
// execAsync(['bash', '-c', `hyprctl keyword monitor ,addreserved,${minHeight},0,0,0`]).catch(print);
},
startWidget: (await WindowTitle(monitor)),
centerWidget: Widget.Box({
className: 'spacing-h-4',
children: [
SideModule([Music()]),
Widget.Box({
homogeneous: true,
children: [await NormalOptionalWorkspaces()],
}),
SideModule([System()]),
]
}),
endWidget: Indicators(monitor),
});
const focusedBarContent = Widget.CenterBox({
className: 'bar-bg-focus',
startWidget: Widget.Box({}),
centerWidget: Widget.Box({
className: 'spacing-h-4',
children: [
SideModule([]),
Widget.Box({
homogeneous: true,
children: [await FocusOptionalWorkspaces()],
}),
SideModule([]),
]
}),
endWidget: Widget.Box({}),
setup: (self) => {
self.hook(Battery, (self) => {
if (!Battery.available) return;
self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= userOptions.battery.low);
})
}
});
const nothingContent = Widget.Box({
className: 'bar-bg-nothing',
})
return Widget.Window({
monitor,
name: `bar${monitor}`,
anchor: ['top', 'left', 'right'],
exclusivity: 'exclusive',
visible: true,
child: Widget.Stack({
homogeneous: false,
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
children: {
'normal': normalBarContent,
'focus': focusedBarContent,
'nothing': nothingContent,
},
setup: (self) => self.hook(currentShellMode, (self) => {
self.shown = currentShellMode.value[monitor];
})
}),
});
}
export const BarCornerTopleft = (monitor = 0) => Widget.Window({
monitor,
name: `barcornertl${monitor}`,
layer: 'top',
anchor: ['top', 'left'],
exclusivity: 'normal',
visible: true,
child: RoundedCorner('topleft', { className: 'corner', }),
setup: enableClickthrough,
});
export const BarCornerTopright = (monitor = 0) => Widget.Window({
monitor,
name: `barcornertr${monitor}`,
layer: 'top',
anchor: ['top', 'right'],
exclusivity: 'normal',
visible: true,
child: RoundedCorner('topright', { className: 'corner', }),
setup: enableClickthrough,
});
-241
View File
@@ -1,241 +0,0 @@
const { GLib } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
const { Box, Button, EventBox, Label, Overlay, Revealer, Scrollable } = Widget;
const { execAsync, exec } = Utils;
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { showMusicControls } from '../../../variables.js';
const CUSTOM_MODULE_CONTENT_INTERVAL_FILE = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-interval.txt`;
const CUSTOM_MODULE_CONTENT_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-poll.sh`;
const CUSTOM_MODULE_LEFTCLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-leftclick.sh`;
const CUSTOM_MODULE_RIGHTCLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-rightclick.sh`;
const CUSTOM_MODULE_MIDDLECLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-middleclick.sh`;
const CUSTOM_MODULE_SCROLLUP_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-scrollup.sh`;
const CUSTOM_MODULE_SCROLLDOWN_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-scrolldown.sh`;
function trimTrackTitle(title) {
if (!title) return '';
const cleanPatterns = [
/【[^】]*】/, // Touhou n weeb stuff
" [FREE DOWNLOAD]", // F-777
];
cleanPatterns.forEach((expr) => title = title.replace(expr, ''));
return title;
}
function adjustVolume(direction) {
const step = 0.1; // We use a larger step because this is player instance volume, not global
const mpris = Mpris.getPlayer('');
mpris.volume += (direction === 'up') ? step : -step
}
const BarGroup = ({ child }) => Box({
className: 'bar-group-margin bar-sides',
children: [
Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad-system`,
children: [child],
}),
]
});
const BarResource = (name, icon, command, circprogClassName = `bar-batt-circprog ${userOptions.appearance.borderless ? 'bar-batt-circprog-borderless' : ''}`, textClassName = 'txt-onSurfaceVariant', iconClassName = 'bar-batt') => {
const resourceCircProg = AnimatedCircProg({
className: `${circprogClassName}`,
vpack: 'center',
hpack: 'center',
});
const resourceProgress = Box({
homogeneous: true,
children: [Overlay({
child: Box({
vpack: 'center',
className: `${iconClassName}`,
homogeneous: true,
children: [
MaterialIcon(icon, 'small'),
],
}),
overlays: [resourceCircProg]
})]
});
const resourceLabel = Label({
className: `txt-smallie ${textClassName}`,
});
const widget = Button({
onClicked: () => Utils.execAsync(['bash', '-c', `${userOptions.apps.taskManager}`]).catch(print),
child: Box({
className: `spacing-h-4 ${textClassName}`,
children: [
resourceProgress,
resourceLabel,
],
setup: (self) => self.poll(5000, () => execAsync(['bash', '-c', command])
.then((output) => {
resourceCircProg.css = `font-size: ${Number(output)}px;`;
resourceLabel.label = `${Math.round(Number(output))}%`;
widget.tooltipText = `${name}: ${Math.round(Number(output))}%`;
}).catch(print))
,
})
});
return widget;
}
const TrackProgress = () => {
const _updateProgress = (circprog) => {
const mpris = Mpris.getPlayer('');
if (!mpris)
circprog.css = `font-size: ${userOptions.appearance.borderless ? 100 : 0}px;`
else // Set circular progress value
circprog.css = `font-size: ${Math.max(mpris.position / mpris.length * 100, 0)}px;`
}
return AnimatedCircProg({
className: `bar-music-circprog ${userOptions.appearance.borderless ? 'bar-music-circprog-borderless' : ''}`,
vpack: 'center', hpack: 'center',
extraSetup: (self) => self
.hook(Mpris, _updateProgress)
.poll(3000, _updateProgress)
,
})
}
const switchToRelativeWorkspace = async (self, num) => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
Hyprland.messageAsync(`dispatch workspace ${num > 0 ? '+' : ''}${num}`).catch(print);
} catch {
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
}
}
export default () => {
// TODO: use cairo to make button bounce smaller on click, if that's possible
const playingState = Box({ // Wrap a box cuz overlay can't have margins itself
homogeneous: true,
children: [Overlay({
child: Box({
vpack: 'center',
className: 'bar-music-playstate',
homogeneous: true,
children: [Label({
vpack: 'center',
className: 'bar-music-playstate-txt',
justification: 'center',
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
label.label = `${mpris !== null && mpris.playBackStatus == 'Playing' ? 'pause' : 'play_arrow'}`;
}),
})],
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
if (!mpris) return;
label.toggleClassName('bar-music-playstate-playing', mpris !== null && mpris.playBackStatus == 'Playing');
label.toggleClassName('bar-music-playstate', mpris !== null || mpris.playBackStatus == 'Paused');
}),
}),
overlays: [
TrackProgress(),
]
})]
});
const trackTitle = Label({
hexpand: true,
className: 'txt-smallie bar-music-txt',
truncate: 'end',
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
if (mpris)
label.label = `${trimTrackTitle(mpris.trackTitle)}${mpris.trackArtists.join(', ')}`;
else
label.label = getString('No media');
}),
})
const musicStuff = Box({
className: 'spacing-h-10',
hexpand: true,
children: [
playingState,
trackTitle,
]
})
const SystemResourcesOrCustomModule = () => {
// Check if $XDG_CACHE_HOME/ags/user/scripts/custom-module-poll.sh exists
if (GLib.file_test(CUSTOM_MODULE_CONTENT_SCRIPT, GLib.FileTest.EXISTS)) {
const interval = Number(Utils.readFile(CUSTOM_MODULE_CONTENT_INTERVAL_FILE)) || 5000;
return BarGroup({
child: Button({
child: Label({
className: 'txt-smallie txt-onSurfaceVariant',
useMarkup: true,
setup: (self) => Utils.timeout(1, () => {
self.label = exec(CUSTOM_MODULE_CONTENT_SCRIPT);
self.poll(interval, (self) => {
const content = exec(CUSTOM_MODULE_CONTENT_SCRIPT);
self.label = content;
})
})
}),
onPrimaryClickRelease: () => execAsync(CUSTOM_MODULE_LEFTCLICK_SCRIPT).catch(print),
onSecondaryClickRelease: () => execAsync(CUSTOM_MODULE_RIGHTCLICK_SCRIPT).catch(print),
onMiddleClickRelease: () => execAsync(CUSTOM_MODULE_MIDDLECLICK_SCRIPT).catch(print),
onScrollUp: () => execAsync(CUSTOM_MODULE_SCROLLUP_SCRIPT).catch(print),
onScrollDown: () => execAsync(CUSTOM_MODULE_SCROLLDOWN_SCRIPT).catch(print),
})
});
} else return BarGroup({
child: Box({
children: [
BarResource(getString('RAM Usage'), 'memory', `LANG=C free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`,
`bar-ram-circprog ${userOptions.appearance.borderless ? 'bar-ram-circprog-borderless' : ''}`, 'bar-ram-txt', 'bar-ram-icon'),
Revealer({
revealChild: true,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
className: 'spacing-h-10 margin-left-10',
children: [
BarResource(getString('Swap Usage'), 'swap_horiz', `LANG=C free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`,
`bar-swap-circprog ${userOptions.appearance.borderless ? 'bar-swap-circprog-borderless' : ''}`, 'bar-swap-txt', 'bar-swap-icon'),
BarResource(getString('CPU Usage'), 'settings_motion_mode', `LANG=C top -bn1 | grep Cpu | sed 's/\\,/\\./g' | awk '{print $2}'`,
`bar-cpu-circprog ${userOptions.appearance.borderless ? 'bar-cpu-circprog-borderless' : ''}`, 'bar-cpu-txt', 'bar-cpu-icon'),
]
}),
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
self.revealChild = (!mpris || mpris.playBackStatus !== 'Playing' || userOptions.bar.alwaysShowFullResources);
}),
})
],
})
});
}
return EventBox({
onScrollUp: () => adjustVolume('up'),
onScrollDown: () => adjustVolume('down'),
child: Box({
className: 'spacing-h-4',
children: [
SystemResourcesOrCustomModule(),
EventBox({
child: BarGroup({ child: musicStuff }),
onPrimaryClick: () => showMusicControls.setValue(!showMusicControls.value),
onSecondaryClick: () => execAsync(['bash', '-c', 'playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` &']).catch(print),
onMiddleClick: () => execAsync('playerctl play-pause').catch(print),
setup: (self) => self.on('button-press-event', (self, event) => {
if (event.get_button()[1] === 8) // Side button
execAsync('playerctl previous').catch(print)
}),
})
]
})
});
}
@@ -1,96 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Brightness from '../../../services/brightness.js';
import Indicator from '../../../services/indicator.js';
import { distance } from '../../.miscutils/mathfuncs.js';
const OSD_DISMISS_DISTANCE = 10;
const WindowTitle = async () => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
return Widget.Scrollable({
hexpand: true, vexpand: true,
hscroll: 'automatic', vscroll: 'never',
child: Widget.Box({
vertical: true,
children: [
Widget.Label({
xalign: 0,
truncate: 'end',
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
className: 'txt-smaller bar-wintitle-topdesc txt',
setup: (self) => self.hook(Hyprland.active.client, label => { // Hyprland.active.client
label.label = Hyprland.active.client.class.length === 0 ? 'Desktop' : Hyprland.active.client.class;
}),
}),
Widget.Label({
xalign: 0,
truncate: 'end',
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
className: 'txt-smallie bar-wintitle-txt',
setup: (self) => {
self.hook(Hyprland.active.client, label => { // Hyprland.active.client
label.label = Hyprland.active.client.title.length === 0 ? `Workspace ${Hyprland.active.workspace.id}` : Hyprland.active.client.title;
});
self.hook(Hyprland.active.workspace, label => { // Hyprland.active.client
label.label = Hyprland.active.client.title.length === 0 ? `Workspace ${Hyprland.active.workspace.id}` : Hyprland.active.client.title;
});
}
})
]
})
});
} catch {
return null;
}
}
export default async (monitor = 0) => {
const optionalWindowTitleInstance = await WindowTitle();
let scrollCursorX, scrollCursorY;
return Widget.EventBox({
onScrollUp: (self, event) => {
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
Indicator.popup(1); // Since the brightness and speaker are both on the same window
Brightness[monitor].screen_value += 0.05;
},
onScrollDown: (self, event) => {
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
Indicator.popup(1); // Since the brightness and speaker are both on the same window
Brightness[monitor].screen_value -= 0.05;
},
onPrimaryClick: () => {
App.toggleWindow('sideleft');
},
setup: (self) => self.on('motion-notify-event', (self, event) => {
const [_, cursorX, cursorY] = event.get_coords();
if (distance(cursorX, cursorY, scrollCursorX, scrollCursorY) >= OSD_DISMISS_DISTANCE)
Indicator.popup(-1);
}),
child: Widget.Box({
homogeneous: false,
children: [
Widget.Box({ className: 'bar-corner-spacing' }),
Widget.Overlay({
overlays: [
Widget.Box({ hexpand: true }),
Widget.Box({
className: 'bar-sidemodule', hexpand: true,
children: [Widget.Box({
vertical: true,
className: 'bar-space-button',
children: [
optionalWindowTitleInstance,
]
})]
}),
]
})
]
})
});
}
@@ -1,106 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
const { execAsync } = Utils;
import Indicator from '../../../services/indicator.js';
import { StatusIcons } from '../../.commonwidgets/statusicons.js';
import { Tray } from "./tray.js";
import { distance } from '../../.miscutils/mathfuncs.js';
const OSD_DISMISS_DISTANCE = 10;
const SeparatorDot = () => Widget.Revealer({
transition: 'slide_left',
revealChild: false,
attribute: {
'count': SystemTray.items.length,
'update': (self, diff) => {
self.attribute.count += diff;
self.revealChild = (self.attribute.count > 0);
}
},
child: Widget.Box({
vpack: 'center',
className: 'separator-circle',
}),
setup: (self) => self
.hook(SystemTray, (self) => self.attribute.update(self, 1), 'added')
.hook(SystemTray, (self) => self.attribute.update(self, -1), 'removed')
,
});
export default (monitor = 0) => {
const barTray = Tray();
const barStatusIcons = StatusIcons({
className: 'bar-statusicons',
setup: (self) => self.hook(App, (self, currentName, visible) => {
if (currentName === 'sideright') {
self.toggleClassName('bar-statusicons-active', visible);
}
}),
}, monitor);
const SpaceRightInteractions = (child) => Widget.EventBox({
onHover: () => { barStatusIcons.toggleClassName('bar-statusicons-hover', true) },
onHoverLost: () => { barStatusIcons.toggleClassName('bar-statusicons-hover', false) },
onPrimaryClick: () => App.toggleWindow('sideright'),
onSecondaryClick: () => execAsync(['bash', '-c', 'playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` &']).catch(print),
onMiddleClick: () => execAsync('playerctl play-pause').catch(print),
setup: (self) => self.on('button-press-event', (self, event) => {
if (event.get_button()[1] === 8)
execAsync('playerctl previous').catch(print)
}).on('motion-notify-event', (self, event) => {
Indicator.popup(-1);
}),
child: child,
});
const emptyArea = SpaceRightInteractions(Widget.Box({ hexpand: true, }));
const indicatorArea = SpaceRightInteractions(Widget.Box({
children: [
SeparatorDot(),
barStatusIcons
],
}));
const actualContent = Widget.Box({
hexpand: true,
className: 'spacing-h-5 bar-spaceright',
children: [
emptyArea,
barTray,
indicatorArea
],
});
let scrollCursorX, scrollCursorY;
return Widget.EventBox({
onScrollUp: (self, event) => {
if (!Audio.speaker) return;
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
if (Audio.speaker.volume <= 0.09) Audio.speaker.volume += 0.01;
else Audio.speaker.volume += 0.03;
Indicator.popup(1);
},
onScrollDown: (self, event) => {
if (!Audio.speaker) return;
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
if (Audio.speaker.volume <= 0.09) Audio.speaker.volume -= 0.01;
else Audio.speaker.volume -= 0.03;
Indicator.popup(1);
},
setup: (self) => self.on('motion-notify-event', (self, event) => {
const [_, cursorX, cursorY] = event.get_coords();
if (distance(cursorX, cursorY, scrollCursorX, scrollCursorY) >= OSD_DISMISS_DISTANCE)
Indicator.popup(-1);
}),
child: Widget.Box({
children: [
actualContent,
SpaceRightInteractions(Widget.Box({ className: 'bar-corner-spacing' })),
]
})
});
}
-238
View File
@@ -1,238 +0,0 @@
// This is for the right pills of the bar.
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Label, Button, Overlay, Revealer, Scrollable, Stack, EventBox } = Widget;
const { exec, execAsync } = Utils;
const { GLib } = imports.gi;
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
import { WWO_CODE, WEATHER_SYMBOL, NIGHT_WEATHER_SYMBOL } from '../../.commondata/weather.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
const WEATHER_CACHE_FOLDER = `${GLib.get_user_cache_dir()}/ags/weather`;
Utils.exec(`mkdir -p ${WEATHER_CACHE_FOLDER}`);
const BarBatteryProgress = () => {
const _updateProgress = (circprog) => { // Set circular progress value
circprog.css = `font-size: ${Math.abs(Battery.percent)}px;`
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= userOptions.battery.low);
circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
}
return AnimatedCircProg({
className: `bar-batt-circprog ${userOptions.appearance.borderless ? 'bar-batt-circprog-borderless' : ''}`,
vpack: 'center', hpack: 'center',
extraSetup: (self) => self
.hook(Battery, _updateProgress)
,
})
}
const time = Variable('', {
poll: [
userOptions.time.interval,
() => GLib.DateTime.new_now_local().format(userOptions.time.format),
],
})
const date = Variable('', {
poll: [
userOptions.time.dateInterval,
() => GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
],
})
const BarClock = () => Widget.Box({
vpack: 'center',
className: 'spacing-h-4 bar-clock-box',
children: [
Widget.Label({
className: 'bar-time',
label: time.bind(),
}),
Widget.Label({
className: 'txt-norm txt-onLayer1',
label: '•',
}),
Widget.Label({
className: 'txt-smallie bar-date',
label: date.bind(),
}),
],
});
const UtilButton = ({ name, icon, onClicked }) => Button({
vpack: 'center',
tooltipText: name,
onClicked: onClicked,
className: `bar-util-btn ${userOptions.appearance.borderless ? 'bar-util-btn-borderless' : ''} icon-material txt-norm`,
label: `${icon}`,
setup: setupCursorHover
})
const Utilities = () => Box({
hpack: 'center',
className: 'spacing-h-4',
children: [
UtilButton({
name: getString('Screen snip'), icon: 'screenshot_region', onClicked: () => {
Utils.execAsync(`${App.configDir}/scripts/grimblast.sh copy area`)
.catch(print)
}
}),
UtilButton({
name: getString('Color picker'), icon: 'colorize', onClicked: () => {
Utils.execAsync(['hyprpicker', '-a']).catch(print)
}
}),
UtilButton({
name: getString('Toggle on-screen keyboard'), icon: 'keyboard', onClicked: () => {
toggleWindowOnAllMonitors('osk');
}
}),
]
})
const BarBattery = () => Box({
className: 'spacing-h-4 bar-batt-txt',
children: [
Revealer({
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
transition: 'slide_right',
child: MaterialIcon('bolt', 'norm', { tooltipText: "Charging" }),
setup: (self) => self.hook(Battery, revealer => {
self.revealChild = Battery.charging;
}),
}),
Label({
className: 'txt-smallie',
setup: (self) => self.hook(Battery, label => {
label.label = `${Number.parseFloat(Battery.percent.toFixed(1))}%`;
}),
}),
Overlay({
child: Widget.Box({
vpack: 'center',
className: 'bar-batt',
homogeneous: true,
children: [
MaterialIcon('battery_full', 'small'),
],
setup: (self) => self.hook(Battery, box => {
box.toggleClassName('bar-batt-low', Battery.percent <= userOptions.battery.low);
box.toggleClassName('bar-batt-full', Battery.charged);
}),
}),
overlays: [
BarBatteryProgress(),
]
}),
]
});
const BarGroup = ({ child }) => Widget.Box({
className: 'bar-group-margin bar-sides',
children: [
Widget.Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad-system`,
children: [child],
}),
]
});
const BatteryModule = () => Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
children: {
'laptop': Box({
className: 'spacing-h-4', children: [
BarGroup({ child: Utilities() }),
BarGroup({ child: BarBattery() }),
]
}),
'desktop': BarGroup({
child: Box({
hexpand: true,
hpack: 'center',
className: 'spacing-h-4 txt-onSurfaceVariant',
children: [
MaterialIcon('device_thermostat', 'small'),
Label({
label: 'Weather',
})
],
setup: (self) => self.poll(900000, async (self) => {
const WEATHER_CACHE_PATH = WEATHER_CACHE_FOLDER + '/wttr.in.txt';
const updateWeatherForCity = (city) => execAsync(`curl https://wttr.in/${city.replace(/ /g, '%20')}?format=j1`)
.then(output => {
const weather = JSON.parse(output);
Utils.writeFile(JSON.stringify(weather), WEATHER_CACHE_PATH)
.catch(print);
const weatherCode = weather.current_condition[0].weatherCode;
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
self.children[0].label = weatherSymbol;
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit}${getString('Feels like')} ${feelsLike}°${userOptions.weather.preferredUnit}`;
self.tooltipText = weatherDesc;
}).catch((err) => {
try { // Read from cache
const weather = JSON.parse(
Utils.readFile(WEATHER_CACHE_PATH)
);
const weatherCode = weather.current_condition[0].weatherCode;
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
self.children[0].label = weatherSymbol;
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit}${getString('Feels like')} ${feelsLike}°${userOptions.weather.preferredUnit}`;
self.tooltipText = weatherDesc;
} catch (err) {
print(err);
}
});
if (userOptions.weather.city != '' && userOptions.weather.city != null) {
updateWeatherForCity(userOptions.weather.city.replace(/ /g, '%20'));
}
else {
Utils.execAsync('curl ipinfo.io')
.then(output => {
return JSON.parse(output)['city'].toLowerCase();
})
.then(updateWeatherForCity)
.catch(print)
}
}),
})
}),
},
setup: (stack) => Utils.timeout(10, () => {
if (!Battery.available) stack.shown = 'desktop';
else stack.shown = 'laptop';
})
})
const switchToRelativeWorkspace = async (self, num) => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
Hyprland.messageAsync(`dispatch workspace r${num > 0 ? '+' : ''}${num}`).catch(print);
} catch {
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
}
}
export default () => Widget.EventBox({
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
onPrimaryClick: () => App.toggleWindow('sideright'),
child: Widget.Box({
className: 'spacing-h-4',
children: [
BarGroup({ child: BarClock() }),
BatteryModule(),
]
})
});
-36
View File
@@ -1,36 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
const { Box, Icon, Button, Revealer } = Widget;
const { Gravity } = imports.gi.Gdk;
const SysTrayItem = (item) => item.id !== null ? Button({
className: 'bar-systray-item',
child: Icon({ hpack: 'center' }).bind('icon', item, 'icon'),
setup: (self) => self
.hook(item, (self) => self.tooltipMarkup = item['tooltip-markup'])
,
onPrimaryClick: (_, event) => item.activate(event),
onSecondaryClick: (btn, event) => item.menu.popup_at_widget(btn, Gravity.SOUTH, Gravity.NORTH, null),
}) : null;
export const Tray = (props = {}) => {
const trayContent = Box({
className: 'margin-right-5 spacing-h-15',
setup: (self) => self
.hook(SystemTray, (self) => {
self.children = SystemTray.items.map(SysTrayItem);
self.show_all();
})
,
});
const trayRevealer = Widget.Revealer({
revealChild: true,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: trayContent,
});
return Box({
...props,
children: [trayRevealer],
});
}
@@ -1,224 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, DrawingArea, EventBox } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
const mix = (value1, value2, perc) => {
return value1 * perc + value2 * (1 - perc);
}
const getFontWeightName = (weight) => {
switch (weight) {
case Pango.Weight.ULTRA_LIGHT:
return 'UltraLight';
case Pango.Weight.LIGHT:
return 'Light';
case Pango.Weight.NORMAL:
return 'Normal';
case Pango.Weight.BOLD:
return 'Bold';
case Pango.Weight.ULTRA_BOLD:
return 'UltraBold';
case Pango.Weight.HEAVY:
return 'Heavy';
default:
return 'Normal';
}
}
// Font size = workspace id
const WorkspaceContents = (count = 10) => {
return DrawingArea({
className: 'bar-ws-container',
attribute: {
initialized: false,
workspaceMask: 0,
workspaceGroup: 0,
updateMask: (self) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
// if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Hyprland.workspaces;
let workspaceMask = 0;
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
if (ws.id <= offset || ws.id > offset + count) continue; // Out of range, ignore
if (workspaces[i].windows > 0)
workspaceMask |= (1 << (ws.id - offset));
}
// console.log('Mask:', workspaceMask.toString(2));
self.attribute.workspaceMask = workspaceMask;
// self.attribute.initialized = true;
self.queue_draw();
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
self.queue_draw();
},
},
setup: (area) => area
.hook(Hyprland.active.workspace, (self) => {
self.setCss(`font-size: ${(Hyprland.active.workspace.id - 1) % count + 1}px;`);
const previousGroup = self.attribute.workspaceGroup;
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / count);
if (currentGroup !== previousGroup) {
self.attribute.updateMask(self);
self.attribute.workspaceGroup = currentGroup;
}
})
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
.on('draw', Lang.bind(area, (area, cr) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
const workspaceFontWeight = workspaceStyleContext.get_property('font-weight', Gtk.StateFlags.NORMAL);
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
area.set_size_request(workspaceDiameter * count, -1);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
const activeWsCenterY = height / 2;
// Font
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${getFontWeightName(workspaceFontWeight)} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.15; // smaller than sqrt(2)*radius
const indicatorGap = workspaceRadius - indicatorRadius;
for (let i = 1; i <= count; i++) {
if (area.attribute.workspaceMask & (1 << i)) {
// Draw bg highlight
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
const wsCenterY = height / 2;
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
}
}
// Draw active ws
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
cr.fill();
// Draw workspace numbers
for (let i = 1; i <= count; i++) {
const inactivecolors = area.attribute.workspaceMask & (1 << i) ? occupiedfg : wsfg;
if (i == activeWs) {
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
}
// Moving to
else if ((i == Math.floor(activeWs) && Hyprland.active.workspace.id < activeWs) || (i == Math.ceil(activeWs) && Hyprland.active.workspace.id > activeWs)) {
cr.setSourceRGBA(mix(activefg.red, inactivecolors.red, 1 - Math.abs(activeWs - i)), mix(activefg.green, inactivecolors.green, 1 - Math.abs(activeWs - i)), mix(activefg.blue, inactivecolors.blue, 1 - Math.abs(activeWs - i)), activefg.alpha);
}
// Moving from
else if ((i == Math.floor(activeWs) && Hyprland.active.workspace.id > activeWs) || (i == Math.ceil(activeWs) && Hyprland.active.workspace.id < activeWs)) {
cr.setSourceRGBA(mix(activefg.red, inactivecolors.red, 1 - Math.abs(activeWs - i)), mix(activefg.green, inactivecolors.green, 1 - Math.abs(activeWs - i)), mix(activefg.blue, inactivecolors.blue, 1 - Math.abs(activeWs - i)), activefg.alpha);
}
// Inactive
else
cr.setSourceRGBA(inactivecolors.red, inactivecolors.green, inactivecolors.blue, inactivecolors.alpha);
layout.set_text(`${i + offset}`, -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
const y = (height - layoutHeight) / 2;
cr.moveTo(x, y);
PangoCairo.show_layout(cr, layout);
cr.stroke();
}
}))
,
})
}
export default () => EventBox({
onScrollUp: () => Hyprland.messageAsync(`dispatch workspace r-1`).catch(print),
onScrollDown: () => Hyprland.messageAsync(`dispatch workspace r+1`).catch(print),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: {
clicked: false,
ws_group: 0,
},
child: Box({
homogeneous: true,
className: 'bar-group-margin',
children: [Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [WorkspaceContents(userOptions.workspaces.shown)],
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
})
self.on('button-press-event', (self, event) => {
if (event.get_button()[1] === 1) {
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
}
else if (event.get_button()[1] === 8) {
Hyprland.messageAsync(`dispatch togglespecialworkspace`).catch(print);
}
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
})
@@ -1,183 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import Widget from "resource:///com/github/Aylur/ags/widget.js";
import Sway from "../../../services/sway.js";
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
const { execAsync, exec } = Utils;
const { Box, DrawingArea, EventBox } = Widget;
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
const switchToWorkspace = (arg) => Utils.execAsync(`swaymsg workspace ${arg}`).catch(print);
const switchToRelativeWorkspace = (self, num) =>
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
const WorkspaceContents = (count = 10) => {
return DrawingArea({
css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`,
attribute: {
initialized: false,
workspaceMask: 0,
updateMask: (self) => {
if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Sway.workspaces;
let workspaceMask = 0;
// console.log('----------------')
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
// console.log(ws.name, ',', ws.num);
if (!Number(ws.name)) return;
const id = Number(ws.name);
if (id <= 0) continue; // Ignore scratchpads
if (id > count) return; // Not rendered
if (workspaces[i].windows > 0) {
workspaceMask |= (1 << id);
}
}
self.attribute.workspaceMask = workspaceMask;
self.attribute.initialized = true;
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
},
},
setup: (area) => area
.hook(Sway.active.workspace, (area) => {
area.setCss(`font-size: ${Sway.active.workspace.name}px;`)
})
.hook(Sway, (self) => self.attribute.updateMask(self), 'notify::workspaces')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, true, name), 'workspace-added')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, false, name), 'workspace-removed')
.on('draw', Lang.bind(area, (area, cr) => {
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
area.set_size_request(workspaceDiameter * count, -1);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
const activeWsCenterY = height / 2;
// Font
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius
const indicatorGap = workspaceRadius - indicatorRadius;
// Draw workspace numbers
for (let i = 1; i <= count; i++) {
if (area.attribute.workspaceMask & (1 << i)) {
// Draw bg highlight
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
const wsCenterY = height / 2;
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
// Set color for text
cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha);
}
else
cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha);
layout.set_text(`${i}`, -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
const y = (height - layoutHeight) / 2;
cr.moveTo(x, y);
// cr.showText(text);
PangoCairo.show_layout(cr, layout);
cr.stroke();
}
// Draw active ws
// base
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
cr.fill();
// inner decor
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
cr.fill();
}))
,
})
}
export default () => EventBox({
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: { clicked: false },
child: Box({
homogeneous: true,
className: 'bar-group-margin',
children: [Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [
WorkspaceContents(10),
]
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
});
@@ -1,122 +0,0 @@
export const keybindList = [[
{
"icon": "pin_drop",
"name": "Workspaces: navigation",
"binds": [
{ "keys": ["󰖳", "+", "#"], "action": "Go to workspace #" },
{ "keys": ["󰖳", "+", "S"], "action": "Toggle special workspace" },
{ "keys": ["󰖳", "+", "(Scroll ↑↓)"], "action": "Go to workspace -1/+1" },
{ "keys": ["Ctrl", "󰖳", "+", "←"], "action": "Go to workspace on the left" },
{ "keys": ["Ctrl", "󰖳", "+", "→"], "action": "Go to workspace on the right" },
{ "keys": ["󰖳", "+", "PageUp"], "action": "Go to workspace on the left" },
{ "keys": ["󰖳", "+", "PageDown"], "action": "Go to workspace on the right" }
],
"id": 1
},
{
"icon": "overview_key",
"name": "Workspaces: management",
"binds": [
{ "keys": ["󰖳", "Alt", "+", "#"], "action": "Move window to workspace #" },
{ "keys": ["󰖳", "Alt", "+", "S"], "action": "Move window to special workspace" },
{ "keys": ["󰖳", "Alt", "+", "PageUp"], "action": "Move window to workspace on the left" },
{ "keys": ["󰖳", "Alt", "+", "PageDown"], "action": "Move window to workspace on the right" }
],
"id": 2
},
{
"icon": "move_group",
"name": "Windows",
"binds": [
{ "keys": ["󰖳", "+", "←↑→↓"], "action": "Focus window in direction" },
{ "keys": ["󰖳", "Shift", "+", "←↑→↓"], "action": "Swap window in direction" },
{ "keys": ["󰖳", "+", ";"], "action": "Split ratio -" },
{ "keys": ["󰖳", "+", "'"], "action": "Split ratio +" },
{ "keys": ["󰖳", "+", "Lmb"], "action": "Move window" },
{ "keys": ["󰖳", "+", "Rmb"], "action": "Resize window" },
{ "keys": ["󰖳", "Alt", "+", "Space"], "action": "Float window" },
{ "keys": ["󰖳", "+", "F"], "action": "Fullscreen" },
{ "keys": ["󰖳", "Alt", "+", "F"], "action": "Fake fullscreen" }
],
"id": 3
}
],
[
{
"icon": "widgets",
"name": "Widgets (AGS)",
"binds": [
{ "keys": ["󰖳", "OR", "󰖳", "+", "Tab"], "action": "Toggle overview/launcher" },
{ "keys": ["Ctrl", "󰖳", "+", "R"], "action": "Restart AGS" },
{ "keys": ["󰖳", "+", "/"], "action": "Toggle this cheatsheet" },
{ "keys": ["󰖳", "+", "N"], "action": "Toggle system sidebar" },
{ "keys": ["󰖳", "+", "B", "OR", "󰖳", "+", "O"], "action": "Toggle utilities sidebar" },
{ "keys": ["󰖳", "+", "K"], "action": "Toggle virtual keyboard" },
{ "keys": ["Ctrl", "Alt", "+", "Del"], "action": "Power/Session menu" },
{ "keys": ["Esc"], "action": "Exit a window" },
{ "keys": ["rightCtrl"], "action": "Dismiss/close sidebar" },
{ "keys": ["Ctrl", "󰖳", "+", "T"], "action": "Change wallpaper+colorscheme" },
// { "keys": ["󰖳", "+", "B"], "action": "Toggle left sidebar" },
// { "keys": ["󰖳", "+", "N"], "action": "Toggle right sidebar" },
// { "keys": ["󰖳", "+", "G"], "action": "Toggle volume mixer" },
// { "keys": ["󰖳", "+", "M"], "action": "Toggle useless audio visualizer" },
// { "keys": ["(right)Ctrl"], "action": "Dismiss notification & close menus" }
],
"id": 4
},
{
"icon": "construction",
"name": "Utilities",
"binds": [
{ "keys": ["PrtSc"], "action": "Screenshot >> clipboard" },
{ "keys": ["Ctrl", "PrtSc"], "action": "Screenshot >> file + clipboard" },
{ "keys": ["󰖳", "Shift", "+", "S"], "action": "Screen snip >> clipboard" },
{ "keys": ["󰖳", "Shift", "+", "T"], "action": "Image to text >> clipboard" },
{ "keys": ["󰖳", "Shift", "+", "C"], "action": "Color picker" },
{ "keys": ["󰖳", "Alt", "+", "R"], "action": "Record region" },
{ "keys": ["Ctrl", "Alt", "+", "R"], "action": "Record region with sound" },
{ "keys": ["󰖳", "Shift", "Alt", "+", "R"], "action": "Record screen with sound" }
],
"id": 5
},
],
[
{
"icon": "apps",
"name": "Apps",
"binds": [
{ "keys": ["󰖳", "+", "T"], "action": "Launch terminal: foot" },
{ "keys": ["󰖳", "+", "W"], "action": "Launch browser: Firefox" },
{ "keys": ["󰖳", "+", "C"], "action": "Launch editor: vscode" },
{ "keys": ["󰖳", "+", "X"], "action": "Launch editor: GNOME Text Editor" },
{ "keys": ["󰖳", "+", "I"], "action": "Launch settings: GNOME Control center" }
],
"id": 6
},
{
"icon": "keyboard",
"name": "Typing",
"binds": [
{ "keys": ["󰖳", "+", "V"], "action": "Clipboard history >> clipboard" },
{ "keys": ["󰖳", "+", "."], "action": "Emoji picker >> clipboard" },
],
"id": 7
},
{
"icon": "terminal",
"name": "Launcher actions",
"binds": [
{ "keys": [">raw"], "action": "Toggle mouse acceleration" },
{ "keys": [">img"], "action": "Select wallpaper and generate colorscheme" },
{ "keys": [">light"], "action": "Switch to light theme" },
{ "keys": [">dark"], "action": "Switch to dark theme" },
{ "keys": [">badapple"], "action": "Apply black n' white colorscheme" },
{ "keys": [">color"], "action": "Pick acccent color" },
{ "keys": [">todo"], "action": "Type something after that to add a To-do item" },
],
"id": 8
}
]];
-126
View File
@@ -1,126 +0,0 @@
const { GLib, Gtk } = imports.gi;
import App from "resource:///com/github/Aylur/ags/app.js";
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
import Widget from "resource:///com/github/Aylur/ags/widget.js";
import { IconTabContainer } from "../.commonwidgets/tabcontainer.js";
const { Box, Label, Scrollable } = Widget;
const HYPRLAND_KEYBIND_CONFIG_FILE = userOptions.cheatsheet.keybinds.configPath ?
userOptions.cheatsheet.keybinds.configPath : `${GLib.get_user_config_dir()}/hypr/hyprland/keybinds.conf`;
const KEYBIND_SECTIONS_PER_PAGE = 3;
const getKeybindList = () => {
let data = Utils.exec(`${App.configDir}/scripts/hyprland/get_keybinds.py --path ${HYPRLAND_KEYBIND_CONFIG_FILE}`);
if (data == "\"error\"") {
Utils.timeout(2000, () => Utils.execAsync(['notify-send',
'Update path to keybinds',
'Keybinds hyprland config file not found. Check your user options.',
'-a', 'ags',
]).catch(print))
return { children: [] };
}
return JSON.parse(data);
};
const keybindList = getKeybindList();
const keySubstitutions = {
"Super": "󰖳",
"mouse_up": "Scroll ↓", // ikr, weird
"mouse_down": "Scroll ↑", // trust me bro
"mouse:272": "LMB",
"mouse:273": "RMB",
"mouse:275": "MouseBack",
"Slash": "/",
"Hash": "#"
}
const substituteKey = (key) => {
return keySubstitutions[key] || key;
}
const Keybind = (keybindData, type) => { // type: either "keys" or "actions"
const Key = (key) => Label({ // Specific keys
vpack: 'center',
className: `${['OR', '+'].includes(key) ? 'cheatsheet-key-notkey' : 'cheatsheet-key'} txt-small`,
label: substituteKey(key),
});
const Action = (text) => Label({ // Binds
xalign: 0,
label: getString(text),
className: "txt txt-small cheatsheet-action",
})
return Widget.Box({
className: "spacing-h-10 cheatsheet-bind-lineheight",
children: type == "keys" ? [
...(keybindData.mods.length > 0 ? [
...keybindData.mods.map(Key),
Key("+"),
] : []),
Key(keybindData.key),
] : [Action(keybindData.comment)],
})
}
const Section = (sectionData, scope) => {
const keys = Box({
vertical: true,
className: 'spacing-v-5',
children: sectionData.keybinds.map((data) => Keybind(data, "keys"))
})
const actions = Box({
vertical: true,
className: 'spacing-v-5',
children: sectionData.keybinds.map((data) => Keybind(data, "actions"))
})
const name = Label({
xalign: 0,
className: "cheatsheet-category-title txt margin-bottom-10",
label: getString(sectionData.name),
})
const binds = Box({
className: 'spacing-h-10',
children: [
keys,
actions,
]
})
const childrenSections = Box({
vertical: true,
className: 'spacing-v-15',
children: sectionData.children.map((data) => Section(data, scope + 1))
})
return Box({
vertical: true,
children: [
...((sectionData.name && sectionData.name.length > 0) ? [name] : []),
Box({
className: 'spacing-v-10',
children: [
binds,
childrenSections,
]
})
]
})
};
export default () => {
const numOfTabs = Math.ceil(keybindList.children.length / KEYBIND_SECTIONS_PER_PAGE);
const keybindPages = Array.from({ length: numOfTabs }, (_, i) => ({
iconWidget: Label({
className: "txt txt-small",
label: `${i + 1}`,
}),
name: `${i + 1}`,
child: Box({
className: 'spacing-h-30',
children: keybindList.children.slice(
KEYBIND_SECTIONS_PER_PAGE * i, 0 + KEYBIND_SECTIONS_PER_PAGE * (i + 1),
).map(data => Section(data, 1)),
}),
}));
return IconTabContainer({
iconWidgets: keybindPages.map((kbp) => kbp.iconWidget),
names: keybindPages.map((kbp) => kbp.name),
children: keybindPages.map((kbp) => kbp.child),
});
};
-146
View File
@@ -1,146 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { setupCursorHover } from "../.widgetutils/cursorhover.js";
import PopupWindow from '../.widgethacks/popupwindow.js';
import Keybinds from "./keybinds.js";
import PeriodicTable from "./periodictable.js";
import { ExpandingIconTabContainer } from '../.commonwidgets/tabcontainer.js';
import { checkKeybind } from '../.widgetutils/keybind.js';
import clickCloseRegion from '../.commonwidgets/clickcloseregion.js';
const cheatsheets = [
{
name: getString('Keybinds'),
materialIcon: 'keyboard',
contentWidget: Keybinds,
},
{
name: getString('Periodic table'),
materialIcon: 'experiment',
contentWidget: PeriodicTable,
},
];
const CheatsheetHeader = () => Widget.CenterBox({
vertical: false,
startWidget: Widget.Box({}),
centerWidget: Widget.Box({
vertical: true,
className: "spacing-h-15",
children: [
Widget.Box({
hpack: 'center',
className: 'spacing-h-5 cheatsheet-title',
children: [
Widget.Label({
hpack: 'center',
css: 'margin-right: 0.682rem;',
className: 'txt-title',
label: getString('Cheat sheet'),
}),
Widget.Label({
vpack: 'center',
className: "cheatsheet-key txt-small",
label: "󰖳",
}),
Widget.Label({
vpack: 'center',
className: "cheatsheet-key-notkey txt-small",
label: "+",
}),
Widget.Label({
vpack: 'center',
className: "cheatsheet-key txt-small",
label: "/",
})
]
}),
]
}),
endWidget: Widget.Button({
vpack: 'start',
hpack: 'end',
className: "cheatsheet-closebtn icon-material txt txt-hugeass",
onClicked: () => {
closeWindowOnAllMonitors('cheatsheet');
},
child: Widget.Label({
className: 'icon-material txt txt-hugeass',
label: 'close'
}),
setup: setupCursorHover,
}),
});
const sheetContents = [];
const SheetContent = (id) => {
sheetContents[id] = ExpandingIconTabContainer({
tabsHpack: 'center',
tabSwitcherClassName: 'sidebar-icontabswitcher',
transitionDuration: userOptions.animations.durationLarge * 1.4,
icons: cheatsheets.map((api) => api.materialIcon),
names: cheatsheets.map((api) => api.name),
children: cheatsheets.map((api) => api.contentWidget()),
onChange: (self, id) => {
self.shown = cheatsheets[id].name;
}
});
return sheetContents[id];
}
export default (id) => {
const sheets = SheetContent(id);
const widgetContent = Widget.Box({
vertical: true,
className: "cheatsheet-bg spacing-v-5",
children: [
CheatsheetHeader(),
sheets,
]
});
return PopupWindow({
monitor: id,
name: `cheatsheet${id}`,
layer: 'top',
keymode: 'on-demand',
visible: false,
anchor: ['top', 'bottom', 'left', 'right'],
child: Widget.Box({
vertical: true,
children: [
clickCloseRegion({ name: 'cheatsheet' }),
Widget.Box({
children: [
clickCloseRegion({ name: 'cheatsheet' }),
widgetContent,
clickCloseRegion({ name: 'cheatsheet' }),
]
}),
clickCloseRegion({ name: 'cheatsheet' }),
],
setup: (self) => self.on('key-press-event', (widget, event) => { // Typing
// Whole sheet
if (checkKeybind(event, userOptions.keybinds.cheatsheet.nextTab))
sheetContents.forEach(tab => tab.nextTab())
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.prevTab))
sheetContents.forEach(tab => tab.prevTab())
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.cycleTab))
sheetContents.forEach(tab => tab.cycleTab())
// Keybinds
if (sheets.attribute.names[sheets.attribute.shown.value] == 'Keybinds') { // If Keybinds tab is focused
if (checkKeybind(event, userOptions.keybinds.cheatsheet.keybinds.nextTab)) {
sheetContents.forEach((sheet) => {
const toSwitchTab = sheet.attribute.children[sheet.attribute.shown.value];
toSwitchTab.nextTab();
})
}
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.keybinds.prevTab)) {
sheetContents.forEach((sheet) => {
const toSwitchTab = sheet.attribute.children[sheet.attribute.shown.value];
toSwitchTab.prevTab();
})
}
}
})
})
});
}
@@ -1,94 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { niceTypes, periodicTable, series } from "./data_periodictable.js";
const { Box, Button, Icon, Label, Revealer } = Widget;
export default () => {
const ElementTile = (element) => {
return Box({
vertical: true,
tooltipText: element.electronConfig ? `${element.electronConfig}` : null,
className: `cheatsheet-periodictable-${element.type}`,
children: element.name == '' ? null : [
Box({
className: 'padding-left-8 padding-right-8 padding-top-8',
children: [
Label({
label: `${element.number}`,
className: "cheatsheet-periodictable-elementnum txt-tiny txt-bold",
}),
Box({ hexpand: true }),
Label({
label: `${element.weight}`,
className: "txt-smaller",
})
]
}),
element.icon ? Icon({
icon: element.icon,
className: "txt-hugerass txt-bold",
}) : Label({
label: `${element.symbol}`,
className: "cheatsheet-periodictable-elementsymbol",
}),
Label({
label: `${element.name}`,
className: "txt-tiny",
})
]
})
}
const BoardColor = (type) => Box({
className: 'spacing-h-5',
children: [
Box({
homogeneous: true,
className: `cheatsheet-periodictable-legend-color-wrapper`,
children: [Box({
className: `cheatsheet-periodictable-legend-color-${type}`,
})]
}),
Label({
label: `${niceTypes[type]}`,
className: "txt txt-small",
})
]
})
const mainBoard = Box({
hpack: 'center',
vertical: true,
className: "spacing-v-3",
children: periodicTable.map((row, _) => Box({ // Rows
className: "spacing-h-5",
children: row.map((element, _) => ElementTile(element))
})),
});
const seriesBoard = Box({
hpack: 'center',
vertical: true,
className: "spacing-v-3",
children: series.map((row, _) => Box({ // Rows
className: "spacing-h-5",
children: row.map((element, _) => ElementTile(element))
})),
});
const legend = Box({
hpack: 'center',
className: 'spacing-h-20',
children: [
BoardColor('metal'),
BoardColor('nonmetal'),
BoardColor('noblegas'),
BoardColor('lanthanum'),
BoardColor('actinium'),
]
})
return Box({
vertical: true,
className: 'spacing-v-20',
children: [
mainBoard,
seriesBoard,
legend
]
})
}
-21
View File
@@ -1,21 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
export default (monitor = 0, ) => {
return Widget.Window({
monitor,
name: `crosshair${monitor}`,
layer: 'overlay',
exclusivity: 'ignore',
visible: false,
child: Widget.Icon({
icon: 'crosshair-symbolic',
css: `
font-size: ${userOptions.gaming.crosshair.size}px;
color: ${userOptions.gaming.crosshair.color};
`,
}),
setup: enableClickthrough,
});
}
@@ -1,14 +0,0 @@
export const quickLaunchItems = [
{
"name": "GitHub + Files×2",
"command": "github-desktop & nautilus --new-window & nautilus --new-window &"
},
{
"name": "Terminal×2",
"command": "foot & foot &"
},
{
"name": "Discord + Youtube + Github",
"command": "xdg-open 'https://discord.com/app' && xdg-open 'https://youtube.com/' && xdg-open 'https://github.com/' &"
},
]
@@ -1,24 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import WallpaperImage from './wallpaper.js';
import TimeAndLaunchesWidget from './timeandlaunches.js'
import SystemWidget from './system.js'
export default (monitor) => Widget.Window({
name: `desktopbackground${monitor}`,
// anchor: ['top', 'bottom', 'left', 'right'],
layer: 'background',
exclusivity: 'ignore',
visible: true,
child: Widget.Overlay({
child: WallpaperImage(monitor),
// child: Widget.Box({}),
overlays: [
TimeAndLaunchesWidget(),
SystemWidget(),
],
setup: (self) => {
self.set_overlay_pass_through(self.get_children()[1], true);
},
}),
});
@@ -1,161 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
const { Box, EventBox, Label, Revealer, Overlay } = Widget;
import { AnimatedCircProg } from "../.commonwidgets/cairo_circularprogress.js";
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
const ResourceValue = (name, icon, interval, valueUpdateCmd, displayFunc, props = {}) => Box({
...props,
className: 'bg-system-bg txt',
children: [
Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
vpack: 'center',
vertical: true,
className: 'margin-right-15',
children: [
Label({
xalign: 1,
className: 'txt-small txt',
label: `${name}`,
}),
Label({
xalign: 1,
className: 'titlefont txt-norm txt-onSecondaryContainer',
setup: (self) => self
.poll(interval, (label) => displayFunc(label))
,
})
]
})
}),
Overlay({
child: AnimatedCircProg({
className: 'bg-system-circprog',
extraSetup: (self) => self
.poll(interval, (self) => {
execAsync(['bash', '-c', `${valueUpdateCmd}`]).then((newValue) => {
self.css = `font-size: ${Math.round(newValue)}px;`
}).catch(print);
})
,
}),
overlays: [
MaterialIcon(`${icon}`, 'hugeass'),
],
setup: self => self.set_overlay_pass_through(self.get_children()[1], true),
}),
]
})
const resources = Box({
vpack: 'fill',
vertical: true,
className: 'spacing-v-15',
children: [
ResourceValue('Memory', 'memory', 10000, `free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`,
(label) => {
execAsync(['bash', '-c', `free -h | awk '/^Mem/ {print $3 " / " $2}' | sed 's/Gi/Gib/g'`])
.then((output) => {
label.label = `${output}`
}).catch(print);
}, { hpack: 'end' }),
ResourceValue('Swap', 'swap_horiz', 10000, `free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`,
(label) => {
execAsync(['bash', '-c', `free -h | awk '/^Swap/ {if ($2 != "0") print $3 " / " $2; else print "No swap"}' | sed 's/Gi/Gib/g'`])
.then((output) => {
label.label = `${output}`
}).catch(print);
}, { hpack: 'end' }),
ResourceValue('Disk space', 'hard_drive_2', 3600000, `echo $(df --output=pcent / | tr -dc '0-9')`,
(label) => {
execAsync(['bash', '-c', `df -h --output=avail / | awk 'NR==2{print $1}'`])
.then((output) => {
label.label = `${output} available`
}).catch(print);
}, { hpack: 'end' }),
]
});
const distroAndVersion = Box({
vertical: true,
children: [
Box({
hpack: 'end',
children: [
Label({
className: 'bg-distro-txt',
xalign: 0,
label: 'Hyping on ',
}),
Label({
className: 'bg-distro-name',
xalign: 0,
label: '<distro>',
setup: (label) => {
execAsync([`grep`, `-oP`, `PRETTY_NAME="\\K[^"]+`, `/etc/os-release`]).then(distro => {
label.label = distro;
}).catch(print);
},
}),
]
}),
Box({
hpack: 'end',
children: [
Label({
className: 'bg-distro-txt',
xalign: 0,
label: 'with ',
}),
Label({
className: 'bg-distro-name',
xalign: 0,
label: 'An environment idk',
setup: (label) => {
// hyprctl will return unsuccessfully if Hyprland isn't running
execAsync([`bash`, `-c`, `hyprctl version | grep -oP "Tag: v\\K\\d+\\.\\d+\\.\\d+"`]).then(version => {
label.label = `Hyprland ${version}`;
}).catch(() => execAsync([`bash`, `-c`, `sway -v | cut -d'-' -f1 | sed 's/sway version /v/'`]).then(version => {
label.label = `Sway ${version}`;
}).catch(print));
},
}),
]
})
]
})
export default () => Box({
hpack: 'end',
vpack: 'end',
children: [
EventBox({
child: Box({
hpack: 'end',
vpack: 'end',
className: 'bg-distro-box spacing-v-20',
vertical: true,
children: [
resources,
distroAndVersion,
]
}),
onPrimaryClickRelease: () => {
const kids = resources.get_children();
for (let i = 0; i < kids.length; i++) {
const child = kids[i];
const firstChild = child.get_children()[0];
firstChild.revealChild = !firstChild.revealChild;
}
},
})
],
})
@@ -1,74 +0,0 @@
const { GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Service from 'resource:///com/github/Aylur/ags/service.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
const { execAsync, exec } = Utils;
const { Box, Label, Button, Revealer, EventBox } = Widget;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { quickLaunchItems } from './data_quicklaunches.js'
const TimeAndDate = () => Box({
vertical: true,
className: 'spacing-v--5',
children: [
Label({
className: 'bg-time-clock',
xalign: 0,
label: GLib.DateTime.new_now_local().format(userOptions.time.format),
setup: (self) => self.poll(userOptions.time.interval, label => {
label.label = GLib.DateTime.new_now_local().format(userOptions.time.format);
}),
}),
Label({
className: 'bg-time-date',
xalign: 0,
label: GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
setup: (self) => self.poll(userOptions.time.dateInterval, (label) => {
label.label = GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong);
}),
}),
]
})
const QuickLaunches = () => Box({
vertical: true,
className: 'spacing-v-10',
children: [
Label({
xalign: 0,
className: 'bg-quicklaunch-title',
label: 'Quick Launches',
}),
Box({
hpack: 'start',
className: 'spacing-h-5',
children: quickLaunchItems.map((item, i) => Button({
onClicked: () => {
execAsync(['bash', '-c', `${item["command"]}`]).catch(print);
},
className: 'bg-quicklaunch-btn',
child: Label({
label: `${item["name"]}`,
}),
setup: (self) => {
setupCursorHover(self);
}
})),
})
]
})
export default () => Box({
hpack: 'start',
vpack: 'end',
vertical: true,
className: 'bg-time-box spacing-h--10',
children: [
TimeAndDate(),
// QuickLaunches(),
],
})
@@ -1,119 +0,0 @@
const { Gdk, GdkPixbuf, Gio, GLib, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { exec, execAsync } = Utils;
const { Box, Button, Label, Stack } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
import Wallpaper from '../../services/wallpaper.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { clamp } from '../.miscutils/mathfuncs.js';
import { monitors } from '../.commondata/hyprlanddata.js';
const DISABLE_AGS_WALLPAPER = true;
const SWITCHWALL_SCRIPT_PATH = `${App.configDir}/scripts/color_generation/switchwall.sh`;
const WALLPAPER_ZOOM_SCALE = 1.25; // For scrolling when we switch workspace
const MAX_WORKSPACES = 10;
export default (monitor = 0) => {
const WALLPAPER_OFFSCREEN_X = (WALLPAPER_ZOOM_SCALE - 1) * monitors[monitor].width;
const WALLPAPER_OFFSCREEN_Y = (WALLPAPER_ZOOM_SCALE - 1) * monitors[monitor].height;
const wallpaperImage = Widget.DrawingArea({
attribute: {
pixbuf: undefined,
workspace: 1,
sideleft: 0,
sideright: 0,
updatePos: (self) => {
self.setCss(`font-size: ${self.attribute.workspace - self.attribute.sideleft + self.attribute.sideright}px;`)
},
},
className: 'bg-wallpaper-transition',
setup: (self) => {
self.set_size_request(monitors[monitor].width, monitors[monitor].height);
self
// TODO: reduced updates using timeouts to reduce lag
// .hook(Hyprland.active.workspace, (self) => {
// self.attribute.workspace = Hyprland.active.workspace.id
// self.attribute.updatePos(self);
// })
// .hook(App, (box, name, visible) => { // Update on open
// if (self.attribute[name] === undefined) return;
// self.attribute[name] = (visible ? 1 : 0);
// self.attribute.updatePos(self);
// })
.on('draw', (self, cr) => {
if (!self.attribute.pixbuf) return;
const styleContext = self.get_style_context();
const workspace = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
// Draw
Gdk.cairo_set_source_pixbuf(cr, self.attribute.pixbuf,
-(WALLPAPER_OFFSCREEN_X / (MAX_WORKSPACES + 1) * (clamp(workspace, 0, MAX_WORKSPACES + 1))),
-WALLPAPER_OFFSCREEN_Y / 2);
cr.paint();
})
.hook(Wallpaper, (self) => {
if (DISABLE_AGS_WALLPAPER) return;
const wallPath = Wallpaper.get(monitor);
if (!wallPath || wallPath === "") return;
self.attribute.pixbuf = GdkPixbuf.Pixbuf.new_from_file(wallPath);
const scale_x = monitors[monitor].width * WALLPAPER_ZOOM_SCALE / self.attribute.pixbuf.get_width();
const scale_y = monitors[monitor].height * WALLPAPER_ZOOM_SCALE / self.attribute.pixbuf.get_height();
const scale_factor = Math.max(scale_x, scale_y);
self.attribute.pixbuf = self.attribute.pixbuf.scale_simple(
Math.round(self.attribute.pixbuf.get_width() * scale_factor),
Math.round(self.attribute.pixbuf.get_height() * scale_factor),
GdkPixbuf.InterpType.BILINEAR
);
self.queue_draw();
}, 'updated');
;
}
,
});
const wallpaperPrompt = Box({
hpack: 'center',
vpack: 'center',
vertical: true,
className: 'spacing-v-10',
children: [
Label({
hpack: 'center',
justification: 'center',
className: 'txt-large',
label: `No wallpaper loaded.\nAn image ≥ ${monitors[monitor].width * WALLPAPER_ZOOM_SCALE} × ${monitors[monitor].height * WALLPAPER_ZOOM_SCALE} is recommended.`,
}),
Button({
hpack: 'center',
className: 'btn-primary',
label: `Select one`,
setup: setupCursorHover,
onClicked: (self) => Utils.execAsync([SWITCHWALL_SCRIPT_PATH]).catch(print),
}),
]
});
const stack = Stack({
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
children: {
'disabled': Box({}),
'image': wallpaperImage,
'prompt': wallpaperPrompt,
},
setup: (self) => self
.hook(Wallpaper, (self) => {
if (DISABLE_AGS_WALLPAPER) {
self.shown = 'disabled';
return;
}
const wallPath = Wallpaper.get(monitor);
self.shown = ((wallPath && wallPath != "") ? 'image' : 'prompt');
}, 'updated')
,
})
return stack;
// return wallpaperImage;
}
-300
View File
@@ -1,300 +0,0 @@
const { Gtk, GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { EventBox, Button } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
import Applications from 'resource:///com/github/Aylur/ags/service/applications.js';
const { execAsync, exec } = Utils;
const { Box, Revealer } = Widget;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { getAllFiles, searchIcons } from './icons.js'
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { substitute } from '../.miscutils/icons.js';
const icon_files = userOptions.icons.searchPaths.map(e => getAllFiles(e)).flat(1)
let isPinned = false
let cachePath = new Map()
let timers = []
function clearTimes() {
timers.forEach(e => GLib.source_remove(e))
timers = []
}
function ExclusiveWindow(client) {
const fn = [
(client) => !(client !== null && client !== undefined),
// Jetbrains
(client) => client.title.includes("win"),
// Vscode
(client) => client.title === '' && client.class === ''
]
for (const item of fn) { if (item(client)) { return true } }
return false
}
const focus = ({ address }) => Utils.execAsync(`hyprctl dispatch focuswindow address:${address}`).catch(print);
const DockSeparator = (props = {}) => Box({
...props,
className: 'dock-separator',
})
const PinButton = () => Widget.Button({
className: 'dock-app-btn dock-app-btn-animate',
tooltipText: 'Pin Dock',
child: Widget.Box({
homogeneous: true,
className: 'dock-app-icon txt',
child: MaterialIcon('push_pin', 'hugeass')
}),
onClicked: (self) => {
isPinned = !isPinned
self.className = `${isPinned ? "pinned-dock-app-btn" : "dock-app-btn animate"} dock-app-btn-animate`
},
setup: setupCursorHover,
})
const LauncherButton = () => Widget.Button({
className: 'dock-app-btn dock-app-btn-animate',
tooltipText: 'Open launcher',
child: Widget.Box({
homogeneous: true,
className: 'dock-app-icon txt',
child: MaterialIcon('apps', 'hugerass')
}),
onClicked: (self) => {
App.toggleWindow('overview');
},
setup: setupCursorHover,
})
const AppButton = ({ icon, ...rest }) => Widget.Revealer({
attribute: {
'workspace': 0
},
revealChild: false,
transition: 'slide_right',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Button({
...rest,
className: 'dock-app-btn dock-app-btn-animate',
child: Widget.Box({
child: Widget.Overlay({
child: Widget.Box({
homogeneous: true,
className: 'dock-app-icon',
child: Widget.Icon({
icon: icon,
}),
}),
overlays: [Widget.Box({
class_name: 'indicator',
vpack: 'end',
hpack: 'center',
})],
}),
}),
setup: (button) => {
setupCursorHover(button);
}
})
});
const Taskbar = (monitor) => Widget.Box({
className: 'dock-apps',
attribute: {
monitor: monitor,
'map': new Map(),
'clientSortFunc': (a, b) => {
return a.attribute.workspace > b.attribute.workspace;
},
'update': (box, monitor) => {
for (let i = 0; i < Hyprland.clients.length; i++) {
const client = Hyprland.clients[i];
if (client["pid"] == -1) return;
const appClass = substitute(client.class);
// for (const appName of userOptions.dock.pinnedApps) {
// if (appClass.includes(appName.toLowerCase()))
// return null;
// }
let appClassLower = appClass.toLowerCase()
let path = ''
if (cachePath[appClassLower]) { path = cachePath[appClassLower] }
else {
path = searchIcons(appClass.toLowerCase(), icon_files)
cachePath[appClassLower] = path
}
if (path === '') { path = substitute(appClass) }
const newButton = AppButton({
icon: path,
tooltipText: `${client.title} (${appClass})`,
onClicked: () => focus(client),
});
newButton.attribute.workspace = client.workspace.id;
newButton.revealChild = true;
box.attribute.map.set(client.address, newButton);
}
box.children = Array.from(box.attribute.map.values());
},
'add': (box, address, monitor) => {
if (!address) { // First active emit is undefined
box.attribute.update(box);
return;
}
const newClient = Hyprland.clients.find(client => {
return client.address == address;
});
if (ExclusiveWindow(newClient)) { return }
let appClass = newClient.class
let appClassLower = appClass.toLowerCase()
let path = ''
if (cachePath[appClassLower]) { path = cachePath[appClassLower] }
else {
path = searchIcons(appClassLower, icon_files)
cachePath[appClassLower] = path
}
if (path === '') { path = substitute(appClass) }
const newButton = AppButton({
icon: path,
tooltipText: `${newClient.title} (${appClass})`,
onClicked: () => focus(newClient),
})
newButton.attribute.workspace = newClient.workspace.id;
box.attribute.map.set(address, newButton);
box.children = Array.from(box.attribute.map.values());
newButton.revealChild = true;
},
'remove': (box, address) => {
if (!address) return;
const removedButton = box.attribute.map.get(address);
if (!removedButton) return;
removedButton.revealChild = false;
Utils.timeout(userOptions.animations.durationLarge, () => {
removedButton.destroy();
box.attribute.map.delete(address);
box.children = Array.from(box.attribute.map.values());
})
},
},
setup: (self) => {
self.hook(Hyprland, (box, address) => box.attribute.add(box, address, self.monitor), 'client-added')
.hook(Hyprland, (box, address) => box.attribute.remove(box, address, self.monitor), 'client-removed')
Utils.timeout(100, () => self.attribute.update(self));
},
});
const PinnedApps = () => Widget.Box({
class_name: 'dock-apps',
homogeneous: true,
children: userOptions.dock.pinnedApps
.map(term => ({ app: Applications.query(term)?.[0], term }))
.filter(({ app }) => app)
.map(({ app, term = true }) => {
const newButton = AppButton({
// different icon, emm...
icon: userOptions.dock.searchPinnedAppIcons ?
searchIcons(app.name, icon_files) :
app.icon_name,
onClicked: () => {
for (const client of Hyprland.clients) {
if (client.class.toLowerCase().includes(term))
return focus(client);
}
app.launch();
},
onMiddleClick: () => app.launch(),
tooltipText: app.name,
setup: (self) => {
self.revealChild = true;
self.hook(Hyprland, button => {
const running = Hyprland.clients
.find(client => client.class.toLowerCase().includes(term)) || false;
button.toggleClassName('notrunning', !running);
button.toggleClassName('focused', Hyprland.active.client.address == running.address);
button.set_tooltip_text(running ? running.title : app.name);
}, 'notify::clients')
},
})
newButton.revealChild = true;
return newButton;
}),
});
export default (monitor = 0) => {
const dockContent = Box({
className: 'dock-bg spacing-h-5',
children: [
PinButton(),
PinnedApps(),
DockSeparator(),
Taskbar(),
LauncherButton(),
]
})
const dockRevealer = Revealer({
attribute: {
'updateShow': self => { // I only use mouse to resize. I don't care about keyboard resize if that's a thing
if (userOptions.dock.monitorExclusivity)
self.revealChild = Hyprland.active.monitor.id === monitor;
else
self.revealChild = true;
return self.revealChild
}
},
revealChild: false,
transition: 'slide_up',
transitionDuration: userOptions.animations.durationLarge,
child: dockContent,
setup: (self) => {
const callback = (self, trigger) => {
if (!userOptions.dock.trigger.includes(trigger)) return
const flag = self.attribute.updateShow(self)
if (flag) clearTimes();
const hidden = userOptions.dock.autoHide.find(e => e["trigger"] === trigger)
if (hidden) {
let id = Utils.timeout(hidden.interval, () => {
if (!isPinned) { self.revealChild = false }
timers = timers.filter(e => e !== id)
})
timers.push(id)
}
}
self
// .hook(Hyprland, (self) => self.attribute.updateShow(self))
.hook(Hyprland.active.workspace, self => callback(self, "workspace-active"))
.hook(Hyprland.active.client, self => callback(self, "client-active"))
.hook(Hyprland, self => callback(self, "client-added"), "client-added")
.hook(Hyprland, self => callback(self, "client-removed"), "client-removed")
},
})
return EventBox({
onHover: () => {
dockRevealer.revealChild = true;
clearTimes()
},
child: Box({
homogeneous: true,
css: `min-height: ${userOptions.dock.hiddenThickness}px;`,
children: [dockRevealer],
}),
setup: self => self.on("leave-notify-event", () => {
if (!isPinned) dockRevealer.revealChild = false;
clearTimes()
})
})
}
-63
View File
@@ -1,63 +0,0 @@
const { Gio, GLib } = imports.gi
const exists = (path) => Gio.File.new_for_path(path).query_exists(null);
export const levenshteinDistance = (a, b) => {
if (!a.length) { return b.length }
if (!b.length) { return a.length }
let f = Array.from(new Array(a.length + 1),
() => new Array(b.length + 1).fill(0))
for (let i = 0; i <= b.length; i++) { f[0][i] = i; }
for (let i = 0; i <= a.length; i++) { f[i][0] = i; }
for (let i = 1; i <= a.length; i++) {
for (let j = 1; j <= b.length; j++) {
if (a.charAt(i - 1) === b.charAt(j - 1)) {
f[i][j] = f[i-1][j-1]
} else {
f[i][j] = Math.min(f[i-1][j-1], Math.min(f[i][j-1], f[i-1][j])) + 1
}
}
}
return f[a.length][b.length]
}
export const getAllFiles = (dir, files = []) => {
if (!exists(dir)) { return [] }
const file = Gio.File.new_for_path(dir);
const enumerator = file.enumerate_children('standard::name,standard::type',
Gio.FileQueryInfoFlags.NONE, null);
for (const info of enumerator) {
if (info.get_file_type() === Gio.FileType.DIRECTORY) {
files.push(getAllFiles(`${dir}/${info.get_name()}`))
} else {
files.push(`${dir}/${info.get_name()}`)
}
}
return files.flat(1);
}
export const searchIcons = (appClass, files) => {
appClass = appClass.toLowerCase()
if (!files.length) { return "" }
let appro = 0x3f3f3f3f
let path = ""
for (const item of files) {
let score = levenshteinDistance(item.split("/").pop().toLowerCase().split(".")[0], appClass)
if (score < appro) {
appro = score
path = item
}
}
return path
}
-12
View File
@@ -1,12 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Dock from './dock.js';
export default (monitor = 0) => Widget.Window({
monitor,
name: `dock${monitor}`,
layer: userOptions.dock.layer,
anchor: ['bottom'],
exclusivity: 'normal',
visible: true,
child: Dock(monitor),
});
@@ -1,236 +0,0 @@
const { Gio, GLib } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { ConfigToggle, ConfigMulipleSelection } from '../.commonwidgets/configwidgets.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync } = Utils;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { showColorScheme } from '../../variables.js';
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { darkMode } from '../.miscutils/system.js';
const ColorBox = ({
name = 'Color',
...rest
}) => Widget.Box({
...rest,
homogeneous: true,
children: [
Widget.Label({
label: `${name}`,
})
]
})
const ColorSchemeSettingsRevealer = () => {
const headerButtonIcon = MaterialIcon('expand_more', 'norm');
const header = Widget.Button({
className: 'osd-settings-btn-arrow',
onClicked: () => {
content.revealChild = !content.revealChild;
headerButtonIcon.label = content.revealChild ? 'expand_less' : 'expand_more';
},
setup: setupCursorHover,
hpack: 'end',
child: headerButtonIcon,
});
const content = Widget.Revealer({
revealChild: false,
transition: 'slide_down',
transitionDuration: 200,
child: ColorSchemeSettings(),
setup: (self) => self.hook(isHoveredColorschemeSettings, (revealer) => {
if (isHoveredColorschemeSettings.value == false) {
setTimeout(() => {
if (isHoveredColorschemeSettings.value == false)
revealer.revealChild = false;
headerButtonIcon.label = 'expand_more';
}, 1500);
}
}),
});
return Widget.EventBox({
onHover: (self) => {
isHoveredColorschemeSettings.setValue(true);
},
onHoverLost: (self) => {
isHoveredColorschemeSettings.setValue(false);
},
child: Widget.Box({
vertical: true,
children: [
header,
content,
]
}),
});
}
function calculateSchemeInitIndex(optionsArr, searchValue = 'vibrant') {
if (searchValue == '')
searchValue = 'vibrant';
const flatArray = optionsArr.flatMap(subArray => subArray);
const result = flatArray.findIndex(element => element.value === searchValue);
const rowIndex = Math.floor(result / optionsArr[0].length);
const columnIndex = result % optionsArr[0].length;
return [rowIndex, columnIndex];
}
const schemeOptionsArr = [
[
{ name: getString('Tonal Spot'), value: 'tonalspot' },
{ name: getString('Fruit Salad'), value: 'fruitsalad' },
{ name: getString('Fidelity'), value: 'fidelity' },
{ name: getString('Rainbow'), value: 'rainbow' },
],
[
{ name: getString('Neutral'), value: 'neutral' },
{ name: getString('Monochrome'), value: 'monochrome' },
{ name: getString('Expressive'), value: 'expressive' },
{ name: getString('Vibrant'), value: 'vibrant' },
],
[
{ name: getString('Vibrant+'), value: 'morevibrant' },
],
//[
// { name: getString('Content'), value: 'content' },
//]
];
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
const initTransparency = Utils.exec(`bash -c "sed -n \'2p\' ${LIGHTDARK_FILE_LOCATION}"`);
const initTransparencyVal = (initTransparency == "transparent") ? 1 : 0;
const initScheme = Utils.exec(`bash -c "sed -n \'3p\' ${LIGHTDARK_FILE_LOCATION}"`);
const initSchemeIndex = calculateSchemeInitIndex(schemeOptionsArr, initScheme);
const ColorSchemeSettings = () => Widget.Box({
className: 'osd-colorscheme-settings spacing-v-5 margin-20',
vertical: true,
vpack: 'center',
children: [
Widget.Box({
vertical: true,
children: [
Widget.Label({
xalign: 0,
className: 'txt-norm titlefont txt',
label: getString('Options'),
hpack: 'center',
}),
//////////////////
ConfigToggle({
icon: 'dark_mode',
name: getString('Dark Mode'),
desc: getString('Ya should go to sleep!'),
initValue: darkMode.value,
onChange: (_, newValue) => {
darkMode.value = !!newValue;
},
extraSetup: (self) => self.hook(darkMode, (self) => {
self.attribute.enabled.value = darkMode.value;
}),
}),
ConfigToggle({
icon: 'border_clear',
name: getString('Transparency'),
desc: getString('Make shell elements transparent'),
initValue: initTransparencyVal,
onChange: (self, newValue) => {
let transparency = newValue == 0 ? "opaque" : "transparent";
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "2s/.*/${transparency}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
},
}),
]
}),
Widget.Box({
vertical: true,
className: 'spacing-v-5',
children: [
Widget.Label({
xalign: 0,
className: 'txt-norm titlefont txt margin-top-5',
label: getString('Scheme styles'),
hpack: 'center',
}),
//////////////////
ConfigMulipleSelection({
hpack: 'center',
vpack: 'center',
optionsArr: schemeOptionsArr,
initIndex: initSchemeIndex,
onChange: (value, name) => {
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "3s/.*/${value}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
},
}),
]
})
]
});
const ColorschemeContent = () => Widget.Box({
className: 'osd-colorscheme spacing-v-5',
vertical: true,
hpack: 'center',
children: [
Widget.Label({
xalign: 0,
className: 'txt-norm titlefont txt',
label: getString('Color scheme'),
hpack: 'center',
}),
Widget.Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
ColorBox({ name: 'P', className: 'osd-color osd-color-primary' }),
ColorBox({ name: 'S', className: 'osd-color osd-color-secondary' }),
ColorBox({ name: 'T', className: 'osd-color osd-color-tertiary' }),
ColorBox({ name: 'Sf', className: 'osd-color osd-color-surface' }),
ColorBox({ name: 'Sf-i', className: 'osd-color osd-color-inverseSurface' }),
ColorBox({ name: 'E', className: 'osd-color osd-color-error' }),
]
}),
Widget.Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
ColorBox({ name: 'P-c', className: 'osd-color osd-color-primaryContainer' }),
ColorBox({ name: 'S-c', className: 'osd-color osd-color-secondaryContainer' }),
ColorBox({ name: 'T-c', className: 'osd-color osd-color-tertiaryContainer' }),
ColorBox({ name: 'Sf-c', className: 'osd-color osd-color-surfaceContainer' }),
ColorBox({ name: 'Sf-v', className: 'osd-color osd-color-surfaceVariant' }),
ColorBox({ name: 'E-c', className: 'osd-color osd-color-errorContainer' }),
]
}),
ColorSchemeSettingsRevealer(),
]
});
const isHoveredColorschemeSettings = Variable(false);
export default () => Widget.Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: ColorschemeContent(),
setup: (self) => {
self
.hook(showColorScheme, (revealer) => {
if (showColorScheme.value == true)
revealer.revealChild = true;
else
revealer.revealChild = isHoveredColorschemeSettings.value;
})
.hook(isHoveredColorschemeSettings, (revealer) => {
if (isHoveredColorschemeSettings.value == false) {
setTimeout(() => {
if (isHoveredColorschemeSettings.value == false)
revealer.revealChild = showColorScheme.value;
}, 2000);
}
})
},
})
@@ -1,133 +0,0 @@
// This file is for brightness/volume indicators
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
const { Box, Label, ProgressBar } = Widget;
import { MarginRevealer } from '../.widgethacks/advancedrevealers.js';
import Brightness from '../../services/brightness.js';
import Indicator from '../../services/indicator.js';
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
const OsdValue = ({
name, icon, nameSetup = undefined, labelSetup, progressSetup,
extraClassName = '', extraProgressClassName = '',
...rest
}) => {
const valueName = Label({
xalign: 0, yalign: 0, hexpand: true,
className: 'osd-label',
label: `${name}`,
setup: nameSetup,
});
const valueNumber = Label({
hexpand: false, className: 'osd-value-txt',
setup: labelSetup,
});
return Box({ // Volume
hexpand: true,
className: `osd-bg osd-value ${extraClassName} spacing-h-5`,
attribute: {
'disable': () => {
valueNumber.label = '󰖭';
}
},
children: [
MaterialIcon(icon, 'hugeass', {vpack: 'center'}),
Box({
vertical: true,
className: 'spacing-v-5',
vpack: 'center',
children: [
Box({
children: [
valueName,
valueNumber,
]
}),
ProgressBar({
className: `osd-progress ${extraProgressClassName}`,
hexpand: true,
vertical: false,
setup: progressSetup,
})
]
})
],
...rest,
});
}
export default (monitor = 0) => {
const brightnessIndicator = OsdValue({
name: 'Brightness',
icon: 'light_mode',
extraClassName: 'osd-brightness',
extraProgressClassName: 'osd-brightness-progress',
labelSetup: (self) => self.hook(Brightness[monitor], self => {
self.label = `${Math.round(Brightness[monitor].screen_value * 100)}`;
}, 'notify::screen-value'),
progressSetup: (self) => self.hook(Brightness[monitor], (progress) => {
const updateValue = Brightness[monitor].screen_value;
if (updateValue !== progress.value) Indicator.popup(1);
progress.value = updateValue;
}, 'notify::screen-value'),
});
const volumeIndicator = OsdValue({
name: 'Volume',
icon: 'volume_up',
extraClassName: 'osd-volume',
extraProgressClassName: 'osd-volume-progress',
attribute: { headphones: undefined , device: undefined},
nameSetup: (self) => Utils.timeout(1, () => {
const updateAudioDevice = (self) => {
const usingHeadphones = (Audio.speaker?.stream?.port)?.toLowerCase().includes('headphone');
if (volumeIndicator.attribute.headphones === undefined ||
volumeIndicator.attribute.headphones !== usingHeadphones) {
volumeIndicator.attribute.headphones = usingHeadphones;
self.label = usingHeadphones ? 'Headphones' : 'Speakers';
// Indicator.popup(1);
}
}
self.hook(Audio, updateAudioDevice);
Utils.timeout(1000, updateAudioDevice);
}),
labelSetup: (self) => self.hook(Audio, (label) => {
const newDevice = (Audio.speaker?.name);
const updateValue = Math.round(Audio.speaker?.volume * 100);
if (!isNaN(updateValue)) {
if (newDevice === volumeIndicator.attribute.device && updateValue != label.label) {
Indicator.popup(1);
}
}
volumeIndicator.attribute.device = newDevice;
label.label = `${updateValue}`;
}),
progressSetup: (self) => self.hook(Audio, (progress) => {
const updateValue = Audio.speaker?.volume;
if (!isNaN(updateValue)) {
if (updateValue > 1) progress.value = 1;
else progress.value = updateValue;
}
}),
});
return MarginRevealer({
transition: 'slide_down',
showClass: 'osd-show',
hideClass: 'osd-hide',
extraSetup: (self) => self
.hook(Indicator, (revealer, value) => {
if (value > -1) revealer.attribute.show();
else revealer.attribute.hide();
}, 'popup')
,
child: Box({
hpack: 'center',
vertical: false,
className: 'spacing-h--10',
children: [
brightnessIndicator,
volumeIndicator,
]
})
});
}
-32
View File
@@ -1,32 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Indicator from '../../services/indicator.js';
import IndicatorValues from './indicatorvalues.js';
import MusicControls from './musiccontrols.js';
import ColorScheme from './colorscheme.js';
import NotificationPopups from './notificationpopups.js';
export default (monitor = 0) => Widget.Window({
name: `indicator${monitor}`,
monitor,
className: 'indicator',
layer: 'overlay',
// exclusivity: 'ignore',
visible: true,
anchor: ['top'],
child: Widget.EventBox({
onHover: () => { //make the widget hide when hovering
Indicator.popup(-1);
},
child: Widget.Box({
vertical: true,
className: 'osd-window',
css: 'min-height: 2px;',
children: [
IndicatorValues(monitor),
MusicControls(),
NotificationPopups(),
ColorScheme(),
]
})
}),
});
@@ -1,412 +0,0 @@
const { GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
const { exec, execAsync } = Utils;
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
import { fileExists } from '../.miscutils/files.js';
import { AnimatedCircProg } from "../.commonwidgets/cairo_circularprogress.js";
import { showMusicControls } from '../../variables.js';
import { darkMode, hasPlasmaIntegration } from '../.miscutils/system.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
const colorMode = Utils.exec(`bash -c "sed -n \'1p\' '${LIGHTDARK_FILE_LOCATION}'"`);
const lightDark = (colorMode == "light") ? 'light' : '';
const COVER_COLORSCHEME_SUFFIX = '_colorscheme.css';
var lastCoverPath = '';
function isRealPlayer(player) {
return (
// Remove unecessary native buses from browsers if there's plasma integration
!(hasPlasmaIntegration && player.busName.startsWith('org.mpris.MediaPlayer2.firefox')) &&
!(hasPlasmaIntegration && player.busName.startsWith('org.mpris.MediaPlayer2.chromium')) &&
// playerctld just copies other buses and we don't need duplicates
!player.busName.startsWith('org.mpris.MediaPlayer2.playerctld') &&
// Non-instance mpd bus
!(player.busName.endsWith('.mpd') && !player.busName.endsWith('MediaPlayer2.mpd'))
);
}
export const getPlayer = (name = userOptions.music.preferredPlayer) => Mpris.getPlayer(name) || Mpris.players[0] || null;
function lengthStr(length) {
const min = Math.floor(length / 60);
const sec = Math.floor(length % 60);
const sec0 = sec < 10 ? '0' : '';
return `${min}:${sec0}${sec}`;
}
function detectMediaSource(link) {
if (link.startsWith("file://")) {
if (link.includes('firefox-mpris'))
return '󰈹 Firefox'
return "󰈣 File";
}
let url = link.replace(/(^\w+:|^)\/\//, '');
let domain = url.match(/(?:[a-z]+\.)?([a-z]+\.[a-z]+)/i)[1];
if (domain == 'ytimg.com') return '󰗃 Youtube';
if (domain == 'discordapp.net') return '󰙯 Discord';
if (domain == 'sndcdn.com') return '󰓀 SoundCloud';
return domain;
}
const DEFAULT_MUSIC_FONT = 'Gabarito, sans-serif';
function getTrackfont(player) {
const title = player.trackTitle;
const artists = player.trackArtists.join(' ');
if (artists.includes('TANO*C') || artists.includes('USAO') || artists.includes('Kobaryo'))
return 'Chakra Petch'; // Rigid square replacement
if (title.includes('東方'))
return 'Crimson Text, serif'; // Serif for Touhou stuff
return DEFAULT_MUSIC_FONT;
}
function trimTrackTitle(title) {
if (!title) return '';
const cleanPatterns = [
/【[^】]*】/, // Touhou n weeb stuff
" [FREE DOWNLOAD]", // F-777
];
cleanPatterns.forEach((expr) => title = title.replace(expr, ''));
return title;
}
const TrackProgress = ({ player, ...rest }) => {
const _updateProgress = (circprog) => {
// const player = Mpris.getPlayer();
if (!player) return;
// Set circular progress (see definition of AnimatedCircProg for explanation)
circprog.css = `font-size: ${Math.max(player.position / player.length * 100, 0)}px;`
}
return AnimatedCircProg({
...rest,
className: 'osd-music-circprog',
vpack: 'center',
extraSetup: (self) => self
.hook(Mpris, _updateProgress)
.poll(3000, _updateProgress)
,
})
}
const TrackTitle = ({ player, ...rest }) => Label({
...rest,
label: 'No music playing',
xalign: 0,
truncate: 'end',
// wrap: true,
className: 'osd-music-title',
setup: (self) => self.hook(player, (self) => {
// Player name
self.label = player.trackTitle.length > 0 ? trimTrackTitle(player.trackTitle) : 'No media';
// Font based on track/artist
const fontForThisTrack = getTrackfont(player);
self.css = `font-family: ${fontForThisTrack}, ${DEFAULT_MUSIC_FONT};`;
}, 'notify::track-title'),
});
const TrackArtists = ({ player, ...rest }) => Label({
...rest,
xalign: 0,
className: 'osd-music-artists',
truncate: 'end',
setup: (self) => self.hook(player, (self) => {
self.label = player.trackArtists.length > 0 ? player.trackArtists.join(', ') : '';
}, 'notify::track-artists'),
})
const CoverArt = ({ player, ...rest }) => {
const fallbackCoverArt = Box({ // Fallback
className: 'osd-music-cover-fallback',
homogeneous: true,
children: [Label({
className: 'icon-material txt-gigantic txt-thin',
label: 'music_note',
})]
});
// const coverArtDrawingArea = Widget.DrawingArea({ className: 'osd-music-cover-art' });
// const coverArtDrawingAreaStyleContext = coverArtDrawingArea.get_style_context();
const realCoverArt = Box({
className: 'osd-music-cover-art',
homogeneous: true,
// children: [coverArtDrawingArea],
attribute: {
'pixbuf': null,
// 'showImage': (self, imagePath) => {
// const borderRadius = coverArtDrawingAreaStyleContext.get_property('border-radius', Gtk.StateFlags.NORMAL);
// const frameHeight = coverArtDrawingAreaStyleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
// const frameWidth = coverArtDrawingAreaStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
// let imageHeight = frameHeight;
// let imageWidth = frameWidth;
// // Get image dimensions
// execAsync(['identify', '-format', '{"w":%w,"h":%h}', imagePath])
// .then((output) => {
// const imageDimensions = JSON.parse(output);
// const imageAspectRatio = imageDimensions.w / imageDimensions.h;
// const displayedAspectRatio = imageWidth / imageHeight;
// if (imageAspectRatio >= displayedAspectRatio) {
// imageWidth = imageHeight * imageAspectRatio;
// } else {
// imageHeight = imageWidth / imageAspectRatio;
// }
// // Real stuff
// // TODO: fix memory leak(?)
// // if (self.attribute.pixbuf) {
// // self.attribute.pixbuf.unref();
// // self.attribute.pixbuf = null;
// // }
// self.attribute.pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imagePath, imageWidth, imageHeight);
// coverArtDrawingArea.set_size_request(frameWidth, frameHeight);
// coverArtDrawingArea.connect("draw", (widget, cr) => {
// // Clip a rounded rectangle area
// cr.arc(borderRadius, borderRadius, borderRadius, Math.PI, 1.5 * Math.PI);
// cr.arc(frameWidth - borderRadius, borderRadius, borderRadius, 1.5 * Math.PI, 2 * Math.PI);
// cr.arc(frameWidth - borderRadius, frameHeight - borderRadius, borderRadius, 0, 0.5 * Math.PI);
// cr.arc(borderRadius, frameHeight - borderRadius, borderRadius, 0.5 * Math.PI, Math.PI);
// cr.closePath();
// cr.clip();
// // Paint image as bg, centered
// Gdk.cairo_set_source_pixbuf(cr, self.attribute.pixbuf,
// frameWidth / 2 - imageWidth / 2,
// frameHeight / 2 - imageHeight / 2
// );
// cr.paint();
// });
// }).catch(print)
// },
'updateCover': (self) => {
// const player = Mpris.getPlayer(); // Maybe no need to re-get player.. can't remember why I had this
// Player closed
// Note that cover path still remains, so we're checking title
if (!player || player.trackTitle == "" || !player.coverPath) {
self.css = `background-image: none;`; // CSS image
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`);
return;
}
const coverPath = player.coverPath;
const stylePath = `${player.coverPath}${darkMode.value ? '' : '-l'}${COVER_COLORSCHEME_SUFFIX}`;
if (player.coverPath == lastCoverPath) { // Since 'notify::cover-path' emits on cover download complete
Utils.timeout(200, () => {
// self.attribute.showImage(self, coverPath);
self.css = `background-image: url('${coverPath}');`; // CSS image
});
}
lastCoverPath = player.coverPath;
// If a colorscheme has already been generated, skip generation
if (fileExists(stylePath)) {
// self.attribute.showImage(self, coverPath)
self.css = `background-image: url('${coverPath}');`; // CSS image
App.applyCss(stylePath);
return;
}
// Generate colors
execAsync(['bash', '-c',
`${App.configDir}/scripts/color_generation/generate_colors_material.py --path '${coverPath}' --mode ${darkMode.value ? 'dark' : 'light'} > ${GLib.get_user_state_dir()}/ags/scss/_musicmaterial.scss`])
.then(() => {
exec(`${App.configDir}/scripts/color_generation/pywal.sh -i "${player.coverPath}" -n -t -s -e -q ${darkMode.value ? '' : '-l'}`)
exec(`cp ${GLib.get_user_cache_dir()}/wal/colors.scss ${GLib.get_user_state_dir()}/ags/scss/_musicwal.scss`);
exec(`sass -I "${GLib.get_user_state_dir()}/ags/scss" -I "${App.configDir}/scss/fallback" "${App.configDir}/scss/_music.scss" "${stylePath}"`);
Utils.timeout(200, () => {
// self.attribute.showImage(self, coverPath)
self.css = `background-image: url('${coverPath}');`; // CSS image
});
App.applyCss(`${stylePath}`);
})
.catch(print);
},
},
setup: (self) => self
.hook(player, (self) => {
self.attribute.updateCover(self);
}, 'notify::cover-path')
,
});
return Box({
...rest,
className: 'osd-music-cover',
children: [
Widget.Overlay({
child: fallbackCoverArt,
overlays: [realCoverArt],
})
],
})
}
const TrackControls = ({ player, ...rest }) => Widget.Revealer({
revealChild: false,
transition: 'slide_right',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
...rest,
vpack: 'center',
className: 'osd-music-controls spacing-h-3',
children: [
Button({
className: 'osd-music-controlbtn',
onClicked: () => player.previous(),
child: Label({
className: 'icon-material osd-music-controlbtn-txt',
label: 'skip_previous',
}),
setup: setupCursorHover
}),
Button({
className: 'osd-music-controlbtn',
onClicked: () => player.next(),
child: Label({
className: 'icon-material osd-music-controlbtn-txt',
label: 'skip_next',
}),
setup: setupCursorHover
}),
],
}),
setup: (self) => self.hook(Mpris, (self) => {
// const player = Mpris.getPlayer();
if (!player)
self.revealChild = false;
else
self.revealChild = true;
}, 'notify::play-back-status'),
});
const TrackSource = ({ player, ...rest }) => Widget.Revealer({
revealChild: false,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
...rest,
className: 'osd-music-pill spacing-h-5',
homogeneous: true,
children: [
Label({
hpack: 'fill',
justification: 'center',
className: 'icon-nerd',
setup: (self) => self.hook(player, (self) => {
self.label = detectMediaSource(player.trackCoverUrl);
}, 'notify::cover-path'),
}),
],
}),
setup: (self) => self.hook(Mpris, (self) => {
const mpris = Mpris.getPlayer('');
if (!mpris)
self.revealChild = false;
else
self.revealChild = true;
}),
});
const TrackTime = ({ player, ...rest }) => {
return Widget.Revealer({
revealChild: false,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
...rest,
vpack: 'center',
className: 'osd-music-pill spacing-h-5',
children: [
Label({
setup: (self) => self.poll(1000, (self) => {
// const player = Mpris.getPlayer();
if (!player) return;
self.label = lengthStr(player.position);
}),
}),
Label({ label: '/' }),
Label({
setup: (self) => self.hook(Mpris, (self) => {
// const player = Mpris.getPlayer();
if (!player) return;
self.label = lengthStr(player.length);
}),
}),
],
}),
setup: (self) => self.hook(Mpris, (self) => {
if (!player) self.revealChild = false;
else self.revealChild = true;
}),
})
}
const PlayState = ({ player }) => {
var position = 0;
const trackCircProg = TrackProgress({ player: player });
return Widget.Button({
className: 'osd-music-playstate',
child: Widget.Overlay({
child: trackCircProg,
overlays: [
Widget.Button({
className: 'osd-music-playstate-btn',
onClicked: () => player.playPause(),
child: Widget.Label({
justification: 'center',
hpack: 'fill',
vpack: 'center',
setup: (self) => self.hook(player, (label) => {
label.label = `${player.playBackStatus == 'Playing' ? 'pause' : 'play_arrow'}`;
}, 'notify::play-back-status'),
}),
setup: setupCursorHover
}),
],
passThrough: true,
}),
});
}
const MusicControlsWidget = (player) => Box({
className: 'osd-music spacing-h-20 test',
children: [
CoverArt({ player: player, vpack: 'center' }),
Box({
vertical: true,
className: 'spacing-v-5 osd-music-info',
children: [
Box({
vertical: true,
vpack: 'center',
hexpand: true,
children: [
TrackTitle({ player: player }),
TrackArtists({ player: player }),
]
}),
Box({ vexpand: true }),
Box({
className: 'spacing-h-10',
setup: (box) => {
box.pack_start(TrackControls({ player: player }), false, false, 0);
box.pack_end(PlayState({ player: player }), false, false, 0);
if(hasPlasmaIntegration || player.busName.startsWith('org.mpris.MediaPlayer2.chromium')) box.pack_end(TrackTime({ player: player }), false, false, 0)
// box.pack_end(TrackSource({ vpack: 'center', player: player }), false, false, 0);
}
})
]
})
]
})
export default () => Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
revealChild: false,
child: Box({
children: Mpris.bind("players")
.as(players => players.map((player) => (isRealPlayer(player) ? MusicControlsWidget(player) : null)))
}),
setup: (self) => self.hook(showMusicControls, (revealer) => {
revealer.revealChild = showMusicControls.value;
}),
})
@@ -1,45 +0,0 @@
// This file is for popup notifications
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
const { Box } = Widget;
import Notification from '../.commonwidgets/notification.js';
export default () => Box({
vertical: true,
hpack: 'center',
className: 'osd-notifs spacing-v-5-revealer',
attribute: {
'map': new Map(),
'dismiss': (box, id, force = false) => {
if (!id || !box.attribute.map.has(id))
return;
const notifWidget = box.attribute.map.get(id);
if (notifWidget == null || notifWidget.attribute.hovered && !force)
return; // cuz already destroyed
notifWidget.revealChild = false;
notifWidget.attribute.destroyWithAnims();
box.attribute.map.delete(id);
},
'notify': (box, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
box.attribute.map.delete(id);
const notif = Notifications.getNotification(id);
const newNotif = Notification({
notifObject: notif,
isPopup: true,
});
box.attribute.map.set(id, newNotif);
box.pack_end(box.attribute.map.get(id), false, false, 0);
box.show_all();
},
},
setup: (self) => self
.hook(Notifications, (box, id) => box.attribute.notify(box, id), 'notified')
.hook(Notifications, (box, id) => box.attribute.dismiss(box, id), 'dismissed')
.hook(Notifications, (box, id) => box.attribute.dismiss(box, id, true), 'closed')
,
});
@@ -1,11 +0,0 @@
import PopupWindow from '../.widgethacks/popupwindow.js';
import OnScreenKeyboard from "./onscreenkeyboard.js";
export default (id) => PopupWindow({
monitor: id,
anchor: ['bottom'],
name: `osk${id}`,
showClassName: 'osk-show',
hideClassName: 'osk-hide',
child: OnScreenKeyboard({ id: id }),
});
@@ -1,267 +0,0 @@
const { Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, EventBox, Button, Revealer } = Widget;
const { execAsync } = Utils;
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { DEFAULT_OSK_LAYOUT, oskLayouts } from './data_keyboardlayouts.js';
import { setupCursorHoverGrab } from '../.widgetutils/cursorhover.js';
const keyboardLayout = oskLayouts[userOptions.onScreenKeyboard.layout] ? userOptions.onScreenKeyboard.layout : DEFAULT_OSK_LAYOUT;
const keyboardJson = oskLayouts[keyboardLayout];
async function startYdotoolIfNeeded() {
const running = exec('pidof ydotool')
if (!running) execAsync(['ydotoold']).catch(print);
}
function releaseAllKeys() {
const keycodes = Array.from(Array(249).keys());
execAsync([`ydotool`, `key`, ...keycodes.map(keycode => `${keycode}:0`)])
.then(console.log('[OSK] Released all keys'))
.catch(print);
}
class ShiftMode {
static Off = new ShiftMode('Off');
static Normal = new ShiftMode('Normal');
static Locked = new ShiftMode('Locked');
constructor(name) {
this.name = name;
}
toString() {
return `ShiftMode.${this.name}`;
}
}
var modsPressed = false;
const TopDecor = () => Box({
vertical: true,
children: [
Box({
hpack: 'center',
className: 'osk-dragline',
homogeneous: true,
children: [EventBox({
setup: setupCursorHoverGrab,
})]
})
]
});
const KeyboardControlButton = (icon, text, runFunction) => Button({
className: 'osk-control-button spacing-h-10',
onClicked: () => runFunction(),
child: Widget.Box({
children: [
MaterialIcon(icon, 'norm'),
Widget.Label({
label: `${text}`,
}),
]
})
})
const KeyboardControls = () => Box({
vertical: true,
className: 'spacing-v-5',
children: [
Button({
className: 'osk-control-button txt-norm icon-material',
onClicked: () => {
releaseAllKeys();
toggleWindowOnAllMonitors('osk');
},
label: 'keyboard_hide',
}),
Button({
className: 'osk-control-button txt-norm',
label: `${keyboardJson['name_short']}`,
}),
Button({
className: 'osk-control-button txt-norm icon-material',
onClicked: () => { // TODO: Proper clipboard widget, since fuzzel doesn't receive mouse inputs
execAsync([`bash`, `-c`, "pkill fuzzel || cliphist list | fuzzel --match-mode fzf --dmenu | cliphist decode | wl-copy"]).catch(print);
},
label: 'assignment',
}),
]
})
var shiftMode = ShiftMode.Off;
var shiftButton;
var rightShiftButton;
var allButtons = [];
const KeyboardItself = (kbJson) => {
return Box({
vertical: true,
className: 'spacing-v-5',
children: kbJson.keys.map(row => Box({
vertical: false,
className: 'spacing-h-5',
children: row.map(key => {
return Button({
className: `osk-key osk-key-${key.shape}`,
hexpand: ["space", "expand"].includes(key.shape),
label: key.label,
attribute:
{ key: key },
setup: (button) => {
let pressed = false;
allButtons = allButtons.concat(button);
if (key.keytype == "normal") {
button.connect('pressed', () => { // mouse down
execAsync(`ydotool key ${key.keycode}:1`).catch(print);
});
button.connect('clicked', () => { // release
execAsync(`ydotool key ${key.keycode}:0`).catch(print);
if (shiftMode == ShiftMode.Normal) {
shiftMode = ShiftMode.Off;
if (typeof shiftButton !== 'undefined') {
execAsync(`ydotool key 42:0`).catch(print);
shiftButton.toggleClassName('osk-key-active', false);
}
if (typeof rightShiftButton !== 'undefined') {
execAsync(`ydotool key 54:0`).catch(print);
rightShiftButton.toggleClassName('osk-key-active', false);
}
allButtons.forEach(button => {
if (typeof button.attribute.key.labelShift !== 'undefined') button.label = button.attribute.key.label;
})
}
});
}
else if (key.keytype == "modkey") {
button.connect('pressed', () => { // release
if (pressed) {
execAsync(`ydotool key ${key.keycode}:0`).catch(print);
button.toggleClassName('osk-key-active', false);
pressed = false;
if (key.keycode == 100) { // Alt Gr button
allButtons.forEach(button => { if (typeof button.attribute.key.labelAlt !== 'undefined') button.label = button.attribute.key.label; });
}
}
else {
execAsync(`ydotool key ${key.keycode}:1`).catch(print);
button.toggleClassName('osk-key-active', true);
if (!(key.keycode == 42 || key.keycode == 54)) pressed = true;
else switch (shiftMode.name) { // This toggles the shift button state
case "Off": {
shiftMode = ShiftMode.Normal;
allButtons.forEach(button => { if (typeof button.attribute.key.labelShift !== 'undefined') button.label = button.attribute.key.labelShift; })
if (typeof shiftButton !== 'undefined') {
shiftButton.toggleClassName('osk-key-active', true);
}
if (typeof rightShiftButton !== 'undefined') {
rightShiftButton.toggleClassName('osk-key-active', true);
}
} break;
case "Normal": {
shiftMode = ShiftMode.Locked;
if (typeof shiftButton !== 'undefined') shiftButton.label = key.labelCaps;
if (typeof rightShiftButton !== 'undefined') rightShiftButton.label = key.labelCaps;
} break;
case "Locked": {
shiftMode = ShiftMode.Off;
if (typeof shiftButton !== 'undefined') {
shiftButton.label = key.label;
shiftButton.toggleClassName('osk-key-active', false);
}
if (typeof rightShiftButton !== 'undefined') {
rightShiftButton.label = key.label;
rightShiftButton.toggleClassName('osk-key-active', false);
}
execAsync(`ydotool key ${key.keycode}:0`).catch(print);
allButtons.forEach(button => { if (typeof button.attribute.key.labelShift !== 'undefined') button.label = button.attribute.key.label; }
)
};
}
if (key.keycode == 100) { // Alt Gr button
allButtons.forEach(button => { if (typeof button.attribute.key.labelAlt !== 'undefined') button.label = button.attribute.key.labelAlt; });
}
modsPressed = true;
}
});
if (key.keycode == 42) shiftButton = button;
else if (key.keycode == 54) rightShiftButton = button;
}
}
})
})
}))
})
}
const KeyboardWindow = () => Box({
vexpand: true,
hexpand: true,
vertical: true,
className: 'osk-window spacing-v-5',
children: [
TopDecor(),
Box({
className: 'osk-body spacing-h-10',
children: [
KeyboardControls(),
Widget.Box({ className: 'separator-line' }),
KeyboardItself(keyboardJson),
],
})
],
setup: (self) => self.hook(App, (self, name, visible) => { // Update on open
if (!name) return;
if (name.startsWith('osk') && visible) {
self.setCss(`margin-bottom: -0px;`);
}
}),
});
export default ({ id }) => {
const kbWindow = KeyboardWindow();
const gestureEvBox = EventBox({ child: kbWindow })
const gesture = Gtk.GestureDrag.new(gestureEvBox);
gesture.connect('drag-begin', async () => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
Hyprland.messageAsync('j/cursorpos').then((out) => {
gesture.startY = JSON.parse(out).y;
}).catch(print);
} catch {
return;
}
});
gesture.connect('drag-update', async () => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
Hyprland.messageAsync('j/cursorpos').then((out) => {
const currentY = JSON.parse(out).y;
const offset = gesture.startY - currentY;
if (offset > 0) return;
kbWindow.setCss(`
margin-bottom: ${offset}px;
`);
}).catch(print);
} catch {
return;
}
});
gesture.connect('drag-end', () => {
var offset = gesture.get_offset()[2];
if (offset > 50) {
App.closeWindow(`osk${id}`);
}
else {
kbWindow.setCss(`
transition: margin-bottom 170ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-bottom: 0px;
`);
}
})
return gestureEvBox;
};
-28
View File
@@ -1,28 +0,0 @@
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
function moveClientToWorkspace(address, workspace) {
Utils.execAsync(['bash', '-c', `hyprctl dispatch movetoworkspacesilent ${workspace},address:${address} &`]);
}
export function dumpToWorkspace(from, to) {
if (from == to) return;
Hyprland.clients.forEach(client => {
if (client.workspace.id == from) {
moveClientToWorkspace(client.address, to);
}
});
}
export function swapWorkspace(workspaceA, workspaceB) {
if (workspaceA == workspaceB) return;
const clientsA = [];
const clientsB = [];
Hyprland.clients.forEach(client => {
if (client.workspace.id == workspaceA) clientsA.push(client.address);
if (client.workspace.id == workspaceB) clientsB.push(client.address);
});
clientsA.forEach((address) => moveClientToWorkspace(address, workspaceB));
clientsB.forEach((address) => moveClientToWorkspace(address, workspaceA));
}
-28
View File
@@ -1,28 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { SearchAndWindows } from "./windowcontent.js";
import PopupWindow from '../.widgethacks/popupwindow.js';
import { clickCloseRegion } from '../.commonwidgets/clickcloseregion.js';
export default (id = '') => PopupWindow({
name: `overview${id}`,
// exclusivity: 'ignore',
keymode: 'on-demand',
visible: false,
anchor: ['top', 'bottom', 'left', 'right'],
layer: 'top',
child: Widget.Box({
vertical: true,
children: [
clickCloseRegion({ name: 'overview', multimonitor: false, expand: false }),
Widget.Box({
children: [
clickCloseRegion({ name: 'overview', multimonitor: false }),
SearchAndWindows(),
clickCloseRegion({ name: 'overview', multimonitor: false }),
]
}),
clickCloseRegion({ name: 'overview', multimonitor: false }),
]
}),
})
@@ -1,151 +0,0 @@
const { Gio, GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
import Todo from "../../services/todo.js";
export function hasUnterminatedBackslash(inputString) {
// Use a regular expression to match a trailing odd number of backslashes
const regex = /\\+$/;
return regex.test(inputString);
}
export function launchCustomCommand(command) {
const args = command.toLowerCase().split(' ');
if (args[0] == '>raw') { // Mouse raw input
Utils.execAsync('hyprctl -j getoption input:accel_profile')
.then((output) => {
const value = JSON.parse(output)["str"].trim();
if (value != "[[EMPTY]]" && value != "") {
execAsync(['bash', '-c', `hyprctl keyword input:accel_profile '[[EMPTY]]'`]).catch(print);
}
else {
execAsync(['bash', '-c', `hyprctl keyword input:accel_profile flat`]).catch(print);
}
})
}
else if (args[0] == '>img') { // Change wallpaper
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchwall.sh`, `&`]).catch(print);
}
else if (args[0] == '>color') { // Generate colorscheme from color picker
if (!args[1])
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh --pick`, `&`]).catch(print);
else if (args[1][0] === '#')
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh "${args[1]}"`, `&`]).catch(print);
}
else if (args[0] == '>light') { // Light mode
darkMode.setValue(false).catch(print);
}
else if (args[0] == '>dark') { // Dark mode
darkMode.setValue(true).catch(print);
}
else if (args[0] == '>badapple') { // Black and white
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "3s/.*/monochrome/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
}
else if (args[0] == '>material') { // Use material colors
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && echo "material" > ${GLib.get_user_state_dir()}/ags/user/colorbackend.txt`]).catch(print)
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchwall.sh --noswitch`]).catch(print))
.catch(print);
}
else if (args[0] == '>pywal') { // Use Pywal (ik it looks shit but I'm not removing)
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && echo "pywal" > ${GLib.get_user_state_dir()}/ags/user/colorbackend.txt`]).catch(print)
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchwall.sh --noswitch`]).catch(print))
.catch(print);
}
else if (args[0] == '>todo') { // Todo
Todo.add(args.slice(1).join(' '));
}
else if (args[0] == '>shutdown') { // Shut down
execAsync([`bash`, `-c`, `systemctl poweroff || loginctl poweroff`]).catch(print);
}
else if (args[0] == '>reboot') { // Reboot
execAsync([`bash`, `-c`, `systemctl reboot || loginctl reboot`]).catch(print);
}
else if (args[0] == '>sleep') { // Sleep
execAsync([`bash`, `-c`, `systemctl suspend || loginctl suspend`]).catch(print);
}
else if (args[0] == '>logout') { // Log out
execAsync([`bash`, `-c`, `pkill Hyprland || pkill sway`]).catch(print);
}
}
export function execAndClose(command, terminal) {
App.closeWindow('overview');
if (terminal) {
execAsync([`bash`, `-c`, `${userOptions.apps.terminal} fish -C "${command}"`, `&`]).catch(print);
}
else
execAsync(command).catch(print);
}
export function couldBeMath(str) {
const regex = /^[0-9.+*/-]/;
return regex.test(str);
}
export function expandTilde(path) {
if (path.startsWith('~')) {
return GLib.get_home_dir() + path.slice(1);
} else {
return path;
}
}
function getFileIcon(fileInfo) {
let icon = fileInfo.get_icon();
if (icon) {
// Get the icon's name
return icon.get_names()[0];
} else {
// Default icon for files
return 'text-x-generic';
}
}
export function ls({ path = '~', silent = false }) {
let contents = [];
try {
let expandedPath = expandTilde(path);
if (expandedPath.endsWith('/'))
expandedPath = expandedPath.slice(0, -1);
let folder = Gio.File.new_for_path(expandedPath);
let enumerator = folder.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
let fileInfo;
while ((fileInfo = enumerator.next_file(null)) !== null) {
let fileName = fileInfo.get_display_name();
let fileType = fileInfo.get_file_type();
let item = {
parentPath: expandedPath,
name: fileName,
type: fileType === Gio.FileType.DIRECTORY ? 'folder' : 'file',
icon: getFileIcon(fileInfo),
};
// Add file extension for files
if (fileType === Gio.FileType.REGULAR) {
let fileExtension = fileName.split('.').pop();
item.type = `${fileExtension}`;
}
contents.push(item);
contents.sort((a, b) => {
const aIsFolder = a.type.startsWith('folder');
const bIsFolder = b.type.startsWith('folder');
if (aIsFolder && !bIsFolder) {
return -1;
} else if (!aIsFolder && bIsFolder) {
return 1;
} else {
return a.name.localeCompare(b.name); // Sort alphabetically within folders and files
}
});
}
} catch (e) {
if (!silent) console.log(e);
}
return contents;
}
@@ -1,446 +0,0 @@
// TODO
// - Make client destroy/create not destroy and recreate the whole thing
// - Active ws hook optimization: only update when moving to next group
//
const { Gdk, Gtk } = imports.gi;
const { Gravity } = imports.gi.Gdk;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
const { execAsync, exec } = Utils;
import { setupCursorHoverGrab } from '../.widgetutils/cursorhover.js';
import { dumpToWorkspace, swapWorkspace } from "./actions.js";
import { iconExists, substitute } from "../.miscutils/icons.js";
import { monitors } from '../.commondata/hyprlanddata.js';
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
const NUM_OF_WORKSPACES_SHOWN = userOptions.overview.numOfCols * userOptions.overview.numOfRows;
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
const overviewTick = Variable(false);
const overviewMonitor = Variable(0);
export default () => {
const clientMap = new Map();
const ContextMenuWorkspaceArray = ({ label, actionFunc, thisWorkspace }) => Widget.MenuItem({
label: `${label}`,
setup: (menuItem) => {
let submenu = new Gtk.Menu();
submenu.className = 'menu';
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
const startWorkspace = offset + 1;
const endWorkspace = startWorkspace + NUM_OF_WORKSPACES_SHOWN - 1;
for (let i = startWorkspace; i <= endWorkspace; i++) {
let button = new Gtk.MenuItem({
label: `Workspace ${i}`
});
button.connect("activate", () => {
// execAsync([`${onClickBinary}`, `${thisWorkspace}`, `${i}`]).catch(print);
actionFunc(thisWorkspace, i);
overviewTick.setValue(!overviewTick.value);
});
submenu.append(button);
}
menuItem.set_reserve_indicator(true);
menuItem.set_submenu(submenu);
}
})
const Window = ({ address, at: [x, y], size: [w, h], workspace: { id, name }, class: c, initialClass, monitor, title, xwayland }, screenCoords) => {
const revealInfoCondition = (Math.min(w, h) * userOptions.overview.scale > 70);
if (w <= 0 || h <= 0 || (c === '' && title === '')) return null;
// Non-primary monitors
if (screenCoords.x != 0) x -= screenCoords.x;
if (screenCoords.y != 0) y -= screenCoords.y;
// Other offscreen adjustments
if (x + w <= 0) x += (Math.floor(x / monitors[monitor].width) * monitors[monitor].width);
else if (x < 0) { w = x + w; x = 0; }
if (y + h <= 0) x += (Math.floor(y / monitors[monitor].height) * monitors[monitor].height);
else if (y < 0) { h = y + h; y = 0; }
// Prevents throwing an error when multiple monitors are plugged in but only one is enabled (#1047)
if (monitors.length - 1 < monitor) {
monitor = monitors.length - 1;
}
// Properly scale for multi monitors
w *= monitors[overviewMonitor.value].width / monitors[monitor].width;
h *= monitors[overviewMonitor.value].height / monitors[monitor].height;
// Truncate if offscreen
if (x + w > monitors[overviewMonitor.value].width) w = monitors[overviewMonitor.value].width - x;
if (y + h > monitors[overviewMonitor.value].height) h = monitors[overviewMonitor.value].height - y;
if (c.length == 0) c = initialClass;
const iconName = substitute(c);
// const appIcon = iconExists(iconName) ? Widget.Icon({
// icon: iconName,
// size: Math.min(w, h) * userOptions.overview.scale / 2.5,
// }) : MaterialIcon('terminal', 'gigantic', {
// css: `font-size: ${Math.min(w, h) * userOptions.overview.scale / 2.5}px`,
// });
const appIcon = Widget.Icon({
icon: iconName,
size: Math.min(w, h) * userOptions.overview.scale / 2.5,
});
return Widget.Button({
attribute: {
address, x, y, w, h, ws: id,
updateIconSize: (self) => {
appIcon.size = Math.min(self.attribute.w, self.attribute.h) * userOptions.overview.scale / 2.5;
},
},
className: 'overview-tasks-window',
hpack: 'start',
vpack: 'start',
css: `
margin-left: ${Math.round(x * userOptions.overview.scale)}px;
margin-top: ${Math.round(y * userOptions.overview.scale)}px;
margin-right: -${Math.round((x + w) * userOptions.overview.scale)}px;
margin-bottom: -${Math.round((y + h) * userOptions.overview.scale)}px;
`,
onClicked: (self) => {
Hyprland.messageAsync(`dispatch focuswindow address:${address}`);
App.closeWindow('overview');
},
onMiddleClickRelease: () => Hyprland.messageAsync(`dispatch closewindow address:${address}`),
onSecondaryClick: (button) => {
button.toggleClassName('overview-tasks-window-selected', true);
const menu = Widget.Menu({
className: 'menu',
children: [
Widget.MenuItem({
child: Widget.Label({
xalign: 0,
label: "Close (Middle-click)",
}),
onActivate: () => Hyprland.messageAsync(`dispatch closewindow address:${address}`),
}),
ContextMenuWorkspaceArray({
label: "Dump windows to workspace",
actionFunc: dumpToWorkspace,
thisWorkspace: Number(id)
}),
ContextMenuWorkspaceArray({
label: "Swap windows with workspace",
actionFunc: swapWorkspace,
thisWorkspace: Number(id)
}),
],
});
menu.connect("deactivate", () => {
button.toggleClassName('overview-tasks-window-selected', false);
})
menu.connect("selection-done", () => {
button.toggleClassName('overview-tasks-window-selected', false);
})
menu.popup_at_widget(button.get_parent(), Gravity.SOUTH, Gravity.NORTH, null); // Show menu below the button
button.connect("destroy", () => menu.destroy());
},
child: Widget.Box({
homogeneous: true,
child: Widget.Box({
vertical: true,
vpack: 'center',
children: [
appIcon,
// TODO: Add xwayland tag instead of just having italics
Widget.Revealer({
transition: 'slide_right',
revealChild: revealInfoCondition,
child: Widget.Revealer({
transition: 'slide_down',
revealChild: revealInfoCondition,
child: Widget.Label({
maxWidthChars: 1, // Doesn't matter what number
truncate: 'end',
className: `margin-top-5 ${xwayland ? 'txt txt-italic' : 'txt'}`,
css: overviewMonitor.bind().as(monitor => `
font-size: ${Math.min(monitors[monitor].width, monitors[monitor].height) * userOptions.overview.scale / 14.6}px;
margin: 0px ${Math.min(monitors[monitor].width, monitors[monitor].height) * userOptions.overview.scale / 10}px;
`),
// If the title is too short, include the class
label: (title.length <= 1 ? `${c}: ${title}` : title),
})
})
})
]
})
}),
tooltipText: `${c}: ${title}`,
setup: (button) => {
setupCursorHoverGrab(button);
button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.MOVE);
button.drag_source_set_icon_name(substitute(c));
button.connect('drag-begin', (button) => { // On drag start, add the dragging class
button.toggleClassName('overview-tasks-window-dragging', true);
});
button.connect('drag-data-get', (_w, _c, data) => { // On drag finish, give address
data.set_text(address, address.length);
button.toggleClassName('overview-tasks-window-dragging', false);
});
},
});
}
const Workspace = (index) => {
// const fixed = Widget.Fixed({
// attribute: {
// put: (widget, x, y) => {
// fixed.put(widget, x, y);
// },
// move: (widget, x, y) => {
// fixed.move(widget, x, y);
// },
// }
// });
const fixed = Widget.Box({
attribute: {
put: (widget, x, y) => {
if (!widget.attribute) return;
// Note: x and y are already multiplied by userOptions.overview.scale
const newCss = `
margin-left: ${Math.round(x)}px;
margin-top: ${Math.round(y)}px;
margin-right: -${Math.round(x + (widget.attribute.w * userOptions.overview.scale))}px;
margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px;
`;
widget.css = newCss;
fixed.pack_start(widget, false, false, 0);
},
move: (widget, x, y) => {
if (!widget) return;
if (!widget.attribute) return;
// Note: x and y are already multiplied by userOptions.overview.scale
const newCss = `
margin-left: ${Math.round(x)}px;
margin-top: ${Math.round(y)}px;
margin-right: -${Math.round(x + (widget.attribute.w * userOptions.overview.scale))}px;
margin-bottom: -${Math.round(y + (widget.attribute.h * userOptions.overview.scale))}px;
`;
widget.css = newCss;
},
}
})
const WorkspaceNumber = ({ index, ...rest }) => Widget.Label({
className: 'overview-tasks-workspace-number',
label: `${index}`,
css: overviewMonitor.bind().as(monitor => `
margin: ${Math.min(monitors[monitor].width, monitors[monitor].height) * userOptions.overview.scale * userOptions.overview.wsNumMarginScale}px;
font-size: ${monitors[monitor].height * userOptions.overview.scale * userOptions.overview.wsNumScale}px;
`),
setup: (self) => self.hook(Hyprland.active.workspace, (self) => {
// Update when going to new ws group
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN);
self.label = `${currentGroup * NUM_OF_WORKSPACES_SHOWN + index}`;
}),
...rest,
})
const widget = Widget.Box({
className: 'overview-tasks-workspace',
vpack: 'center',
// Rounding and adding 1px to minimum width/height to work around scaling inaccuracy:
css: overviewMonitor.bind().as(monitor => `
min-width: ${1 + Math.round(monitors[monitor].width * userOptions.overview.scale)}px;
min-height: ${1 + Math.round(monitors[monitor].height * userOptions.overview.scale)}px;
`),
children: [Widget.EventBox({
hexpand: true,
onPrimaryClick: () => {
Hyprland.messageAsync(`dispatch workspace ${index}`);
App.closeWindow('overview');
},
setup: (eventbox) => {
eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
eventbox.connect('drag-data-received', (_w, _c, _x, _y, data) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
Hyprland.messageAsync(`dispatch movetoworkspacesilent ${index + offset},address:${data.get_text()}`)
overviewTick.setValue(!overviewTick.value);
});
},
child: Widget.Overlay({
child: Widget.Box({}),
overlays: [
WorkspaceNumber({ index: index, hpack: 'start', vpack: 'start' }),
fixed
]
}),
})],
});
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
fixed.attribute.put(WorkspaceNumber(offset + index), 0, 0);
widget.clear = () => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
clientMap.forEach((client, address) => {
if (!client) return;
if ((client.attribute.ws <= offset || client.attribute.ws > offset + NUM_OF_WORKSPACES_SHOWN) ||
(client.attribute.ws == offset + index)) {
client.destroy();
client = null;
clientMap.delete(address);
}
});
}
widget.set = (clientJson, screenCoords) => {
let c = clientMap.get(clientJson.address);
if (c) {
if (c.attribute?.ws !== clientJson.workspace.id) {
c.destroy();
c = null;
clientMap.delete(clientJson.address);
}
else if (c) {
c.attribute.w = clientJson.size[0];
c.attribute.h = clientJson.size[1];
c.attribute.updateIconSize(c);
fixed.attribute.move(c,
Math.max(0, clientJson.at[0] * userOptions.overview.scale),
Math.max(0, clientJson.at[1] * userOptions.overview.scale)
);
return;
}
}
const newWindow = Window(clientJson, screenCoords);
if (newWindow === null) return;
// clientMap.set(clientJson.address, newWindow);
fixed.attribute.put(newWindow,
Math.max(0, newWindow.attribute.x * userOptions.overview.scale),
Math.max(0, newWindow.attribute.y * userOptions.overview.scale)
);
clientMap.set(clientJson.address, newWindow);
};
widget.unset = (clientAddress) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
let c = clientMap.get(clientAddress);
if (!c) return;
c.destroy();
c = null;
clientMap.delete(clientAddress);
};
widget.show = () => {
fixed.show_all();
}
return widget;
};
const arr = (s, n) => {
const array = [];
for (let i = 0; i < n; i++)
array.push(s + i);
return array;
};
const OverviewRow = ({ startWorkspace, workspaces, windowName = 'overview' }) => Widget.Box({
children: arr(startWorkspace, workspaces).map(Workspace),
attribute: {
workspaceGroup: Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN),
monitorMap: [],
getMonitorMap: (box) => {
execAsync('hyprctl -j monitors').then(monitors => {
box.attribute.monitorMap = JSON.parse(monitors).reduce((acc, item) => {
acc[item.id] = { x: item.x, y: item.y };
return acc;
}, {});
});
},
update: (box) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
Hyprland.messageAsync('j/clients').then(clients => {
const allClients = JSON.parse(clients);
const kids = box.get_children();
kids.forEach(kid => kid.clear());
for (let i = 0; i < allClients.length; i++) {
const client = allClients[i];
const childID = client.workspace.id - (offset + startWorkspace);
if (offset + startWorkspace <= client.workspace.id &&
client.workspace.id <= offset + startWorkspace + workspaces) {
const screenCoords = box.attribute.monitorMap[client.monitor];
if (kids[childID]) {
kids[childID].set(client, screenCoords);
}
continue;
}
}
kids.forEach(kid => kid.show());
}).catch(print);
},
updateWorkspace: (box, id) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
if (!( // Not in range, ignore
offset + startWorkspace <= id &&
id <= offset + startWorkspace + workspaces
)) return;
// if (!App.getWindow(windowName)?.visible) return;
Hyprland.messageAsync('j/clients').then(clients => {
const allClients = JSON.parse(clients);
const kids = box.get_children();
for (let i = 0; i < allClients.length; i++) {
const client = allClients[i];
if (client.workspace.id != id) continue;
const screenCoords = box.attribute.monitorMap[client.monitor];
kids[id - (offset + startWorkspace)]?.set(client, screenCoords);
}
kids[id - (offset + startWorkspace)]?.show();
}).catch(print);
},
},
setup: (box) => {
box.attribute.getMonitorMap(box);
box
.hook(overviewTick, (box) => box.attribute.update(box))
.hook(Hyprland, (box, clientAddress) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN) * NUM_OF_WORKSPACES_SHOWN;
const kids = box.get_children();
const client = Hyprland.getClient(clientAddress);
if (!client) return;
const id = client.workspace.id;
box.attribute.updateWorkspace(box, id);
kids[id - (offset + startWorkspace)]?.unset(clientAddress);
}, 'client-removed')
.hook(Hyprland, (box, clientAddress) => {
const client = Hyprland.getClient(clientAddress);
if (!client) return;
box.attribute.updateWorkspace(box, client.workspace.id);
}, 'client-added')
.hook(Hyprland.active.workspace, (box) => {
// Full update when going to new ws group
const previousGroup = box.attribute.workspaceGroup;
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / NUM_OF_WORKSPACES_SHOWN);
if (currentGroup !== previousGroup) {
if (!App.getWindow(windowName) || !App.getWindow(windowName).visible) return;
box.attribute.update(box);
box.attribute.workspaceGroup = currentGroup;
}
})
.hook(App, (box, name, visible) => { // Update on open
if (name == 'overview' && visible) {
overviewMonitor.value = Hyprland.active.monitor.id;
box.attribute.update(box);
}
})
},
});
return Widget.Revealer({
revealChild: true,
// hpack to prevent unneeded expansion in overview-tasks-workspace:
hpack: 'center',
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
vertical: true,
className: 'overview-tasks',
children: Array.from({ length: userOptions.overview.numOfRows }, (_, index) =>
OverviewRow({
startWorkspace: 1 + index * userOptions.overview.numOfCols,
workspaces: userOptions.overview.numOfCols,
})
)
}),
});
}
@@ -1,189 +0,0 @@
const { Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
import { searchItem } from './searchitem.js';
import { execAndClose, couldBeMath, launchCustomCommand } from './miscfunctions.js';
import GeminiService from '../../services/gemini.js';
export const NoResultButton = () => searchItem({
materialIconName: 'Error',
name: "Search invalid",
content: "No results found!",
onActivate: () => {
App.closeWindow('overview');
},
});
export const DirectoryButton = ({ parentPath, name, type, icon }) => {
const actionText = Widget.Revealer({
revealChild: false,
transition: "crossfade",
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Label({
className: 'overview-search-results-txt txt txt-small txt-action',
label: 'Open',
})
});
const actionTextRevealer = Widget.Revealer({
revealChild: false,
transition: "slide_left",
transitionDuration: userOptions.animations.durationSmall,
child: actionText,
});
return Widget.Button({
className: 'overview-search-result-btn',
onClicked: () => {
App.closeWindow('overview');
execAsync(['bash', '-c', `xdg-open '${parentPath}/${name}'`, `&`]).catch(print);
},
child: Widget.Box({
children: [
Widget.Box({
vertical: false,
children: [
Widget.Box({
className: 'overview-search-results-icon',
homogeneous: true,
child: Widget.Icon({
icon: icon,
}),
}),
Widget.Label({
className: 'overview-search-results-txt txt txt-norm',
label: name,
}),
Widget.Box({ hexpand: true }),
actionTextRevealer,
]
})
]
}),
setup: (self) => self
.on('focus-in-event', (button) => {
actionText.revealChild = true;
actionTextRevealer.revealChild = true;
})
.on('focus-out-event', (button) => {
actionText.revealChild = false;
actionTextRevealer.revealChild = false;
})
,
})
}
export const CalculationResultButton = ({ result, text }) => searchItem({
materialIconName: 'calculate',
name: `Math result`,
actionName: "Copy",
content: `${result}`,
onActivate: () => {
App.closeWindow('overview');
execAsync(['wl-copy', `${result}`]).catch(print);
},
});
export const DesktopEntryButton = (app) => {
const actionText = Widget.Revealer({
revealChild: false,
transition: "crossfade",
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Label({
className: 'overview-search-results-txt txt txt-small txt-action',
label: 'Launch',
})
});
const actionTextRevealer = Widget.Revealer({
revealChild: false,
transition: "slide_left",
transitionDuration: userOptions.animations.durationSmall,
child: actionText,
});
return Widget.Button({
className: 'overview-search-result-btn',
onClicked: () => {
App.closeWindow('overview');
app.launch();
},
child: Widget.Box({
children: [
Widget.Box({
vertical: false,
children: [
Widget.Box({
className: 'overview-search-results-icon',
homogeneous: true,
child: Widget.Icon({
icon: app.iconName,
}),
}),
Widget.Label({
className: 'overview-search-results-txt txt txt-norm',
label: app.name,
}),
Widget.Box({ hexpand: true }),
actionTextRevealer,
]
})
]
}),
setup: (self) => self
.on('focus-in-event', (button) => {
actionText.revealChild = true;
actionTextRevealer.revealChild = true;
})
.on('focus-out-event', (button) => {
actionText.revealChild = false;
actionTextRevealer.revealChild = false;
})
,
})
}
export const ExecuteCommandButton = ({ command, terminal = false }) => searchItem({
materialIconName: `${terminal ? 'terminal' : 'settings_b_roll'}`,
name: `Run command`,
actionName: `Execute ${terminal ? 'in terminal' : ''}`,
content: `${command}`,
onActivate: () => execAndClose(command, terminal),
extraClassName: 'techfont',
})
export const CustomCommandButton = ({ text = '' }) => searchItem({
materialIconName: 'settings_suggest',
name: 'Action',
actionName: 'Run',
content: `${text}`,
onActivate: () => {
App.closeWindow('overview');
launchCustomCommand(text);
},
});
export const SearchButton = ({ text = '' }) => searchItem({
materialIconName: 'travel_explore',
name: 'Search the web',
actionName: 'Go',
content: `${text}`,
onActivate: () => {
App.closeWindow('overview');
let search = userOptions.search.engineBaseUrl + text;
for (let site of userOptions.search.excludedSites) {
if (site) search += ` -site:${site}`;
}
execAsync(['bash', '-c', `xdg-open '${search}' &`]).catch(print);
},
});
export const AiButton = ({ text }) => searchItem({
materialIconName: 'chat_paste_go',
name: 'Ask Gemini',
actionName: 'Ask',
content: `${text}`,
onActivate: () => {
GeminiService.send(text);
App.closeWindow('overview');
App.openWindow('sideleft');
},
});
@@ -1,65 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
export const searchItem = ({ materialIconName, name, actionName, content, onActivate, extraClassName = '', ...rest }) => {
const actionText = Widget.Revealer({
revealChild: false,
transition: "crossfade",
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Label({
className: 'overview-search-results-txt txt txt-small txt-action',
label: `${actionName}`,
})
});
const actionTextRevealer = Widget.Revealer({
revealChild: false,
transition: "slide_left",
transitionDuration: userOptions.animations.durationSmall,
child: actionText,
})
return Widget.Button({
className: `overview-search-result-btn txt ${extraClassName}`,
onClicked: onActivate,
child: Widget.Box({
children: [
Widget.Box({
vertical: false,
children: [
Widget.Label({
className: `icon-material overview-search-results-icon`,
label: `${materialIconName}`,
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
hpack: 'start',
className: 'overview-search-results-txt txt-smallie txt-subtext',
label: `${name}`,
truncate: "end",
}),
Widget.Label({
hpack: 'start',
className: 'overview-search-results-txt txt-norm',
label: `${content}`,
truncate: "end",
}),
]
}),
Widget.Box({ hexpand: true }),
actionTextRevealer,
],
})
]
}),
setup: (self) => self
.on('focus-in-event', (button) => {
actionText.revealChild = true;
actionTextRevealer.revealChild = true;
})
.on('focus-out-event', (button) => {
actionText.revealChild = false;
actionTextRevealer.revealChild = false;
})
,
});
}
@@ -1,213 +0,0 @@
const { Gdk, Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Applications from 'resource:///com/github/Aylur/ags/service/applications.js';
const { execAsync, exec } = Utils;
import { execAndClose, expandTilde, hasUnterminatedBackslash, couldBeMath, launchCustomCommand, ls } from './miscfunctions.js';
import {
CalculationResultButton, CustomCommandButton, DirectoryButton,
DesktopEntryButton, ExecuteCommandButton, SearchButton, AiButton, NoResultButton,
} from './searchbuttons.js';
import { checkKeybind } from '../.widgetutils/keybind.js';
import GeminiService from '../../services/gemini.js';
// Add math funcs
const { abs, sin, cos, tan, cot, asin, acos, atan, acot } = Math;
const pi = Math.PI;
// trigonometric funcs for deg
const sind = x => sin(x * pi / 180);
const cosd = x => cos(x * pi / 180);
const tand = x => tan(x * pi / 180);
const cotd = x => cot(x * pi / 180);
const asind = x => asin(x) * 180 / pi;
const acosd = x => acos(x) * 180 / pi;
const atand = x => atan(x) * 180 / pi;
const acotd = x => acot(x) * 180 / pi;
const MAX_RESULTS = 10;
const OVERVIEW_SCALE = 0.18; // = overview workspace box / screen size
const OVERVIEW_WS_NUM_SCALE = 0.09;
const OVERVIEW_WS_NUM_MARGIN_SCALE = 0.07;
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
function iconExists(iconName) {
let iconTheme = Gtk.IconTheme.get_default();
return iconTheme.has_icon(iconName);
}
const OptionalOverview = async () => {
try {
return (await import('./overview_hyprland.js')).default();
} catch {
return Widget.Box({});
// return (await import('./overview_hyprland.js')).default();
}
};
const overviewContent = await OptionalOverview();
export const SearchAndWindows = () => {
var _appSearchResults = [];
const resultsBox = Widget.Box({
className: 'overview-search-results',
vertical: true,
});
const resultsRevealer = Widget.Revealer({
transitionDuration: userOptions.animations.durationLarge,
revealChild: false,
transition: 'slide_down',
// duration: 200,
hpack: 'center',
child: resultsBox,
});
const entryPromptRevealer = Widget.Revealer({
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
revealChild: true,
hpack: 'center',
child: Widget.Label({
className: 'overview-search-prompt txt-small txt',
label: getString('Type to search')
}),
});
const entryIconRevealer = Widget.Revealer({
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
revealChild: false,
hpack: 'end',
child: Widget.Label({
className: 'txt txt-large icon-material overview-search-icon',
label: 'search',
}),
});
const entryIcon = Widget.Box({
className: 'overview-search-prompt-box',
setup: box => box.pack_start(entryIconRevealer, true, true, 0),
});
const entry = Widget.Entry({
className: 'overview-search-box txt-small txt',
hpack: 'center',
onAccept: (self) => { // This is when you hit Enter
resultsBox.children[0].onClicked();
},
onChange: (entry) => { // this is when you type
const isAction = entry.text[0] == '>';
const isDir = (['/', '~'].includes(entry.text[0]));
resultsBox.get_children().forEach(ch => ch.destroy());
// check empty if so then dont do stuff
if (entry.text == '') {
resultsRevealer.revealChild = false;
overviewContent.revealChild = true;
entryPromptRevealer.revealChild = true;
entryIconRevealer.revealChild = false;
entry.toggleClassName('overview-search-box-extended', false);
return;
}
const text = entry.text;
resultsRevealer.revealChild = true;
overviewContent.revealChild = false;
entryPromptRevealer.revealChild = false;
entryIconRevealer.revealChild = true;
entry.toggleClassName('overview-search-box-extended', true);
_appSearchResults = Applications.query(text);
// Calculate
if (userOptions.search.enableFeatures.mathResults && couldBeMath(text)) { // Eval on typing is dangerous; this is a small workaround.
try {
const fullResult = eval(text.replace(/\^/g, "**"));
resultsBox.add(CalculationResultButton({ result: fullResult, text: text }));
} catch (e) {
// console.log(e);
}
}
if (userOptions.search.enableFeatures.directorySearch && isDir) {
var contents = [];
contents = ls({ path: text, silent: true });
contents.forEach((item) => {
resultsBox.add(DirectoryButton(item));
})
}
if (userOptions.search.enableFeatures.actions && isAction) { // Eval on typing is dangerous, this is a workaround.
resultsBox.add(CustomCommandButton({ text: entry.text }));
}
// Add application entries
let appsToAdd = MAX_RESULTS;
_appSearchResults.forEach(app => {
if (appsToAdd == 0) return;
resultsBox.add(DesktopEntryButton(app));
appsToAdd--;
});
// Fallbacks
// if the first word is an actual command
if (userOptions.search.enableFeatures.commands && !isAction && !hasUnterminatedBackslash(text) && exec(`bash -c "command -v ${text.split(' ')[0]}"`) != '') {
resultsBox.add(ExecuteCommandButton({ command: entry.text, terminal: entry.text.startsWith('sudo') }));
}
// Add fallback: search
if (userOptions.search.enableFeatures.aiSearch)
resultsBox.add(AiButton({ text: entry.text }));
if (userOptions.search.enableFeatures.webSearch)
resultsBox.add(SearchButton({ text: entry.text }));
if (resultsBox.children.length == 0) resultsBox.add(NoResultButton());
resultsBox.show_all();
},
});
return Widget.Box({
vertical: true,
children: [
Widget.Box({
hpack: 'center',
children: [
entry,
Widget.Box({
className: 'overview-search-icon-box',
setup: (box) => {
box.pack_start(entryPromptRevealer, true, true, 0)
},
}),
entryIcon,
]
}),
overviewContent,
resultsRevealer,
],
setup: (self) => self
.hook(App, (_b, name, visible) => {
if (name == 'overview' && !visible) {
resultsBox.children = [];
entry.set_text('');
}
})
.on('key-press-event', (widget, event) => { // Typing
const keyval = event.get_keyval()[1];
const modstate = event.get_state()[1];
if (checkKeybind(event, userOptions.keybinds.overview.altMoveLeft))
entry.set_position(Math.max(entry.get_position() - 1, 0));
else if (checkKeybind(event, userOptions.keybinds.overview.altMoveRight))
entry.set_position(Math.min(entry.get_position() + 1, entry.get_text().length));
else if (checkKeybind(event, userOptions.keybinds.overview.deleteToEnd)) {
const text = entry.get_text();
const pos = entry.get_position();
const newText = text.slice(0, pos);
entry.set_text(newText);
entry.set_position(newText.length);
}
else if (!(modstate & Gdk.ModifierType.CONTROL_MASK)) { // Ctrl not held
if (keyval >= 32 && keyval <= 126 && widget != entry) {
Utils.timeout(1, () => entry.grab_focus());
entry.set_text(entry.text + String.fromCharCode(keyval));
entry.set_position(-1);
}
}
})
,
});
};
-38
View File
@@ -1,38 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js";
if(userOptions.appearance.fakeScreenRounding === 2) Hyprland.connect('event', (service, name, data) => {
if (name == 'fullscreen') {
const monitor = Hyprland.active.monitor.id;
if (data == '1') {
for (const window of App.windows) {
if (window.name.startsWith("corner") && window.name.endsWith(monitor)) {
App.closeWindow(window.name);
}
}
} else {
for (const window of App.windows) {
if (window.name.startsWith("corner") && window.name.endsWith(monitor)) {
App.openWindow(window.name);
}
}
}
}
})
export default (monitor = 0, where = 'bottom left', useOverlayLayer = true) => {
const positionString = where.replace(/\s/, ""); // remove space
return Widget.Window({
monitor,
name: `corner${positionString}${monitor}`,
layer: useOverlayLayer ? 'overlay' : 'top',
anchor: where.split(' '),
exclusivity: 'ignore',
visible: true,
child: RoundedCorner(positionString, { className: 'corner-black', }),
setup: enableClickthrough,
});
}
-14
View File
@@ -1,14 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import SessionScreen from "./sessionscreen.js";
import PopupWindow from '../.widgethacks/popupwindow.js';
export default (id = 0) => PopupWindow({ // On-screen keyboard
monitor: id,
name: `session${id}`,
visible: false,
keymode: 'on-demand',
layer: 'overlay',
exclusivity: 'ignore',
anchor: ['top', 'bottom', 'left', 'right'],
child: SessionScreen({ id: id }),
})
@@ -1,134 +0,0 @@
// This is for the cool memory indicator on the sidebar
// For the right pill of the bar, see system.js
const { Gdk, Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { monitors } from '../.commondata/hyprlanddata.js';
const { exec, execAsync } = Utils;
const SessionButton = (name, icon, command, props = {}, colorid = 0) => {
const buttonDescription = Widget.Revealer({
vpack: 'end',
transitionDuration: userOptions.animations.durationSmall,
transition: 'slide_down',
revealChild: false,
child: Widget.Label({
className: 'txt-smaller session-button-desc',
label: name,
}),
});
return Widget.Button({
onClicked: command,
className: `session-button session-color-${colorid}`,
child: Widget.Overlay({
className: 'session-button-box',
child: Widget.Label({
vexpand: true,
className: 'icon-material',
label: icon,
}),
overlays: [
buttonDescription,
]
}),
onHover: (button) => {
const display = Gdk.Display.get_default();
const cursor = Gdk.Cursor.new_from_name(display, 'pointer');
button.get_window().set_cursor(cursor);
buttonDescription.revealChild = true;
},
onHoverLost: (button) => {
const display = Gdk.Display.get_default();
const cursor = Gdk.Cursor.new_from_name(display, 'default');
button.get_window().set_cursor(cursor);
buttonDescription.revealChild = false;
},
setup: (self) => self
.on('focus-in-event', (self) => {
buttonDescription.revealChild = true;
self.toggleClassName('session-button-focused', true);
})
.on('focus-out-event', (self) => {
buttonDescription.revealChild = false;
self.toggleClassName('session-button-focused', false);
})
,
...props,
});
}
export default ({ id = 0 }) => {
// lock, logout, sleep
const lockButton = SessionButton(getString('Lock'), 'lock', () => { closeWindowOnAllMonitors('session'); execAsync(['loginctl', 'lock-session']).catch(print) }, {}, 1);
const logoutButton = SessionButton(getString('Logout'), 'logout', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'pkill Hyprland || pkill sway || pkill niri || loginctl terminate-user $USER']).catch(print) }, {}, 2);
const sleepButton = SessionButton(getString('Sleep'), 'sleep', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl suspend || loginctl suspend']).catch(print) }, {}, 3);
// hibernate, shutdown, reboot
const hibernateButton = SessionButton(getString('Hibernate'), 'downloading', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl hibernate || loginctl hibernate']).catch(print) }, {}, 4);
const shutdownButton = SessionButton(getString('Shutdown'), 'power_settings_new', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl poweroff || loginctl poweroff']).catch(print) }, {}, 5);
const rebootButton = SessionButton(getString('Reboot'), 'restart_alt', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl reboot || loginctl reboot']).catch(print) }, {}, 6);
const cancelButton = SessionButton(getString('Cancel'), 'close', () => closeWindowOnAllMonitors('session'), { className: 'session-button-cancel' }, 7);
const sessionDescription = Widget.Box({
vertical: true,
css: 'margin-bottom: 0.682rem;',
children: [
Widget.Label({
className: 'txt-title txt',
label: getString('Session'),
}),
Widget.Label({
justify: Gtk.Justification.CENTER,
className: 'txt-small txt',
label: getString('Use arrow keys to navigate.\nEnter to select, Esc to cancel.')
}),
]
});
const SessionButtonRow = (children) => Widget.Box({
hpack: 'center',
className: 'spacing-h-15',
children: children,
});
const sessionButtonRows = [
SessionButtonRow([lockButton, logoutButton, sleepButton]),
SessionButtonRow([hibernateButton, shutdownButton, rebootButton]),
SessionButtonRow([cancelButton]),
]
return Widget.Box({
className: 'session-bg',
css: `
min-width: ${monitors[id].width}px;
min-height: ${monitors[id].height}px;
`, // idk why but height = screen height doesn't fill
vertical: true,
children: [
Widget.EventBox({
onPrimaryClick: () => closeWindowOnAllMonitors('session'),
onSecondaryClick: () => closeWindowOnAllMonitors('session'),
onMiddleClick: () => closeWindowOnAllMonitors('session'),
}),
Widget.Box({
hpack: 'center',
vexpand: true,
vertical: true,
children: [
Widget.Box({
vpack: 'center',
vertical: true,
className: 'spacing-v-15',
children: [
sessionDescription,
...sessionButtonRows,
]
})
]
})
],
setup: (self) => self
.hook(App, (_b, name, visible) => {
if (visible) lockButton.grab_focus(); // Lock is the default option
})
,
});
}
@@ -1,491 +0,0 @@
const { GLib, Gtk } = imports.gi;
import GtkSource from "gi://GtkSource?version=3.0";
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, Label, Icon, Revealer, Scrollable, Stack } = Widget;
const { execAsync, exec } = Utils;
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import md2pango, { replaceInlineLatexWithCodeBlocks } from '../../.miscutils/md2pango.js';
import { darkMode } from "../../.miscutils/system.js";
import { setupCursorHover } from "../../.widgetutils/cursorhover.js";
const LATEX_DIR = `${GLib.get_user_cache_dir()}/ags/media/latex`;
const USERNAME = GLib.get_user_name();
function substituteLang(str) {
const subs = [
{ from: 'javascript', to: 'js' },
{ from: 'bash', to: 'sh' },
];
for (const { from, to } of subs) {
if (from === str) return to;
}
return str;
}
const HighlightedCode = (content, lang) => {
const buffer = new GtkSource.Buffer();
const sourceView = new GtkSource.View({
buffer: buffer,
wrap_mode: Gtk.WrapMode.NONE,
insertSpacesInsteadOfTabs: true,
indentWidth: 4,
tabWidth: 4,
smartHomeEnd: true,
smartBackspace: true,
});
const langManager = GtkSource.LanguageManager.get_default();
let displayLang = langManager.get_language(substituteLang(lang)); // Set your preferred language
if (displayLang) {
buffer.set_language(displayLang);
}
const schemeManager = GtkSource.StyleSchemeManager.get_default();
buffer.set_style_scheme(schemeManager.get_scheme(`custom${darkMode.value ? '' : '-light'}`));
buffer.set_text(content, -1);
return sourceView;
}
const TextBlock = (content = '') => {
const widget = Label({
attribute: {
'text': content,
'updateText': (text) => {
widget.attribute.text = text;
widget.label = md2pango(widget.attribute.text)
},
'appendText': (text) => {
widget.attribute.text += text;
widget.label = md2pango(widget.attribute.text)
},
},
hpack: 'fill',
className: 'txt sidebar-chat-txtblock sidebar-chat-txt',
useMarkup: true,
xalign: 0,
wrap: true,
selectable: true,
label: content,
});
return widget;
}
const ThinkBlock = (content = '', revealChild = true) => {
const revealThought = Variable(revealChild);
const mainText = Label({
hpack: 'fill',
className: `txt sidebar-chat-txtblock-think sidebar-chat-txt`,
useMarkup: true,
xalign: 0,
wrap: true,
selectable: true,
label: content,
});
const mainTextRevealer = Revealer({
transition: 'slide_down',
revealChild: revealThought.value,
child: mainText,
setup: (self) => self.hook(revealThought, (self) => {
self.revealChild = revealThought.value;
})
})
const expandIcon = MaterialIcon(revealThought.value ? 'expand_less' : 'expand_more', 'norm', {
setup: (self) => self.hook(revealThought, (self) => {
self.label = revealThought.value ? 'expand_less' : 'expand_more';
})
});
const widget = Box({
attribute: {
'text': content,
'updateText': (text) => {
widget.attribute.text = text;
mainText.label = md2pango(widget.attribute.text);
},
'appendText': (text) => {
widget.attribute.text += text;
mainText.label = md2pango(widget.attribute.text);
},
'done': () => {
revealThought.value = false;
}
},
className: 'sidebar-chat-thinkblock',
vertical: true,
children: [
Button({
onClicked: (self) => {
revealThought.value = !revealThought.value;
},
child: Box({
className: 'spacing-h-10 padding-10',
children: [
Box({
homogeneous: true,
valign: 'center',
className: 'sidebar-chat-thinkblock-icon',
children: [MaterialIcon('neurology', 'large')]
}),
Label({
valign: 'center',
hexpand: true,
xalign: 0,
label: 'Chain of Thought',
className: 'txt sidebar-chat-thinkblock-txt',
}),
Box({
className: 'sidebar-chat-thinkblock-btn-arrow',
homogeneous: true,
children: [expandIcon],
}),
]
}),
setup: setupCursorHover,
}),
mainTextRevealer,
]
});
return widget;
}
Utils.execAsync(['bash', '-c', `rm -rf ${LATEX_DIR}`])
.then(() => Utils.execAsync(['bash', '-c', `mkdir -p ${LATEX_DIR}`]))
.catch(print);
const LatexBlock = (content = '') => {
const latexViewArea = Box({
// vscroll: 'never',
// hscroll: 'automatic',
// homogeneous: true,
attribute: {
'render': async (self, text) => {
if (text.length == 0) return;
const styleContext = self.get_style_context();
const fontSize = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const timeSinceEpoch = Date.now();
const fileName = `${timeSinceEpoch}.tex`;
const outFileName = `${timeSinceEpoch}-symbolic.svg`;
const outIconName = `${timeSinceEpoch}-symbolic`;
const scriptFileName = `${timeSinceEpoch}-render.sh`;
const filePath = `${LATEX_DIR}/${fileName}`;
const outFilePath = `${LATEX_DIR}/${outFileName}`;
const scriptFilePath = `${LATEX_DIR}/${scriptFileName}`;
Utils.writeFile(text, filePath).catch(print);
// Since MicroTex doesn't support file path input properly, we gotta cat it
// And escaping such a command is a fucking pain so I decided to just generate a script
// Note: MicroTex doesn't support `&=`
// You can add this line in the middle for debugging: echo "$text" > ${filePath}.tmp
const renderScript = `#!/usr/bin/env bash
text=$(cat ${filePath} | sed 's/$/ \\\\\\\\/g' | sed 's/&=/=/g')
cd /opt/MicroTeX
./LaTeX -headless -input="$text" -output=${outFilePath} -textsize=${fontSize * 1.1} -padding=0 -maxwidth=${latexViewArea.get_allocated_width() * 0.85} > /dev/null 2>&1
sed -i 's/fill="rgb(0%, 0%, 0%)"/style="fill:#000000"/g' ${outFilePath}
sed -i 's/stroke="rgb(0%, 0%, 0%)"/stroke="${darkMode.value ? '#ffffff' : '#000000'}"/g' ${outFilePath}
`;
Utils.writeFile(renderScript, scriptFilePath).catch(print);
Utils.exec(`chmod a+x ${scriptFilePath}`)
Utils.timeout(100, () => {
Utils.exec(`bash ${scriptFilePath}`);
Gtk.IconTheme.get_default().append_search_path(LATEX_DIR);
self.child?.destroy();
self.child = Gtk.Image.new_from_icon_name(outIconName, 0);
})
}
},
setup: (self) => self.attribute.render(self, content).catch(print),
});
const wholeThing = Box({
className: 'sidebar-chat-latex',
homogeneous: true,
attribute: {
'text': content,
'updateText': (text) => {
wholeThing.attribute.text = text;
latexViewArea.attribute.render(latexViewArea, wholeThing.attribute.text).catch(print);
},
'appendText': (text) => {
wholeThing.attribute.text += text;
latexViewArea.attribute.render(latexViewArea, wholeThing.attribute.text).catch(print);
},
},
children: [Scrollable({
vscroll: 'never',
hscroll: 'automatic',
child: latexViewArea
})]
})
return wholeThing;
}
const CodeBlock = (content = '', lang = 'txt') => {
if (lang == 'tex' || lang == 'latex') {
return LatexBlock(content);
}
const topBar = Box({
className: 'sidebar-chat-codeblock-topbar',
children: [
Label({
label: lang,
className: 'sidebar-chat-codeblock-topbar-txt',
}),
Box({
hexpand: true,
}),
Button({
className: 'sidebar-chat-codeblock-topbar-btn',
child: Box({
className: 'spacing-h-5',
children: [
MaterialIcon('content_copy', 'small'),
Label({
label: 'Copy',
})
]
}),
onClicked: (self) => {
const buffer = sourceView.get_buffer();
const copyContent = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), false); // TODO: fix this
execAsync([`wl-copy`, `${copyContent}`]).catch(print);
},
}),
]
})
// Source view
const sourceView = HighlightedCode(content, lang);
const codeBlock = Box({
attribute: {
'updateText': (text) => {
// Enable useful features for multi-line code
if (text.split('\n').length > 1) {
sourceView.autoIndent = true;
sourceView.highlightCurrentLine = true;
sourceView.showLineNumbers = true;
sourceView.showLineMarks = true;
}
sourceView.get_buffer().set_text(text, -1);
},
'appendText': (text) => {
codeBlock.attribute.updateText(sourceView.get_buffer().text + text);
},
},
className: 'sidebar-chat-codeblock',
vertical: true,
children: [
topBar,
Box({
className: 'sidebar-chat-codeblock-code',
homogeneous: true,
children: [Scrollable({
vscroll: 'never',
hscroll: 'automatic',
child: sourceView,
})],
})
],
setup: (self) => self.hook(darkMode, (self) => {
const schemeManager = GtkSource.StyleSchemeManager.get_default();
Utils.timeout(1000, () => { // Wait for the theme to be loaded
sourceView.buffer.set_style_scheme(schemeManager.get_scheme(`custom${darkMode.value ? '' : '-light'}`));
});
}, "changed"),
})
// const schemeIds = styleManager.get_scheme_ids();
// print("Available Style Schemes:");
// for (let i = 0; i < schemeIds.length; i++) {
// print(schemeIds[i]);
// }
return codeBlock;
}
const Divider = () => Box({
className: 'sidebar-chat-divider',
})
const MessageContent = (content) => {
const contentBox = Box({
vertical: true,
attribute: {
'lastUpdateTextLength': 0,
'inCode': false,
'fullUpdate': (self, content, useCursor = false) => {
// First text widget
if (contentBox.attribute.lastUpdateTextLength === 0
&& contentBox.get_children().length === 0
) {
contentBox.add(TextBlock())
}
const codeBlockRegex = /^\s*```([a-zA-Z0-9]+)?\n?/;
const thinkBlockStartRegex = /^\s*<think>/; // Start: <think>
const thinkBlockEndRegex = /<\/think>\s*$/; // End: </think>
const dividerRegex = /^\s*---/;
const newContent = content.slice(contentBox.attribute.lastUpdateTextLength);
// print("CONTENT:'" + content + "'")
// print("LAST UPDATE LENGTH:" + contentBox.attribute.lastUpdateTextLength)
// print("NEW CONTENT:" + newContent)
if (newContent.length == 0) return;
let lines = replaceInlineLatexWithCodeBlocks(newContent).split('\n');
// let lines = newContent.split('\n');
// Process each line except the last line (potentially incomplete)
let lastProcessed = 0;
for (let [index, line] of lines.entries()) {
if (index == lines.length - 1) break;
// Code blocks
if (codeBlockRegex.test(line)) {
const kids = self.get_children();
const lastLabel = kids[kids.length - 1];
const blockContent = lines.slice(lastProcessed, index).join('\n');
if (!contentBox.attribute.inCode) {
lastLabel.attribute.appendText(blockContent);
if (lastLabel.label === '') lastLabel.destroy();
contentBox.add(CodeBlock('', codeBlockRegex.exec(line)[1]));
}
else {
lastLabel.attribute.appendText(blockContent);
contentBox.add(TextBlock());
}
lastProcessed = index + 1;
contentBox.attribute.inCode = !contentBox.attribute.inCode;
}
// Think block
if (!contentBox.attribute.inCode && (thinkBlockStartRegex.test(line) || thinkBlockEndRegex.test(line))) {
const kids = self.get_children();
const lastLabel = kids[kids.length - 1];
const blockContent = lines.slice(lastProcessed, index).join('\n');
lastLabel.attribute.appendText(blockContent);
if (lastLabel.label === '') lastLabel.destroy();
if (thinkBlockStartRegex.test(line)) contentBox.add(ThinkBlock());
else {
lastLabel.attribute.done();
contentBox.add(TextBlock());
}
lastProcessed = index + 1;
}
// Breaks
if (!contentBox.attribute.inCode && dividerRegex.test(line)) {
const kids = self.get_children();
const lastLabel = kids[kids.length - 1];
const blockContent = lines.slice(lastProcessed, index).join('\n');
lastLabel.attribute.appendText(blockContent);
contentBox.add(Divider());
contentBox.add(TextBlock());
lastProcessed = index + 1;
}
}
if (lastProcessed < lines.length - 1) {
const kids = self.get_children();
const lastLabel = kids[kids.length - 1];
let blockContent = lines.slice(lastProcessed, lines.length - 1).join('\n') + '\n';
lastLabel.attribute.appendText(blockContent);
}
// Debug: plain text
// contentBox.add(Label({
// hpack: 'fill',
// className: 'txt sidebar-chat-txtblock sidebar-chat-txt',
// useMarkup: false,
// xalign: 0,
// wrap: true,
// selectable: true,
// label: '------------------------------\n' + md2pango(content),
// }))
contentBox.show_all();
contentBox.attribute.lastUpdateTextLength = content.length - lines[lines.length - 1].length;
}
}
});
contentBox.attribute.fullUpdate(contentBox, content, false);
return contentBox;
}
export const ChatMessage = (message, modelName = 'Model') => {
const TextSkeleton = (extraClassName = '') => Box({
className: `sidebar-chat-message-skeletonline ${extraClassName}`,
})
const messageContentBox = MessageContent(message.content);
const messageLoadingSkeleton = Box({
vertical: true,
className: 'spacing-v-5',
children: Array.from({ length: 3 }, (_, id) => TextSkeleton(`sidebar-chat-message-skeletonline-offset${id}`)),
})
const messageArea = Stack({
homogeneous: message.role !== 'user',
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
children: {
'thinking': messageLoadingSkeleton,
'message': messageContentBox,
},
shown: message.thinking ? 'thinking' : 'message',
});
const thisMessage = Box({
className: 'sidebar-chat-message',
homogeneous: true,
children: [
Box({
vertical: true,
children: [
Label({
hpack: 'start',
xalign: 0,
className: `txt txt-bold sidebar-chat-name sidebar-chat-name-${message.role == 'user' ? 'user' : 'bot'}`,
wrap: true,
useMarkup: true,
label: (message.role === 'user' ? USERNAME : modelName),
}),
Box({
homogeneous: true,
className: 'sidebar-chat-messagearea',
children: [messageArea]
})
],
setup: (self) => self
.hook(message, (self, isThinking) => {
messageArea.shown = message.thinking ? 'thinking' : 'message';
}, 'notify::thinking')
.hook(message, (self) => { // Message update
messageContentBox.attribute.fullUpdate(messageContentBox, message.content, message.role != 'user');
}, 'notify::content')
.hook(message, (label, isDone) => { // Remove the cursor
if (!isDone && message.role !== 'user') return;
messageContentBox.attribute.fullUpdate(messageContentBox, message.content + '\n', false);
// print('----------------')
// print(message.content)
}, 'notify::done')
,
})
]
});
return thisMessage;
}
export const SystemMessage = (content, commandName, scrolledWindow) => {
const messageContentBox = MessageContent(content + '\n'); // Add newline so everything is added
const thisMessage = Box({
className: 'sidebar-chat-message',
children: [
Box({
vertical: true,
children: [
Label({
xalign: 0,
hpack: 'start',
className: 'txt txt-bold sidebar-chat-name sidebar-chat-name-system',
wrap: true,
label: `System • ${commandName}`,
}),
messageContentBox,
],
})
],
});
return thisMessage;
}
-546
View File
@@ -1,546 +0,0 @@
const { Gdk, GdkPixbuf, Gio, GLib, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, EventBox, Label, Overlay, Revealer, Scrollable, Stack } = Widget;
const { execAsync, exec } = Utils;
import { fileExists } from '../../.miscutils/files.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { MarginRevealer } from '../../.widgethacks/advancedrevealers.js';
import { setupCursorHover, setupCursorHoverInfo } from '../../.widgetutils/cursorhover.js';
import BooruService from '../../../services/booru.js';
import { SystemMessage } from './ai_chatmessage.js';
import { AgsToggle } from '../../.commonwidgets/configwidgets_apps.js';
const IMAGE_REVEAL_DELAY = 13; // Some wait for inits n other weird stuff
const USER_CACHE_DIR = GLib.get_user_cache_dir();
// Create cache folder and clear pics from previous session
Utils.exec(`bash -c 'mkdir -p ${USER_CACHE_DIR}/ags/media/waifus'`);
Utils.exec(`bash -c 'rm ${USER_CACHE_DIR}/ags/media/waifus/*'`);
function getDomainName(url) {
try {
const match = url.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i);
if (!match) return null;
const domainParts = match[1].split('.');
if (domainParts.length > 2) {
// Return only the last two parts (e.g., "yande.re" from "files.yande.re")
return domainParts.slice(-2).join('.');
}
return match[1]; // Return as is if no subdomain
} catch (error) {
print(`Invalid URL: ${url}`);
return null;
}
}
const TagButton = (command, entry) => Button({
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
// Interactions disabled for now because they aren't working
// onClicked: () => { entry.buffer.text += `${command} ` },
// setup: setupCursorHover,
label: command,
});
const CommandButton = (command, displayName = command) => Button({
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
onClicked: () => sendMessage(command),
setup: setupCursorHover,
label: displayName,
});
export const booruTabIcon = Box({
hpack: 'center',
homogeneous: true,
children: [
MaterialIcon('gallery_thumbnail', 'norm'),
]
});
const BooruInfo = () => {
const booruLogo = Label({
hpack: 'center',
className: 'sidebar-chat-welcome-logo',
label: 'gallery_thumbnail',
})
return Box({
vertical: true,
vexpand: true,
className: 'spacing-v-15',
children: [
booruLogo,
Label({
className: 'txt txt-title-small sidebar-chat-welcome-txt',
wrap: true,
justify: Gtk.Justification.CENTER,
label: 'Anime booru',
}),
Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
Label({
className: 'txt-smallie txt-subtext',
wrap: true,
justify: Gtk.Justification.CENTER,
label: getString('Powered by yande.re and konachan'),
}),
Button({
className: 'txt-subtext txt-norm icon-material',
label: 'info',
tooltipText: getString('An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.'),
setup: setupCursorHoverInfo,
}),
]
}),
]
});
}
export const BooruSettings = () => MarginRevealer({
transition: 'slide_down',
revealChild: true,
child: Box({
vertical: true,
className: 'sidebar-chat-settings',
children: [
Box({
vertical: true,
hpack: 'center',
className: 'sidebar-chat-settings-toggles',
children: [
AgsToggle({
icon: 'menstrual_health',
name: getString('Lewds'),
desc: getString("Shows naughty stuff when enabled"),
option: 'sidebar.image.allowNsfw',
extraOnChange: (self, newValue) => {
BooruService.nsfw = newValue;
},
extraSetup: (self) => self.hook(BooruService, (self) => {
self.attribute.enabled.value = BooruService.nsfw;
}, 'notify::nsfw')
}),
]
})
]
})
});
const booruWelcome = Box({
vexpand: true,
homogeneous: true,
child: Box({
className: 'spacing-v-15 margin-top-15 margin-bottom-15',
vpack: 'center',
vertical: true,
children: [
BooruInfo(),
BooruSettings(),
]
})
});
const BooruPage = (taglist, serviceName = 'Booru') => {
const PageState = (icon, name) => Box({
className: 'spacing-h-5 txt margin-right-5',
children: [
Label({
className: 'sidebar-waifu-txt txt-smallie',
xalign: 0,
label: name,
}),
MaterialIcon(icon, 'norm'),
]
})
const ImageAction = ({ name, icon, action }) => Button({
className: 'sidebar-waifu-image-action txt-norm icon-material',
tooltipText: name,
label: icon,
onClicked: action,
setup: setupCursorHover,
})
const PreviewImage = (data, delay = 0) => {
const imageArea = Widget.DrawingArea({
className: 'sidebar-booru-image-drawingarea',
});
const imageBox = Box({
className: 'sidebar-booru-image',
// css: `background-image: url('${data.preview_url}');`,
attribute: {
'update': (self, data, force = false) => {
const imagePath = `${USER_CACHE_DIR}/ags/media/waifus/${data.md5}.${data.file_ext}`;
// const widgetStyleContext = imageArea.get_style_context();
// const widgetWidth = widgetStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
// const widgetWidth = Math.min(Math.floor(booruContent.get_allocated_width() * 0.9 / userOptions.sidebar.image.columns), data["preview_width"]);
const widgetWidth = Math.floor(booruContent.get_allocated_width() * 0.9 / userOptions.sidebar.image.columns);
const widgetHeight = widgetWidth / data.aspect_ratio;
imageArea.set_size_request(widgetWidth, widgetHeight);
const showImage = () => {
const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(imagePath, widgetWidth, widgetHeight, false);
imageArea.connect("draw", (widget, cr) => {
const borderRadius = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
// Draw a rounded rectangle
cr.arc(borderRadius, borderRadius, borderRadius, Math.PI, 1.5 * Math.PI);
cr.arc(widgetWidth - borderRadius, borderRadius, borderRadius, 1.5 * Math.PI, 2 * Math.PI);
cr.arc(widgetWidth - borderRadius, widgetHeight - borderRadius, borderRadius, 0, 0.5 * Math.PI);
cr.arc(borderRadius, widgetHeight - borderRadius, borderRadius, 0.5 * Math.PI, Math.PI);
cr.closePath();
cr.clip();
// Paint image as bg
Gdk.cairo_set_source_pixbuf(cr, pixbuf, (widgetWidth - widgetWidth) / 2, (widgetHeight - widgetHeight) / 2);
cr.paint();
});
self.queue_draw();
imageRevealer.revealChild = true;
}
// Show
// const downloadCommand = `wget -O '${imagePath}' '${data.preview_url}'`;
const downloadCommand = `curl -L -o '${imagePath}' '${data.preview_url}'`;
if (!force && fileExists(imagePath)) showImage();
else Utils.timeout(delay, () => Utils.execAsync(['bash', '-c', downloadCommand])
.then(showImage)
.catch(print)
);
},
},
child: imageArea,
setup: (self) => {
Utils.timeout(1000, () => self.attribute.update(self, data));
}
});
const imageActions = Revealer({
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
vpack: 'start',
className: 'sidebar-booru-image-actions spacing-h-3',
children: [
Box({ hexpand: true }),
ImageAction({
name: `${getString('Go to file url')} (${getDomainName(data.file_url)})`,
icon: 'file_open',
action: () => execAsync(['xdg-open', `https://${getDomainName(data.file_url)}/post/show/${data.id}`]).catch(print),
}),
ImageAction({
name: `${getString('Go to source')} (${getDomainName(data.source)})`,
icon: 'open_in_new',
action: () => execAsync(['xdg-open', `${data.source}`]).catch(print),
}),
ImageAction({
name: getString('Save image'),
icon: 'save',
action: (self) => {
const currentTags = BooruService.queries.at(-1).realTagList.filter(tag => !tag.includes('rating:'));
const tagDirectory = currentTags.join('+');
const fileName = decodeURIComponent((data.file_url).substring((data.file_url).lastIndexOf('/') + 1));
const saveCommand = `mkdir -p "$(xdg-user-dir PICTURES)/homework/${data.is_nsfw ? '🌶️/' : ''}" && curl -L -o "$(xdg-user-dir PICTURES)/homework/${data.is_nsfw ? '🌶️/' : ''}${fileName}" '${data.file_url}'`;
print(saveCommand)
execAsync(['bash', '-c', saveCommand])
.then(() => self.label = 'done')
.catch(print);
},
}),
ImageAction({
name: getString('Set as wallpaper'),
icon: 'wallpaper',
action: (self) => {
const currentTags = BooruService.queries.at(-1).realTagList.filter(tag => !tag.includes('rating:'));
let fileExtension = data.file_ext || 'jpg';
print(data)
const fileName = decodeURIComponent((data.file_url).substring((data.file_url).lastIndexOf('/') + 1));
const saveCommand = `mkdir -p "$(xdg-user-dir PICTURES)/Wallpapers" && curl -L -o "$(xdg-user-dir PICTURES)/Wallpapers/${fileName}" '${data.file_url}'`;
const setWallpaperCommand = `${App.configDir}/scripts/color_generation/switchwall.sh "$(xdg-user-dir PICTURES)/Wallpapers/${fileName}"`;
// const
execAsync(['bash', '-c', `${saveCommand} && ${setWallpaperCommand}`])
.then(() => self.label = 'done')
.catch(print);
},
}),
]
})
});
const imageOverlay = Overlay({
passThrough: true,
child: imageBox,
overlays: [imageActions]
});
const imageRevealer = Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: EventBox({
onHover: () => { imageActions.revealChild = true },
onHoverLost: () => { imageActions.revealChild = false },
child: imageOverlay,
})
})
return imageRevealer;
}
const downloadState = Stack({
homogeneous: false,
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'api': PageState('api', getString('Calling API')),
'download': PageState('downloading', getString('Downloading image')),
'done': PageState('done', getString('Finished!')),
'error': PageState('error', getString('Error')),
},
});
const downloadIndicator = MarginRevealer({
vpack: 'center',
transition: 'slide_left',
revealChild: true,
child: downloadState,
});
const pageHeading = Box({
vertical: true,
children: [
Box({
children: [
Label({
hpack: 'start',
className: `sidebar-booru-provider`,
label: `${serviceName}`,
truncate: 'end',
maxWidthChars: 20,
}),
Box({ hexpand: true }),
downloadIndicator,
]
}),
Box({
className: 'margin-5',
children: [
Scrollable({
hexpand: true,
vscroll: 'never',
hscroll: 'automatic',
child: Box({
hpack: 'fill',
className: 'spacing-h-5',
children: [
...taglist.map((tag) => TagButton(tag)),
Box({ hexpand: true }),
]
})
}),
]
})
]
});
const pageImages = Box({
hpack: 'start',
homogeneous: true,
className: 'sidebar-booru-imagegrid',
})
const pageTip = Revealer({
transition: 'slide_down',
transitionDuration: 0,
revealChild: false,
child: Box({
className: 'txt-subtext margin-5',
children: [
Box({
homogeneous: true,
className: 'sidebar-booru-tip-icon',
children: [MaterialIcon('lightbulb', 'larger')]
}),
Label({
label: getString("No tag in mind? Type a page number"),
className: 'txt-smallie',
wrap: true,
xalign: 0,
})
]
})
})
const pageContentRevealer = Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
revealChild: false,
child: Box({
vertical: true,
children: [
pageImages,
pageTip,
]
}),
});
const thisPage = Box({
homogeneous: true,
className: 'sidebar-chat-message',
attribute: {
'imagePath': '',
'isNsfw': false,
'showContent': () => {
Utils.timeout(IMAGE_REVEAL_DELAY,
() => pageContentRevealer.revealChild = true
);
},
'update': (data, force = false) => {
// Sort by .aspect_ratio
data = data.sort(
(a, b) => a.aspect_ratio - b.aspect_ratio
);
if (data.length == 0) {
pageTip.revealChild = true;
downloadState.shown = 'error';
thisPage.attribute.showContent();
return;
}
const imageColumns = userOptions.sidebar.image.columns;
const imageRows = data.length / imageColumns;
// Init cols
pageImages.children = Array.from(
{ length: imageColumns },
(_, i) => Box({
attribute: { height: 0 },
vertical: true,
})
);
// Greedy add O(n^2) 😭
for (let i = 0; i < data.length; i++) {
// Find column with lowest length
let minHeight = Infinity;
let minIndex = -1;
for (let j = 0; j < imageColumns; j++) {
const height = pageImages.children[j].attribute.height;
if (height < minHeight) {
minHeight = height;
minIndex = j;
}
}
// Add image to it
pageImages.children[minIndex].pack_start(PreviewImage(data[i], minIndex), false, false, 0)
pageImages.children[minIndex].attribute.height += 1 / data[i].aspect_ratio; // we want height/width
}
pageImages.show_all();
// Reveal stuff
thisPage.attribute.showContent();
downloadIndicator.attribute.hide();
},
},
children: [Box({
vertical: true,
children: [
pageHeading,
Box({
vertical: true,
children: [pageContentRevealer],
})
]
})],
});
return thisPage;
}
const booruContent = Box({
className: 'spacing-v-15',
vertical: true,
attribute: {
'map': new Map(),
},
setup: (self) => self
.hook(BooruService, (box, id) => {
if (id === undefined) return;
const newPage = BooruPage(BooruService.queries[id].taglist, BooruService.queries[id].providerName);
box.add(newPage);
box.show_all();
box.attribute.map.set(id, newPage);
}, 'newResponse')
.hook(BooruService, (box, id) => {
if (id === undefined) return;
if (!BooruService.responses[id]) return;
box.attribute.map.get(id)?.attribute.update(BooruService.responses[id]);
}, 'updateResponse')
,
});
export const BooruView = (chatEntry) => Scrollable({
className: 'sidebar-chat-viewport',
vexpand: true,
child: Box({
vertical: true,
children: [
booruWelcome,
booruContent,
]
}),
setup: (scrolledWindow) => {
// Show scrollbar
scrolledWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
const vScrollbar = scrolledWindow.get_vscrollbar();
vScrollbar.get_style_context().add_class('sidebar-scrollbar');
// Avoid click-to-scroll-widget-to-view behavior
Utils.timeout(1, () => {
const viewport = scrolledWindow.child;
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
})
// Scroll to bottom with new content if chat entry not focused
const adjustment = scrolledWindow.get_vadjustment();
adjustment.connect("changed", () => {
if (!chatEntry.hasFocus) return;
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
})
}
});
export const booruCommands = Box({
className: 'spacing-h-5',
setup: (self) => {
self.pack_end(CommandButton('/clear'), false, false, 0);
self.pack_end(CommandButton('+'), false, false, 0);
self.pack_end(CommandButton('/mode konachan', 'Konachan'), false, false, 0);
self.pack_end(CommandButton('/mode yandere', 'yande.re'), false, false, 0);
}
});
const clearChat = () => { // destroy!!
booruContent.attribute.map.forEach((value, key, map) => {
value.destroy();
value = null;
});
}
export const sendMessage = (text, booruView) => {
// Commands
if (text.startsWith('+')) { // Next page
const lastQuery = BooruService.queries.at(-1);
BooruService.fetch(`${lastQuery.realTagList.join(' ')} ${lastQuery.page + 1}`)
}
else if (text.startsWith('/')) {
if (text.startsWith('/clear')) clearChat();
else if (text.startsWith('/safe')) {
BooruService.nsfw = false;
const message = SystemMessage(`Switched to safe mode`, '/safe', booruView)
booruContent.add(message);
booruContent.show_all();
booruContent.attribute.map.set(Date.now(), message);
}
else if (text.startsWith('/lewd')) {
BooruService.nsfw = true;
const message = SystemMessage(`Tiddies enabled`, '/lewd', booruView)
booruContent.add(message);
booruContent.show_all();
booruContent.attribute.map.set(Date.now(), message);
}
else if (text.startsWith('/mode')) {
const mode = text.slice(text.indexOf(' ') + 1);
BooruService.mode = mode;
const message = SystemMessage(`Changed provider to ${BooruService.providerName}`, '/mode', booruView)
booruContent.add(message);
booruContent.show_all();
booruContent.attribute.map.set(Date.now(), message);
}
else if (text.startsWith('/next')) {
sendMessage('+')
}
}
else BooruService.fetch(text);
}
@@ -1,377 +0,0 @@
const { Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, Icon, Label, Revealer, Scrollable } = Widget;
import GPTService from '../../../services/gpt.js';
import { setupCursorHover, setupCursorHoverInfo } from '../../.widgetutils/cursorhover.js';
import { SystemMessage, ChatMessage } from "./ai_chatmessage.js";
import { ConfigToggle, ConfigSegmentedSelection, ConfigGap } from '../../.commonwidgets/configwidgets.js';
import { markdownTest } from '../../.miscutils/md2pango.js';
import { MarginRevealer } from '../../.widgethacks/advancedrevealers.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
const AGS_CONFIG_FILE = `${App.configDir}/user_options.jsonc`;
export const chatGPTTabIcon = Icon({
hpack: 'center',
icon: `openai-symbolic`,
});
const ProviderSwitcher = () => {
const ProviderChoice = (id, provider) => {
const providerSelected = MaterialIcon('check', 'norm', {
setup: (self) => self.hook(GPTService, (self) => {
self.toggleClassName('invisible', GPTService.providerID !== id);
}, 'providerChanged')
});
return Button({
tooltipText: provider.description,
onClicked: () => {
GPTService.providerID = id;
providerList.revealChild = false;
indicatorChevron.label = 'expand_more';
// Save provider to config
Utils.execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ai.defaultGPTProvider \
--value ${id} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
},
child: Box({
className: 'spacing-h-10 txt',
children: [
Icon({
icon: provider['logo_name'],
className: 'txt-large'
}),
Label({
hexpand: true,
xalign: 0,
className: 'txt-small',
label: provider.name,
}),
providerSelected
],
}),
setup: setupCursorHover,
});
}
let indicatorIcon = Icon({
icon: GPTService.providers[GPTService._currentProvider]['logo_name'],
className: 'txt-large',
setup: (self) => self.hook(GPTService, (self) => {
self.icon = GPTService.providers[GPTService.providerID]['logo_name'];
}, 'providerChanged')
});
const indicatorChevron = MaterialIcon('expand_more', 'norm');
const indicatorButton = Button({
tooltipText: getString('Select ChatGPT-compatible API provider'),
child: Box({
className: 'spacing-h-10 txt',
children: [
indicatorIcon,
Label({
hexpand: true,
xalign: 0,
className: 'txt-small',
label: GPTService.providerID,
setup: (self) => self.hook(GPTService, (self) => {
self.label = `${GPTService.providers[GPTService.providerID]['name']}`;
}, 'providerChanged')
}),
indicatorChevron,
]
}),
onClicked: () => {
providerList.revealChild = !providerList.revealChild;
indicatorChevron.label = (providerList.revealChild ? 'expand_less' : 'expand_more');
},
setup: setupCursorHover,
});
const providerList = Revealer({
revealChild: false,
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
vertical: true, className: 'spacing-v-5 sidebar-chat-providerswitcher-list',
children: [
Box({ className: 'separator-line margin-top-5 margin-bottom-5' }),
Box({
className: 'spacing-v-5',
vertical: true,
setup: (self) => self.hook(GPTService, (self) => {
self.children = Object.entries(GPTService.providers)
.map(([id, provider]) => ProviderChoice(id, provider));
}, 'initialized'),
})
]
})
})
return Box({
hpack: 'center',
vertical: true,
className: 'sidebar-chat-providerswitcher',
children: [
indicatorButton,
providerList,
]
})
}
const GPTInfo = () => {
const openAiLogo = Icon({
hpack: 'center',
className: 'sidebar-chat-welcome-logo',
icon: `openai-symbolic`,
});
return Box({
vertical: true,
className: 'spacing-v-15',
children: [
openAiLogo,
Label({
className: 'txt txt-title-small sidebar-chat-welcome-txt',
wrap: true,
justify: Gtk.Justification.CENTER,
label: `Assistant (GPTs)`,
}),
Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
Label({
className: 'txt-smallie txt-subtext',
wrap: true,
justify: Gtk.Justification.CENTER,
label: getString('Provider shown above'),
}),
Button({
className: 'txt-subtext txt-norm icon-material',
label: 'info',
tooltipText: getString("Chat with models compatible with OpenAI's Chat Completions API.\nNot affiliated, endorsed, or sponsored by any of the providers."),
setup: setupCursorHoverInfo,
}),
]
}),
]
});
}
const GPTSettings = () => MarginRevealer({
transition: 'slide_down',
revealChild: true,
extraSetup: (self) => self
.hook(GPTService, (self) => Utils.timeout(200, () => {
self.attribute.hide();
}), 'newMsg')
.hook(GPTService, (self) => Utils.timeout(200, () => {
self.attribute.show();
}), 'clear')
,
child: Box({
vertical: true,
className: 'sidebar-chat-settings',
children: [
ConfigSegmentedSelection({
hpack: 'center',
icon: 'casino',
name: 'Randomness',
desc: getString('The model\'s temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1'),
options: [
{ value: 0.00, name: getString('Precise'), },
{ value: 0.50, name: getString('Balanced'), },
{ value: 1.00, name: getString('Creative'), },
],
initIndex: 1,
onChange: (value, name) => {
GPTService.temperature = value;
},
}),
ConfigGap({ vertical: true, size: 10 }), // Note: size can only be 5, 10, or 15
Box({
vertical: true,
hpack: 'center',
className: 'sidebar-chat-settings-toggles',
children: [
ConfigToggle({
icon: 'model_training',
name: getString('Prompt'),
desc: getString('Tells the model:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points'),
initValue: GPTService.assistantPrompt,
onChange: (self, newValue) => {
GPTService.assistantPrompt = newValue;
},
}),
]
})
]
})
});
export const OpenaiApiKeyInstructions = () => Box({
homogeneous: true,
children: [Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
setup: (self) => self
.hook(GPTService, (self, hasKey) => {
self.revealChild = (
GPTService.providers[GPTService.providerID]["requires_key"]
&& GPTService.key.length == 0);
}, 'hasKey')
,
child: Button({
child: Label({
useMarkup: true,
wrap: true,
className: 'txt sidebar-chat-welcome-txt',
justify: Gtk.Justification.CENTER,
label: getString('An API key is required\nYou can grab one <u>here</u>, then enter it below')
}),
setup: setupCursorHover,
onClicked: () => {
Utils.execAsync(['bash', '-c', `xdg-open ${GPTService.getKeyUrl}`]);
}
})
})]
});
const GPTWelcome = () => Box({
vexpand: true,
homogeneous: true,
child: Box({
className: 'spacing-v-15 margin-top-15 margin-bottom-15',
vpack: 'center',
vertical: true,
children: [
GPTInfo(),
OpenaiApiKeyInstructions(),
GPTSettings(),
]
})
});
export const chatContent = Box({
className: 'spacing-v-5',
vertical: true,
setup: (self) => self
.hook(GPTService, (box, id) => {
const message = GPTService.messages[id];
if (!message) return;
box.add(ChatMessage(message, `Model (${GPTService.providers[GPTService.providerID]['name']})`))
}, 'newMsg')
.hook(GPTService, (self, hasKey) => {
self.revealChild = (
GPTService.providers[GPTService.providerID]["requires_key"]
&& GPTService.key.length == 0);
}, 'providerChanged')
,
});
const clearChat = () => {
GPTService.clear();
const children = chatContent.get_children();
for (let i = 0; i < children.length; i++) {
const child = children[i];
child.destroy();
}
}
const CommandButton = (command) => Button({
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
onClicked: () => sendMessage(command),
setup: setupCursorHover,
label: command,
});
export const chatGPTCommands = Box({
className: 'spacing-h-5',
children: [
Box({ hexpand: true }),
CommandButton('/key'),
CommandButton('/model'),
CommandButton('/clear'),
]
});
export const sendMessage = (text) => {
// Check if text or API key is empty
if (text.length == 0) return;
if (GPTService.providers[GPTService.providerID]["requires_key"]
&& GPTService.key.length == 0
&& !text.startsWith('/key')) {
GPTService.key = text;
chatContent.add(SystemMessage(`Key saved to \`${GPTService.keyPath}\`\nUpdate anytime with \`/key YOUR_API_KEY\`.`, 'API Key', ChatGPTView));
text = '';
return;
}
// Commands
if (text.startsWith('/')) {
if (text.startsWith('/clear')) clearChat();
else if (text.startsWith('/model')) chatContent.add(SystemMessage(`${getString("Currently using")} \`${GPTService.modelName}\``, '/model', ChatGPTView))
else if (text.startsWith('/prompt')) {
const firstSpaceIndex = text.indexOf(' ');
const prompt = text.slice(firstSpaceIndex + 1);
if (firstSpaceIndex == -1 || prompt.length < 1) {
chatContent.add(SystemMessage(`Usage: \`/prompt MESSAGE\``, '/prompt', ChatGPTView))
}
else {
GPTService.addMessage('user', prompt)
}
}
else if (text.startsWith('/key')) {
const parts = text.split(' ');
if (parts.length == 1) chatContent.add(SystemMessage(
`${getString("Key stored in:")}\n\`${GPTService.keyPath}\`\n${getString("To update this key, type")} \`/key YOUR_API_KEY\``,
'/key',
ChatGPTView));
else {
GPTService.key = parts[1];
chatContent.add(SystemMessage(`${getString("Updated API Key at")}\n\`${GPTService.keyPath}\``, '/key', ChatGPTView));
}
}
else if (text.startsWith('/test'))
chatContent.add(SystemMessage(markdownTest, `Markdown test`, ChatGPTView));
else
chatContent.add(SystemMessage(getString("Invalid command."), 'Error', ChatGPTView))
}
else {
GPTService.send(text);
}
}
export const ChatGPTView = (chatEntry) => Box({
vertical: true,
children: [
ProviderSwitcher(),
Scrollable({
className: 'sidebar-chat-viewport',
vexpand: true,
child: Box({
vertical: true,
children: [
GPTWelcome(),
chatContent,
]
}),
setup: (scrolledWindow) => {
// Show scrollbar
scrolledWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
const vScrollbar = scrolledWindow.get_vscrollbar();
vScrollbar.get_style_context().add_class('sidebar-scrollbar');
// Avoid click-to-scroll-widget-to-view behavior
Utils.timeout(1, () => {
const viewport = scrolledWindow.child;
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
})
// Always scroll to bottom with new content
const adjustment = scrolledWindow.get_vadjustment();
adjustment.connect("changed", () => {
if (!chatEntry.hasFocus) return;
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
})
}
})
]
});
-296
View File
@@ -1,296 +0,0 @@
const { Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, Icon, Label, Revealer, Scrollable } = Widget;
import GeminiService from '../../../services/gemini.js';
import { setupCursorHover, setupCursorHoverInfo } from '../../.widgetutils/cursorhover.js';
import { SystemMessage, ChatMessage } from "./ai_chatmessage.js";
import { ConfigToggle, ConfigSegmentedSelection, ConfigGap } from '../../.commonwidgets/configwidgets.js';
import { markdownTest } from '../../.miscutils/md2pango.js';
import { MarginRevealer } from '../../.widgethacks/advancedrevealers.js';
import { AgsToggle } from '../../.commonwidgets/configwidgets_apps.js';
const MODEL_NAME = `Gemini`;
export const geminiTabIcon = Icon({
hpack: 'center',
icon: `google-gemini-symbolic`,
})
const GeminiInfo = () => {
const geminiLogo = Icon({
hpack: 'center',
className: 'sidebar-chat-welcome-logo',
icon: `google-gemini-symbolic`,
});
return Box({
vertical: true,
className: 'spacing-v-15',
children: [
geminiLogo,
Label({
className: 'txt txt-title-small sidebar-chat-welcome-txt',
wrap: true,
justify: Gtk.Justification.CENTER,
label: `Assistant (Gemini)`,
}),
Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
Label({
className: 'txt-smallie txt-subtext',
wrap: true,
justify: Gtk.Justification.CENTER,
label: getString('Powered by Google'),
}),
Button({
className: 'txt-subtext txt-norm icon-material',
label: 'info',
tooltipText: getString("Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model."),
setup: setupCursorHoverInfo,
}),
]
}),
]
});
}
export const GeminiSettings = () => MarginRevealer({
transition: 'slide_down',
revealChild: true,
extraSetup: (self) => self
.hook(GeminiService, (self) => Utils.timeout(200, () => {
self.attribute.hide();
}), 'newMsg')
.hook(GeminiService, (self) => Utils.timeout(200, () => {
self.attribute.show();
}), 'clear')
,
child: Box({
vertical: true,
className: 'sidebar-chat-settings',
children: [
ConfigSegmentedSelection({
hpack: 'center',
icon: 'casino',
name: 'Randomness',
desc: getString("Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1"),
options: [
{ value: 0.00, name: getString('Precise'), },
{ value: 0.50, name: getString('Balanced'), },
{ value: 1.00, name: getString('Creative'), },
],
initIndex: 1,
onChange: (value, name) => {
GeminiService.temperature = value;
},
}),
ConfigGap({ vertical: true, size: 10 }), // Note: size can only be 5, 10, or 15
Box({
vertical: true,
hpack: 'center',
className: 'sidebar-chat-settings-toggles',
children: [
AgsToggle({
icon: 'model_training',
name: getString('Prompt'),
desc: getString("Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points"),
option: "ai.enhancements",
extraOnChange: (self, newValue) => {
GeminiService.assistantPrompt = newValue;
},
extraOnReset: (self, newValue) => {
GeminiService.assistantPrompt = userOptions.ai.enhancements;
},
}),
AgsToggle({
icon: 'shield',
name: getString('Safety'),
desc: getString("When turned off, tells the API (not the model) \nto not block harmful/explicit content"),
option: "ai.safety",
extraOnChange: (self, newValue) => {
GeminiService.safe = newValue;
},
extraOnReset: (self, newValue) => {
GeminiService.safe = userOptions.ai.safety;
},
}),
AgsToggle({
icon: 'history',
name: getString('History'),
desc: getString("Saves chat history\nMessages in previous chats won't show automatically, but they are there"),
option: "ai.useHistory",
extraOnChange: (self, newValue) => {
GeminiService.useHistory = newValue;
},
extraOnReset: (self, newValue) => {
GeminiService.useHistory = userOptions.ai.useHistory;
},
})
]
})
]
})
});
export const GoogleAiInstructions = () => Box({
homogeneous: true,
children: [Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
setup: (self) => self
.hook(GeminiService, (self, hasKey) => {
self.revealChild = (GeminiService.key.length == 0);
}, 'hasKey')
,
child: Button({
child: Label({
useMarkup: true,
wrap: true,
className: 'txt sidebar-chat-welcome-txt',
justify: Gtk.Justification.CENTER,
label: 'A Google AI API key is required\nYou can grab one <u>here</u>, then enter it below',
// setup: self => self.set_markup("This is a <a href=\"https://www.github.com\">test link</a>")
}),
setup: setupCursorHover,
onClicked: () => {
Utils.execAsync(['bash', '-c', `xdg-open https://makersuite.google.com/app/apikey &`]);
}
})
})]
});
const geminiWelcome = Box({
vexpand: true,
homogeneous: true,
child: Box({
className: 'spacing-v-15 margin-top-15 margin-bottom-15',
vpack: 'center',
vertical: true,
children: [
GeminiInfo(),
GoogleAiInstructions(),
GeminiSettings(),
]
})
});
export const chatContent = Box({
className: 'spacing-v-5',
vertical: true,
setup: (self) => self
.hook(GeminiService, (box, id) => {
const message = GeminiService.messages[id];
if (!message) return;
box.add(ChatMessage(message, MODEL_NAME))
}, 'newMsg')
,
});
const clearChat = () => {
GeminiService.clear();
const children = chatContent.get_children();
for (let i = 0; i < children.length; i++) {
const child = children[i];
child.destroy();
}
}
const CommandButton = (command) => Button({
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
onClicked: () => sendMessage(command),
setup: setupCursorHover,
label: command,
});
export const geminiCommands = Box({
className: 'spacing-h-5',
children: [
Box({ hexpand: true }),
CommandButton('/key'),
CommandButton('/model'),
CommandButton('/clear'),
]
});
export const sendMessage = (text) => {
// Check if text or API key is empty
if (text.length == 0) return;
if (GeminiService.key.length == 0) {
GeminiService.key = text;
chatContent.add(SystemMessage(`Key saved to \`${GeminiService.keyPath}\`\nUpdate anytime with /key YOUR_API_KEY.`, 'API Key', GeminiView));
text = '';
return;
}
// Commands
if (text.startsWith('/')) {
if (text.startsWith('/clear')) clearChat();
else if (text.startsWith('/load')) {
clearChat();
GeminiService.loadHistory();
}
else if (text.startsWith('/model')) chatContent.add(SystemMessage(`${getString("Currently using")} \`${GeminiService.modelName}\``, '/model', GeminiView))
else if (text.startsWith('/prompt')) {
const firstSpaceIndex = text.indexOf(' ');
const prompt = text.slice(firstSpaceIndex + 1);
if (firstSpaceIndex == -1 || prompt.length < 1) {
chatContent.add(SystemMessage(`Usage: \`/prompt MESSAGE\``, '/prompt', GeminiView))
}
else {
GeminiService.addMessage('user', prompt)
}
}
else if (text.startsWith('/key')) {
const parts = text.split(' ');
if (parts.length == 1) chatContent.add(SystemMessage(
`${getString("Key stored in:")} \n\`${GeminiService.keyPath}\`\n${getString("To update this key, type")} \`/key YOUR_API_KEY\``,
'/key',
GeminiView));
else {
GeminiService.key = parts[1];
chatContent.add(SystemMessage(`${getString("Updated API Key at")}\n\`${GeminiService.keyPath}\``, '/key', GeminiView));
}
}
else if (text.startsWith('/test'))
chatContent.add(SystemMessage(markdownTest, `Markdown test`, GeminiView));
else
chatContent.add(SystemMessage(getString(`Invalid command.`), 'Error', GeminiView))
}
else {
GeminiService.send(text);
}
}
export const GeminiView = (chatEntry) => Box({
homogeneous: true,
children: [Scrollable({
className: 'sidebar-chat-viewport',
vexpand: true,
child: Box({
vertical: true,
children: [
geminiWelcome,
chatContent,
]
}),
setup: (scrolledWindow) => {
// Show scrollbar
scrolledWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
const vScrollbar = scrolledWindow.get_vscrollbar();
vScrollbar.get_style_context().add_class('sidebar-scrollbar');
// Avoid click-to-scroll-widget-to-view behavior
Utils.timeout(1, () => {
const viewport = scrolledWindow.child;
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
})
// Always scroll to bottom with new content
const adjustment = scrolledWindow.get_vadjustment();
adjustment.connect("changed", () => Utils.timeout(1, () => {
if (!chatEntry.hasFocus) return;
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
}))
}
})]
});
-418
View File
@@ -1,418 +0,0 @@
// TODO: execAsync(['identify', '-format', '{"w":%w,"h":%h}', imagePath])
// to detect img dimensions
const { Gdk, GdkPixbuf, Gio, GLib, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, Label, Overlay, Revealer, Scrollable, Stack } = Widget;
const { execAsync, exec } = Utils;
import { fileExists } from '../../.miscutils/files.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { MarginRevealer } from '../../.widgethacks/advancedrevealers.js';
import { setupCursorHover, setupCursorHoverInfo } from '../../.widgetutils/cursorhover.js';
import WaifuService from '../../../services/waifus.js';
import { darkMode } from '../../.miscutils/system.js';
async function getImageViewerApp(preferredApp) {
return Utils.execAsync(['bash', '-c', `command -v ${preferredApp}`])
.then((output) => {
if (output != '') return preferredApp;
else return 'xdg-open';
})
.catch(print);
}
const IMAGE_REVEAL_DELAY = 13; // Some wait for inits n other weird stuff
const IMAGE_VIEWER_APP = getImageViewerApp(userOptions.apps.imageViewer); // Gnome's image viewer cuz very comfortable zooming
const USER_CACHE_DIR = GLib.get_user_cache_dir();
// Create cache folder and clear pics from previous session
Utils.exec(`bash -c 'mkdir -p ${USER_CACHE_DIR}/ags/media/waifus'`);
Utils.exec(`bash -c 'rm ${USER_CACHE_DIR}/ags/media/waifus/*'`);
const CommandButton = (command) => Button({
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
onClicked: () => sendMessage(command),
setup: setupCursorHover,
label: command,
});
export const waifuTabIcon = Box({
hpack: 'center',
children: [
MaterialIcon('photo', 'norm'),
]
});
const WaifuInfo = () => {
const waifuLogo = Label({
hpack: 'center',
className: 'sidebar-chat-welcome-logo',
label: 'photo',
})
return Box({
vertical: true,
vexpand: true,
className: 'spacing-v-15',
children: [
waifuLogo,
Label({
className: 'txt txt-title-small sidebar-chat-welcome-txt',
wrap: true,
justify: Gtk.Justification.CENTER,
label: 'Waifus',
}),
Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
Label({
className: 'txt-smallie txt-subtext',
wrap: true,
justify: Gtk.Justification.CENTER,
label: getString('Powered by waifu.im + other APIs'),
}),
Button({
className: 'txt-subtext txt-norm icon-material',
label: 'info',
tooltipText: getString('Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.'),
setup: setupCursorHoverInfo,
}),
]
}),
]
});
}
const waifuWelcome = Box({
vexpand: true,
homogeneous: true,
child: Box({
className: 'spacing-v-15 margin-top-15 margin-bottom-15',
vpack: 'center',
vertical: true,
children: [
WaifuInfo(),
]
})
});
const WaifuImage = (taglist) => {
const ImageState = (icon, name) => Box({
className: 'spacing-h-5 txt',
children: [
Box({ hexpand: true }),
Label({
className: 'sidebar-waifu-txt txt-smallie',
xalign: 0,
label: name,
}),
MaterialIcon(icon, 'norm'),
]
})
const ImageAction = ({ name, icon, action }) => Button({
className: 'sidebar-waifu-image-action txt-norm icon-material',
tooltipText: name,
label: icon,
onClicked: action,
setup: setupCursorHover,
})
const downloadState = Stack({
homogeneous: false,
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'api': ImageState('api', getString('Calling API')),
'download': ImageState('downloading', getString('Downloading image')),
'done': ImageState('done', getString('Finished!')),
'error': ImageState('error', getString('Error')),
'notfound': ImageState('error', getString('Not found!')),
},
});
const downloadIndicator = MarginRevealer({
vpack: 'center',
transition: 'slide_left',
revealChild: true,
child: downloadState,
});
const blockHeading = Box({
hpack: 'fill',
className: 'spacing-h-5',
children: [
...taglist.map((tag) => CommandButton(tag)),
Box({ hexpand: true }),
downloadIndicator,
]
});
const blockImageActions = Revealer({
transition: 'crossfade',
revealChild: false,
child: Box({
vertical: true,
children: [
Box({
className: 'sidebar-waifu-image-actions spacing-h-3',
children: [
Box({ hexpand: true }),
ImageAction({
name: getString('Go to source'),
icon: 'link',
action: () => execAsync(['xdg-open', `${thisBlock.attribute.imageData.source}`]).catch(print),
}),
ImageAction({
name: getString('Hoard'),
icon: 'save',
action: (self) => {
execAsync(['bash', '-c', `mkdir -p $(xdg-user-dir PICTURES)/homework${thisBlock.attribute.isNsfw ? '/🌶️' : ''} && cp ${thisBlock.attribute.imagePath} $(xdg-user-dir PICTURES)/homework${thisBlock.attribute.isNsfw ? '/🌶️/' : ''}`])
.then(() => self.label = 'done')
.catch(print);
},
}),
ImageAction({
name: getString('Open externally'),
icon: 'open_in_new',
action: () => execAsync([IMAGE_VIEWER_APP, `${thisBlock.attribute.imagePath}`]).catch(print),
}),
]
})
],
})
})
const blockImage = Widget.DrawingArea({
className: 'sidebar-waifu-image',
});
const blockImageRevealer = Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
revealChild: false,
child: Box({
className: 'margin-top-5',
children: [Overlay({
child: Box({
homogeneous: true,
className: 'sidebar-waifu-image',
children: [blockImage],
}),
overlays: [blockImageActions],
})]
}),
});
const thisBlock = Box({
className: 'sidebar-chat-message',
attribute: {
'imagePath': '',
'isNsfw': false,
'imageData': '',
'update': (imageData, force = false) => {
thisBlock.attribute.imageData = imageData;
const { status, signature, url, extension, source, dominant_color, is_nsfw, width, height, tags } = thisBlock.attribute.imageData;
thisBlock.attribute.isNsfw = is_nsfw;
if (status == 404) {
downloadState.shown = 'notfound';
return;
}
if (status != 200) {
downloadState.shown = 'error';
return;
}
thisBlock.attribute.imagePath = `${USER_CACHE_DIR}/ags/media/waifus/${signature}${extension}`;
downloadState.shown = 'download';
// Width/height
const widgetWidth = Math.min(Math.floor(waifuContent.get_allocated_width() * 0.85), width);
const widgetHeight = Math.ceil(widgetWidth * height / width);
blockImage.set_size_request(widgetWidth, widgetHeight);
const showImage = () => {
downloadState.shown = 'done';
const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(thisBlock.attribute.imagePath, widgetWidth, widgetHeight);
// const pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(thisBlock.attribute.imagePath, widgetWidth, widgetHeight, false);
blockImage.set_size_request(widgetWidth, widgetHeight);
blockImage.connect("draw", (widget, cr) => {
const borderRadius = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
// Draw a rounded rectangle
cr.arc(borderRadius, borderRadius, borderRadius, Math.PI, 1.5 * Math.PI);
cr.arc(widgetWidth - borderRadius, borderRadius, borderRadius, 1.5 * Math.PI, 2 * Math.PI);
cr.arc(widgetWidth - borderRadius, widgetHeight - borderRadius, borderRadius, 0, 0.5 * Math.PI);
cr.arc(borderRadius, widgetHeight - borderRadius, borderRadius, 0.5 * Math.PI, Math.PI);
cr.closePath();
cr.clip();
// Paint image as bg
Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
cr.paint();
});
// Reveal stuff
Utils.timeout(IMAGE_REVEAL_DELAY, () => {
blockImageRevealer.revealChild = true;
})
Utils.timeout(IMAGE_REVEAL_DELAY + blockImageRevealer.transitionDuration,
() => blockImageActions.revealChild = true
);
downloadIndicator.attribute.hide();
}
// Show
if (!force && fileExists(thisBlock.attribute.imagePath)) showImage();
else Utils.execAsync(['bash', '-c', `wget -O '${thisBlock.attribute.imagePath}' '${url}'`])
.then(showImage)
.catch(print);
thisBlock.css = `background-color: mix(${darkMode.value ? 'black' : 'white'}, ${dominant_color}, 0.97);`;
},
},
children: [
Box({
vertical: true,
children: [
blockHeading,
Box({
vertical: true,
hpack: 'start',
children: [blockImageRevealer],
})
]
})
],
});
return thisBlock;
}
const waifuContent = Box({
className: 'spacing-v-15',
vertical: true,
attribute: {
'map': new Map(),
},
setup: (self) => self
.hook(WaifuService, (box, id) => {
if (id === undefined) return;
const newImageBlock = WaifuImage(WaifuService.queries[id]);
box.add(newImageBlock);
box.show_all();
box.attribute.map.set(id, newImageBlock);
}, 'newResponse')
.hook(WaifuService, (box, id) => {
if (id === undefined) return;
const data = WaifuService.responses[id];
if (!data) return;
const imageBlock = box.attribute.map.get(id);
imageBlock?.attribute.update(data);
}, 'updateResponse')
,
});
export const WaifuView = (chatEntry) => Scrollable({
className: 'sidebar-chat-viewport',
vexpand: true,
child: Box({
vertical: true,
children: [
waifuWelcome,
waifuContent,
]
}),
setup: (scrolledWindow) => {
// Show scrollbar
scrolledWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
const vScrollbar = scrolledWindow.get_vscrollbar();
vScrollbar.get_style_context().add_class('sidebar-scrollbar');
// Avoid click-to-scroll-widget-to-view behavior
Utils.timeout(1, () => {
const viewport = scrolledWindow.child;
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
})
// Always scroll to bottom with new content
const adjustment = scrolledWindow.get_vadjustment();
adjustment.connect("changed", () => {
if (!chatEntry.hasFocus) return;
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
})
}
});
const waifuTags = Revealer({
revealChild: false,
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
className: 'spacing-h-5',
children: [
Scrollable({
vscroll: 'never',
hscroll: 'automatic',
hexpand: true,
child: Box({
className: 'spacing-h-5',
children: [
CommandButton('waifu'),
CommandButton('maid'),
CommandButton('uniform'),
CommandButton('oppai'),
CommandButton('selfies'),
CommandButton('marin-kitagawa'),
CommandButton('raiden-shogun'),
CommandButton('mori-calliope'),
]
})
}),
Box({ className: 'separator-line' }),
]
})
});
export const waifuCommands = Box({
className: 'spacing-h-5',
setup: (self) => {
self.pack_end(CommandButton('/clear'), false, false, 0);
self.pack_start(Button({
className: 'sidebar-chat-chip-toggle',
setup: setupCursorHover,
label: getString('Tags →'),
onClicked: () => {
waifuTags.revealChild = !waifuTags.revealChild;
}
}), false, false, 0);
self.pack_start(waifuTags, true, true, 0);
}
});
const clearChat = () => { // destroy!!
waifuContent.attribute.map.forEach((value, key, map) => {
value.destroy();
value = null;
});
}
function newSimpleImageCall(name, url, width, height, dominantColor = '#9392A6') {
const timeSinceEpoch = Date.now();
const newImage = WaifuImage([`/${name}`]);
waifuContent.add(newImage);
waifuContent.attribute.map.set(timeSinceEpoch, newImage);
Utils.timeout(IMAGE_REVEAL_DELAY, () => newImage?.attribute.update({
status: 200,
url: url,
extension: '',
signature: timeSinceEpoch,
source: url,
dominant_color: dominantColor,
is_nsfw: false,
width: width,
height: height,
tags: [`/${name}`],
}, true));
}
export const sendMessage = (text) => {
// Commands
if (text.startsWith('/')) {
if (text.startsWith('/clear')) clearChat();
else if (text.startsWith('/test'))
newSimpleImageCall('test', 'https://picsum.photos/600/400', 300, 200);
else if (text.startsWith('/chino'))
newSimpleImageCall('chino', 'https://chino.pages.dev/chino', 300, 400, '#B2AEF3');
else if (text.startsWith('/place'))
newSimpleImageCall('place', 'https://placewaifu.com/image/400/600', 400, 600, '#F0A235');
}
else WaifuService.fetch(text);
}
-243
View File
@@ -1,243 +0,0 @@
const { Gtk, Gdk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, CenterBox, Entry, EventBox, Icon, Label, Overlay, Revealer, Scrollable, Stack } = Widget;
const { execAsync, exec } = Utils;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
// APIs
import GPTService from '../../services/gpt.js';
import Gemini from '../../services/gemini.js';
import { GeminiView, geminiCommands, sendMessage as geminiSendMessage, geminiTabIcon } from './apis/gemini.js';
import { ChatGPTView, chatGPTCommands, sendMessage as chatGPTSendMessage, chatGPTTabIcon } from './apis/chatgpt.js';
import { WaifuView, waifuCommands, sendMessage as waifuSendMessage, waifuTabIcon } from './apis/waifu.js';
import { BooruView, booruCommands, sendMessage as booruSendMessage, booruTabIcon } from './apis/booru.js';
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
import { checkKeybind } from '../.widgetutils/keybind.js';
const TextView = Widget.subclass(Gtk.TextView, "AgsTextView");
import { widgetContent } from './sideleft.js';
import { IconTabContainer } from '../.commonwidgets/tabcontainer.js';
import { updateNestedProperty } from '../.miscutils/objects.js';
const EXPAND_INPUT_THRESHOLD = 30;
const AGS_CONFIG_FILE = `${App.configDir}/user_options.jsonc`;
export const chatEntry = TextView({
hexpand: true,
wrapMode: Gtk.WrapMode.WORD_CHAR,
acceptsTab: false,
className: 'sidebar-chat-entry txt txt-smallie',
setup: (self) => self
.hook(App, (self, currentName, visible) => {
if (visible && currentName === 'sideleft') {
self.grab_focus();
}
})
.hook(GPTService, (self) => {
if (APIS[currentApiId].name != 'Assistant (GPTs)') return;
self.placeholderText = (GPTService.key.length > 0 ? getString('Message the model...') : getString('Enter API Key...'));
}, 'hasKey')
.hook(Gemini, (self) => {
if (APIS[currentApiId].name != 'Assistant (Gemini Pro)') return;
self.placeholderText = (Gemini.key.length > 0 ? getString('Message Gemini...') : getString('Enter Google AI API Key...'));
}, 'hasKey')
.on("key-press-event", (widget, event) => {
// Don't send when Shift+Enter
if (event.get_keyval()[1] === Gdk.KEY_Return || event.get_keyval()[1] === Gdk.KEY_KP_Enter) {
if (event.get_state()[1] !== 17) {// SHIFT_MASK doesn't work but 17 should be shift
apiSendMessage(widget);
return true;
}
return false;
}
// Keybinds
if (checkKeybind(event, userOptions.keybinds.sidebar.cycleTab))
widgetContent.cycleTab();
else if (checkKeybind(event, userOptions.keybinds.sidebar.nextTab))
widgetContent.nextTab();
else if (checkKeybind(event, userOptions.keybinds.sidebar.prevTab))
widgetContent.prevTab();
else if (checkKeybind(event, userOptions.keybinds.sidebar.apis.nextTab)) {
apiWidgets.attribute.nextTab();
return true;
}
else if (checkKeybind(event, userOptions.keybinds.sidebar.apis.prevTab)) {
apiWidgets.attribute.prevTab();
return true;
}
})
,
});
const APILIST = {
'gemini': {
"name": 'Assistant (Gemini Pro)',
"sendCommand": geminiSendMessage,
"contentWidget": GeminiView(chatEntry),
"commandBar": geminiCommands,
"tabIcon": geminiTabIcon,
"placeholderText": getString('Message Gemini...'),
},
'gpt': {
"name": 'Assistant (GPTs)',
"sendCommand": chatGPTSendMessage,
"contentWidget": ChatGPTView(chatEntry),
"commandBar": chatGPTCommands,
"tabIcon": chatGPTTabIcon,
"placeholderText": getString('Message the model...'),
},
'waifu': {
"name": 'Waifus',
"sendCommand": waifuSendMessage,
"contentWidget": WaifuView(chatEntry),
"commandBar": waifuCommands,
"tabIcon": waifuTabIcon,
"placeholderText": getString('Enter tags'),
},
'booru': {
"name": 'Booru',
"sendCommand": booruSendMessage,
"contentWidget": BooruView(chatEntry),
"commandBar": booruCommands,
"tabIcon": booruTabIcon,
"placeholderText": getString('Enter tags and/or page number'),
},
}
const APIS = userOptions.sidebar.pages.apis.order.map((apiName) => {
const obj = { ...APILIST[apiName] };
obj["id"] = apiName;
return obj;
});
let currentApiId = APIS.findIndex(obj => obj.id === userOptions.sidebar.pages.apis.defaultPage);
function apiSendMessage(textView) {
// Get text
const buffer = textView.get_buffer();
const [start, end] = buffer.get_bounds();
const text = buffer.get_text(start, end, true).trimStart();
if (!text || text.length == 0) return;
// Send
if (APIS[currentApiId].name == APILIST['booru'].name)
APIS[currentApiId].sendCommand(text, APILIST['booru'].contentWidget)
else
APIS[currentApiId].sendCommand(text)
// Reset
buffer.set_text("", -1);
chatEntryWrapper.toggleClassName('sidebar-chat-wrapper-extended', false);
chatEntry.set_valign(Gtk.Align.CENTER);
}
chatEntry.get_buffer().connect("changed", (buffer) => {
const bufferText = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), true);
chatSendButton.toggleClassName('sidebar-chat-send-available', bufferText.length > 0);
chatPlaceholderRevealer.revealChild = (bufferText.length == 0);
if (buffer.get_line_count() > 1 || bufferText.length > EXPAND_INPUT_THRESHOLD) {
chatEntryWrapper.toggleClassName('sidebar-chat-wrapper-extended', true);
chatEntry.set_valign(Gtk.Align.FILL);
chatPlaceholder.set_valign(Gtk.Align.FILL);
}
else {
chatEntryWrapper.toggleClassName('sidebar-chat-wrapper-extended', false);
chatEntry.set_valign(Gtk.Align.CENTER);
chatPlaceholder.set_valign(Gtk.Align.CENTER);
}
});
const chatEntryWrapper = Scrollable({
className: 'sidebar-chat-wrapper',
hscroll: 'never',
vscroll: 'always',
child: chatEntry,
});
const chatSendButton = Button({
className: 'txt-norm icon-material sidebar-chat-send',
vpack: 'end',
label: 'arrow_upward',
setup: setupCursorHover,
onClicked: (self) => {
APIS[currentApiId].sendCommand(chatEntry.get_buffer().text);
chatEntry.get_buffer().set_text("", -1);
},
});
const chatPlaceholder = Label({
className: 'txt-subtext txt-smallie margin-left-5',
hpack: 'start',
vpack: 'center',
label: APIS[currentApiId].placeholderText,
});
const chatPlaceholderRevealer = Revealer({
revealChild: true,
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
child: chatPlaceholder,
setup: enableClickthrough,
});
const textboxArea = Box({ // Entry area
className: 'sidebar-chat-textarea',
children: [
Overlay({
passThrough: true,
child: chatEntryWrapper,
overlays: [chatPlaceholderRevealer],
}),
Box({ className: 'width-10' }),
chatSendButton,
]
});
const apiCommandStack = Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
children: APIS.reduce((acc, api) => {
acc[api.name] = api.commandBar;
return acc;
}, {}),
})
export const apiContentStack = IconTabContainer({
tabSwitcherClassName: 'sidebar-icontabswitcher',
className: 'margin-top-5',
iconWidgets: APIS.map((api) => api.tabIcon),
names: APIS.map((api) => api.name),
children: APIS.map((api) => api.contentWidget),
initIndex: currentApiId,
onChange: (self, id) => {
apiCommandStack.shown = APIS[id].name;
chatPlaceholder.label = APIS[id].placeholderText;
currentApiId = id;
const pageName = APIS[id].id;
const option = 'sidebar.pages.apis.defaultPage';
updateNestedProperty(userOptions, option, pageName);
execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--value ${pageName} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
}
});
function switchToTab(id) {
apiContentStack.shown.value = id;
}
const apiWidgets = Widget.Box({
attribute: {
'nextTab': () => switchToTab(Math.min(currentApiId + 1, APIS.length - 1)),
'prevTab': () => switchToTab(Math.max(0, currentApiId - 1)),
},
vertical: true,
className: 'spacing-v-10',
homogeneous: false,
children: [
apiContentStack,
apiCommandStack,
textboxArea,
],
});
export default apiWidgets;
-18
View File
@@ -1,18 +0,0 @@
import PopupWindow from '../.widgethacks/popupwindow.js';
import SidebarLeft from "./sideleft.js";
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box } = Widget;
import clickCloseRegion from '../.commonwidgets/clickcloseregion.js';
export default () => PopupWindow({
keymode: 'on-demand',
anchor: ['left', 'top', 'bottom'],
name: 'sideleft',
layer: 'top',
child: Box({
children: [
SidebarLeft(),
clickCloseRegion({ name: 'sideleft', multimonitor: false, fillMonitor: 'horizontal' }),
]
})
});
-158
View File
@@ -1,158 +0,0 @@
const { Gdk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, EventBox, Label, Revealer, Scrollable, Stack } = Widget;
const { execAsync, exec } = Utils;
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import toolBox from './toolbox.js';
import apiWidgets from './apiwidgets.js';
import { chatEntry } from './apiwidgets.js';
import { TabContainer } from '../.commonwidgets/tabcontainer.js';
import { checkKeybind } from '../.widgetutils/keybind.js';
import { updateNestedProperty } from '../.miscutils/objects.js';
const AGS_CONFIG_FILE = `${App.configDir}/user_options.jsonc`;
const SIDEBARTABS = {
'apis': {
name: 'apis',
content: apiWidgets,
materialIcon: 'api',
friendlyName: 'APIs',
},
'tools': {
name: 'tools',
content: toolBox,
materialIcon: 'home_repair_service',
friendlyName: 'Tools',
},
}
const CONTENTS = userOptions.sidebar.pages.order.map((tabName) => SIDEBARTABS[tabName])
// const pinButton = Button({
// attribute: {
// 'enabled': false,
// 'toggle': (self) => {
// self.attribute.enabled = !self.attribute.enabled;
// self.toggleClassName('sidebar-controlbtn-enabled', self.attribute.enabled);
// const sideleftWindow = App.getWindow('sideleft');
// const sideleftContent = sideleftWindow.get_children()[0].get_children()[0].get_children()[1];
// sideleftContent.toggleClassName('sidebar-pinned', self.attribute.enabled);
// if (self.attribute.enabled) {
// sideleftWindow.exclusivity = 'exclusive';
// }
// else {
// sideleftWindow.exclusivity = 'normal';
// }
// },
// },
// vpack: 'start',
// className: 'sidebar-controlbtn',
// child: MaterialIcon('push_pin', 'larger'),
// tooltipText: `Pin sidebar (${userOptions.keybinds.sidebar.pin})`,
// onClicked: (self) => self.attribute.toggle(self),
// setup: (self) => {
// setupCursorHover(self);
// self.hook(App, (self, currentName, visible) => {
// if (currentName === 'sideleft' && visible) self.grab_focus();
// })
// },
// })
const expandButton = Button({
attribute: {
'enabled': false,
'toggle': (self) => {
self.attribute.enabled = !self.attribute.enabled;
// We don't expand the bar, but the expand button. Funny hax but it works
// (somehow directly expanding the sidebar directly makes it unable to unexpand)
self.toggleClassName('sidebar-expandbtn-enabled', self.attribute.enabled);
self.toggleClassName('sidebar-controlbtn-enabled', self.attribute.enabled);
},
},
vpack: 'start',
className: 'sidebar-controlbtn',
child: MaterialIcon('expand_content', 'larger'),
tooltipText: `Expand sidebar (${userOptions.keybinds.sidebar.expand})`,
onClicked: (self) => self.attribute.toggle(self),
setup: setupCursorHover,
})
export const widgetContent = TabContainer({
icons: CONTENTS.map((item) => item.materialIcon),
names: CONTENTS.map((item) => item.friendlyName),
children: CONTENTS.map((item) => item.content),
className: 'sidebar-left spacing-v-10',
initIndex: CONTENTS.findIndex(obj => obj.name === userOptions.sidebar.pages.defaultPage),
onChange: (self, index) => {
const pageName = CONTENTS[index].name;
const option = 'sidebar.pages.defaultPage';
updateNestedProperty(userOptions, option, pageName);
execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--value ${pageName} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
},
extraTabStripWidgets: [
// pinButton,
expandButton,
]
});
export default () => {
return Box({
// vertical: true,
vexpand: true,
css: 'min-width: 2px;',
children: [
widgetContent,
],
setup: (self) => self
.on('key-press-event', (widget, event) => { // Handle keybinds
if (checkKeybind(event, userOptions.keybinds.sidebar.cycleTab))
widgetContent.cycleTab();
else if (checkKeybind(event, userOptions.keybinds.sidebar.nextTab))
widgetContent.nextTab();
else if (checkKeybind(event, userOptions.keybinds.sidebar.prevTab))
widgetContent.prevTab();
else if (checkKeybind(event, userOptions.keybinds.sidebar.expand))
expandButton.attribute.toggle(expandButton);
// if (checkKeybind(event, userOptions.keybinds.sidebar.pin))
// pinButton.attribute.toggle(pinButton);
if (widgetContent.attribute.names[widgetContent.attribute.shown.value] == 'APIs') { // If api tab is focused
// Focus entry when typing
if ((
!(event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) &&
event.get_keyval()[1] >= 32 && event.get_keyval()[1] <= 126 &&
widget != chatEntry && event.get_keyval()[1] != Gdk.KEY_space)
||
((event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) &&
event.get_keyval()[1] === Gdk.KEY_v)
) {
chatEntry.grab_focus();
const buffer = chatEntry.get_buffer();
buffer.set_text(buffer.text + String.fromCharCode(event.get_keyval()[1]), -1);
buffer.place_cursor(buffer.get_iter_at_offset(-1));
}
// Switch API type
else if (checkKeybind(event, userOptions.keybinds.sidebar.apis.nextTab)) {
const toSwitchTab = widgetContent.attribute.children[widgetContent.attribute.shown.value];
toSwitchTab.nextTab();
}
else if (checkKeybind(event, userOptions.keybinds.sidebar.apis.prevTab)) {
const toSwitchTab = widgetContent.attribute.children[widgetContent.attribute.shown.value];
toSwitchTab.prevTab();
}
}
})
,
});
}
-22
View File
@@ -1,22 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Label, Scrollable } = Widget;
import QuickScripts from './tools/quickscripts.js';
import ColorPicker from './tools/colorpicker.js';
import Conversions from './tools/conversions.js';
import Name from './tools/name.js';
export default Scrollable({
hscroll: "never",
vscroll: "automatic",
child: Box({
vertical: true,
className: 'spacing-v-10',
children: [
QuickScripts(),
Conversions(),
ColorPicker(),
Box({ vexpand: true }),
Name(),
]
})
});
@@ -1,99 +0,0 @@
#!/bin/bash
# Function to get the current resolution
get_current_resolution() {
local output
output=$(hyprctl monitors -j)
local width height refreshRate
width=$(echo "$output" | jq -r '.[0].width')
height=$(echo "$output" | jq -r '.[0].height')
refreshRate=$(echo "$output" | jq -r '.[0].refreshRate')
echo "$width $height $refreshRate"
}
# Function to update the Hyprland configuration with the new resolution
update_resolution_config() {
local newWidth="$1"
local newHeight="$2"
local newRefreshRate="$3"
local currentRes
currentRes=$(get_current_resolution)
local width height refreshRate
width=${newWidth:-$(echo "$currentRes" | awk '{print $1}')}
height=${newHeight:-$(echo "$currentRes" | awk '{print $2}')}
refreshRate=${newRefreshRate:-$(echo "$currentRes" | awk '{print $3}')}
local modelineOutput
modelineOutput=$(gtf "$width" "$height" "$refreshRate")
local modeline
modeline=$(echo "$modelineOutput" | grep -oP 'Modeline "\K[^"]+')
if [ -z "$modeline" ]; then
echo "Failed to generate modeline"
exit 1
fi
# Extract the resolution and refresh rate from the modeline
local resolution
resolution=$(echo "$modeline" | grep -oP '^[0-9]+x[0-9]+')
local rate
rate=$(echo "$modeline" | grep -oP '[0-9]+.[0-9]+$')
if [ -z "$resolution" ] || [ -z "$rate" ]; then
echo "Failed to extract resolution or refresh rate from modeline"
exit 1
fi
local configPath="${HOME}/.config/hypr/hyprland/general.conf"
local newConfigContent
newConfigContent=$(sed "s/^monitor=.*$/monitor=eDP-1, $resolution@$rate, auto, 1/" "$configPath")
echo "$newConfigContent" > "$configPath"
}
# Main script
echo "Welcome to the Resolution Configurator"
echo ""
echo " +---------------------------+"
echo " | _____ |"
echo " | | | |"
echo " | | | |"
echo " | |_____| |"
echo " | |"
echo " +---------------------------+"
echo ""
echo "Current resolution and refresh rate:"
currentRes=$(get_current_resolution)
width=$(echo "$currentRes" | awk '{print $1}')
height=$(echo "$currentRes" | awk '{print $2}')
refreshRate=$(echo "$currentRes" | awk '{print $3}')
echo "Width: $width px"
echo "Height: $height px"
echo "Refresh Rate: $refreshRate Hz"
echo ""
read -p "Enter new width (or press Enter to keep current width): " newWidth
read -p "Enter new height (or press Enter to keep current height): " newHeight
read -p "Enter new refresh rate (or press Enter to keep current refresh rate): " newRefreshRate
# Validate inputs (if provided)
if [[ ! "$newWidth" =~ ^[0-9]+$ && -n "$newWidth" ]]; then
echo "Invalid width value."
exit 1
fi
if [[ ! "$newHeight" =~ ^[0-9]+$ && -n "$newHeight" ]]; then
echo "Invalid height value."
exit 1
fi
if [[ ! "$newRefreshRate" =~ ^[0-9]+$ && -n "$newRefreshRate" ]]; then
echo "Invalid refresh rate value."
exit 1
fi
update_resolution_config "$newWidth" "$newHeight" "$newRefreshRate"
echo "Resolution updated successfully."
-198
View File
@@ -1,198 +0,0 @@
// It's weird, I know
const { Gio, GLib } = imports.gi;
import Service from 'resource:///com/github/Aylur/ags/service.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { exec, execAsync } = Utils;
import { clamp } from '../../.miscutils/mathfuncs.js';
export class ColorPickerSelection extends Service {
static {
Service.register(this, {
'picked': [],
'assigned': ['int'],
'hue': [],
'sl': [],
});
}
_hue = 198;
_xAxis = 94;
_yAxis = 80;
get hue() { return this._hue; }
set hue(value) {
this._hue = clamp(value, 0, 360);
this.emit('hue');
this.emit('picked');
this.emit('changed');
}
get xAxis() { return this._xAxis; }
set xAxis(value) {
this._xAxis = clamp(value, 0, 100);
this.emit('sl');
this.emit('picked');
this.emit('changed');
}
get yAxis() { return this._yAxis; }
set yAxis(value) {
this._yAxis = clamp(value, 0, 100);
this.emit('sl');
this.emit('picked');
this.emit('changed');
}
setColorFromHex(hexString, id) {
const hsl = hexToHSL(hexString);
this._hue = hsl.hue;
this._xAxis = hsl.saturation;
// this._yAxis = hsl.lightness;
this._yAxis = (100 - hsl.saturation / 2) / 100 * hsl.lightness;
// console.log(this._hue, this._xAxis, this._yAxis)
this.emit('assigned', id);
this.emit('changed');
}
constructor() {
super();
this.emit('changed');
}
}
export function hslToRgbValues(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
const to255 = x => Math.round(x * 255);
r = to255(r);
g = to255(g);
b = to255(b);
return `${Math.round(r)},${Math.round(g)},${Math.round(b)}`;
// return `rgb(${r},${g},${b})`;
}
export function hslToHex(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
const toHex = x => {
const hex = Math.round(x * 255).toString(16);
return hex.length === 1 ? "0" + hex : hex;
};
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
// export function hexToHSL(hex) {
// // Remove the '#' if present
// hex = hex.replace(/^#/, '');
// // Parse the hex value into RGB components
// const bigint = parseInt(hex, 16);
// const r = (bigint >> 16) & 255;
// const g = (bigint >> 8) & 255;
// const b = bigint & 255;
// // Normalize RGB values to range [0, 1]
// const normalizedR = r / 255;
// const normalizedG = g / 255;
// const normalizedB = b / 255;
// // Find the maximum and minimum values
// const max = Math.max(normalizedR, normalizedG, normalizedB);
// const min = Math.min(normalizedR, normalizedG, normalizedB);
// // Calculate the lightness
// const lightness = (max + min) / 2;
// // If the color is grayscale, set saturation to 0
// if (max === min) {
// return {
// hue: 0,
// saturation: 0,
// lightness: lightness * 100 // Convert to percentage
// };
// }
// // Calculate the saturation
// const d = max - min;
// const saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min);
// // Calculate the hue
// let hue;
// if (max === normalizedR) {
// hue = ((normalizedG - normalizedB) / d + (normalizedG < normalizedB ? 6 : 0)) * 60;
// } else if (max === normalizedG) {
// hue = ((normalizedB - normalizedR) / d + 2) * 60;
// } else {
// hue = ((normalizedR - normalizedG) / d + 4) * 60;
// }
// return {
// hue: Math.round(hue),
// saturation: Math.round(saturation * 100), // Convert to percentage
// lightness: Math.round(lightness * 100) // Convert to percentage
// };
// }
export function hexToHSL(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
var r = parseInt(result[1], 16);
var g = parseInt(result[2], 16);
var b = parseInt(result[3], 16);
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
s = s * 100;
s = Math.round(s);
l = l * 100;
l = Math.round(l);
h = Math.round(360 * h);
return {
hue: h,
saturation: s,
lightness: l
};
}
@@ -1,283 +0,0 @@
// TODO: Make selection update when entry changes
const { Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
const { Box, Button, Entry, EventBox, Icon, Label, Overlay, Scrollable } = Widget;
import SidebarModule from './module.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { ColorPickerSelection, hslToHex, hslToRgbValues, hexToHSL } from './color.js';
import { clamp } from '../../.miscutils/mathfuncs.js';
export default () => {
const selectedColor = new ColorPickerSelection();
function shouldUseBlackColor() {
return ((selectedColor.xAxis < 40 || (45 <= selectedColor.hue && selectedColor.hue <= 195)) &&
selectedColor.yAxis > 60);
}
const colorBlack = 'rgba(0,0,0,0.9)';
const colorWhite = 'rgba(255,255,255,0.9)';
const hueRange = Box({
homogeneous: true,
className: 'sidebar-module-colorpicker-wrapper',
children: [Box({
className: 'sidebar-module-colorpicker-hue',
css: `background: linear-gradient(to bottom, #ff6666, #ffff66, #66dd66, #66ffff, #6666ff, #ff66ff, #ff6666);`,
})],
});
const hueSlider = Box({
vpack: 'start',
className: 'sidebar-module-colorpicker-cursorwrapper',
css: `margin-top: ${13.636 * selectedColor.hue / 360}rem;`,
homogeneous: true,
children: [Box({
className: 'sidebar-module-colorpicker-hue-cursor',
})],
setup: (self) => self.hook(selectedColor, () => {
const widgetHeight = hueRange.children[0].get_allocated_height();
self.setCss(`margin-top: ${13.636 * selectedColor.hue / 360}rem;`)
}),
});
const hueSelector = Box({
children: [EventBox({
child: Overlay({
child: hueRange,
overlays: [hueSlider],
}),
attribute: {
clicked: false,
setHue: (self, event) => {
const widgetHeight = hueRange.children[0].get_allocated_height();
const [_, cursorX, cursorY] = event.get_coords();
const cursorYPercent = clamp(cursorY / widgetHeight, 0, 1);
selectedColor.hue = Math.round(cursorYPercent * 360);
}
},
setup: (self) => self
.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
self.attribute.setHue(self, event);
})
.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
self.attribute.setHue(self, event);
})
.on('button-release-event', (self) => self.attribute.clicked = false)
,
})]
});
const saturationAndLightnessRange = Box({
homogeneous: true,
children: [Box({
className: 'sidebar-module-colorpicker-saturationandlightness',
attribute: {
update: (self) => {
// css: `background: linear-gradient(to right, #ffffff, color);`,
self.setCss(`background:
linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,1)),
linear-gradient(to right, #ffffff, ${hslToHex(selectedColor.hue, 100, 50)});
`);
},
},
setup: (self) => self
.hook(selectedColor, self.attribute.update, 'hue')
.hook(selectedColor, self.attribute.update, 'assigned')
,
})],
});
const saturationAndLightnessCursor = Box({
className: 'sidebar-module-colorpicker-saturationandlightness-cursorwrapper',
children: [Box({
vpack: 'start',
hpack: 'start',
homogeneous: true,
css: `
margin-left: ${13.636 * selectedColor.xAxis / 100}rem;
margin-top: ${13.636 * (100 - selectedColor.yAxis) / 100}rem;
`, // Why 13.636rem? see class name in stylesheet
attribute: {
update: (self) => {
const allocation = saturationAndLightnessRange.children[0].get_allocation();
self.setCss(`
margin-left: ${13.636 * selectedColor.xAxis / 100}rem;
margin-top: ${13.636 * (100 - selectedColor.yAxis) / 100}rem;
`); // Why 13.636rem? see class name in stylesheet
}
},
setup: (self) => self
.hook(selectedColor, self.attribute.update, 'sl')
.hook(selectedColor, self.attribute.update, 'assigned')
,
children: [Box({
className: 'sidebar-module-colorpicker-saturationandlightness-cursor',
css: `
background-color: ${hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))};
border-color: ${shouldUseBlackColor() ? colorBlack : colorWhite};
`,
attribute: {
update: (self) => {
self.setCss(`
background-color: ${hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))};
border-color: ${shouldUseBlackColor() ? colorBlack : colorWhite};
`);
}
},
setup: (self) => self
.hook(selectedColor, self.attribute.update, 'sl')
.hook(selectedColor, self.attribute.update, 'hue')
.hook(selectedColor, self.attribute.update, 'assigned')
,
})],
})]
});
const saturationAndLightnessSelector = Box({
homogeneous: true,
className: 'sidebar-module-colorpicker-saturationandlightness-wrapper',
children: [EventBox({
child: Overlay({
child: saturationAndLightnessRange,
overlays: [saturationAndLightnessCursor],
}),
attribute: {
clicked: false,
setSaturationAndLightness: (self, event) => {
const allocation = saturationAndLightnessRange.children[0].get_allocation();
const [_, cursorX, cursorY] = event.get_coords();
const cursorXPercent = clamp(cursorX / allocation.width, 0, 1);
const cursorYPercent = clamp(cursorY / allocation.height, 0, 1);
selectedColor.xAxis = Math.round(cursorXPercent * 100);
selectedColor.yAxis = Math.round(100 - cursorYPercent * 100);
}
},
setup: (self) => self
.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
self.attribute.setSaturationAndLightness(self, event);
})
.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
self.attribute.setSaturationAndLightness(self, event);
})
.on('button-release-event', (self) => self.attribute.clicked = false)
,
})]
});
const resultColorBox = Box({
className: 'sidebar-module-colorpicker-result-box',
homogeneous: true,
css: `background-color: ${hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))};`,
children: [Label({
className: 'txt txt-small',
label: getString('Result'),
}),],
attribute: {
update: (self) => {
self.setCss(`background-color: ${hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))};`);
self.children[0].setCss(`color: ${shouldUseBlackColor() ? colorBlack : colorWhite};`)
}
},
setup: (self) => self
.hook(selectedColor, self.attribute.update, 'sl')
.hook(selectedColor, self.attribute.update, 'hue')
.hook(selectedColor, self.attribute.update, 'assigned')
,
});
const ResultBox = ({ colorSystemName, updateCallback, copyCallback }) => Box({
children: [
Box({
vertical: true,
hexpand: true,
children: [
Label({
xalign: 0,
className: 'txt-tiny',
label: colorSystemName,
}),
Overlay({
child: Entry({
widthChars: 10,
className: 'txt-small techfont',
attribute: {
id: 0,
update: updateCallback,
},
setup: (self) => self
.hook(selectedColor, self.attribute.update, 'sl')
.hook(selectedColor, self.attribute.update, 'hue')
.hook(selectedColor, self.attribute.update, 'assigned')
// .on('activate', (self) => {
// const newColor = self.text;
// if (newColor.length != 7) return;
// selectedColor.setColorFromHex(self.text, self.attribute.id);
// })
,
}),
})
]
}),
Button({
child: MaterialIcon('content_copy', 'norm'),
onClicked: (self) => {
copyCallback(self);
self.child.label = 'done';
Utils.timeout(1000, () => self.child.label = 'content_copy');
},
setup: setupCursorHover,
})
]
});
const resultHex = ResultBox({
colorSystemName: 'Hex',
updateCallback: (self, id) => {
if (id && self.attribute.id === id) return;
self.text = hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100));
},
copyCallback: () => Utils.execAsync(['wl-copy', `${hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))}`]),
})
const resultRgb = ResultBox({
colorSystemName: 'RGB',
updateCallback: (self, id) => {
if (id && self.attribute.id === id) return;
self.text = hslToRgbValues(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100));
},
copyCallback: () => Utils.execAsync(['wl-copy', `rgb(${hslToRgbValues(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))})`]),
})
const resultHsl = ResultBox({
colorSystemName: 'HSL',
updateCallback: (self, id) => {
if (id && self.attribute.id === id) return;
self.text = `${selectedColor.hue},${selectedColor.xAxis}%,${Math.round(selectedColor.yAxis / (1 + selectedColor.xAxis / 100))}%`;
},
copyCallback: () => Utils.execAsync(['wl-copy', `hsl(${selectedColor.hue},${selectedColor.xAxis}%,${Math.round(selectedColor.yAxis / (1 + selectedColor.xAxis / 100))}%)`]),
})
const result = Box({
className: 'sidebar-module-colorpicker-result-area spacing-v-5 txt',
hexpand: true,
vertical: true,
children: [
resultColorBox,
resultHex,
resultRgb,
resultHsl,
]
})
return SidebarModule({
icon: MaterialIcon('colorize', 'norm'),
name: getString('Color picker'),
revealChild: false,
child: Box({
className: 'spacing-h-5',
children: [
hueSelector,
saturationAndLightnessSelector,
result,
]
})
});
}
@@ -1,169 +0,0 @@
const { Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
const { Box, Button, Entry, EventBox, Icon, Label, Scrollable, Overlay } = Widget;
import SidebarModule from './module.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { truncateToPrecision } from '../../.miscutils/mathfuncs.js';
const VALUE_DEFAULT_PRECISION = 3;
const conversions = [
{
unit1: 'px',
unit2: 'rem',
unit1Default: 5,
formula1to2: '{{x}} / (parseFloat(Utils.exec(\'gsettings get org.gnome.desktop.interface font-name\').split(" ").pop().split("\'"))*4/3)',
formula2to1: '{{x}} * (parseFloat(Utils.exec(\'gsettings get org.gnome.desktop.interface font-name\').split(" ").pop().split("\'"))*4/3)',
forcePrecision: true,
},
{
unit1: 'deg',
unit2: 'rad',
unit1Default: 90,
formula1to2: '{{x}} * Math.PI / 180',
formula2to1: '{{x}} * 180 / Math.PI',
},
{
unit1: '°F',
unit2: '°C',
unit1Default: 68,
formula1to2: '({{x}} - 32) * 5 / 9',
formula2to1: '{{x}} * 9 / 5 + 32',
},
{
unit1: 'Ft',
unit2: 'Cm',
formula1to2: '{{x}} * 30.48',
formula2to1: '{{x}} / 30.48',
},
// {
// unit1: 'Mile',
// unit2: 'Km',
// formula1to2: '{{x}} * 1.60934',
// formula2to1: '{{x}} / 1.60934',
// },
// {
// unit1: 'Inch',
// unit2: 'Cm',
// formula1to2: '{{x}} * 2.54',
// formula2to1: '{{x}} / 2.54',
// },
{
unit1: 'lbs',
unit2: 'Kg',
formula1to2: '{{x}} * 0.453592',
formula2to1: '{{x}} / 0.453592',
}
]
export default () => {
const ValueBox = ({ unit, initValue = 0, updateCallback }) => {
const unitName = Label({
xalign: 0,
className: 'txt txt-smallie txt-semibold margin-top-2 margin-left-2',
label: `${unit}`,
});
const entry = Entry({
hexpand: 'true',
widthChars: 10,
className: 'txt-small techfont margin-left-2',
text: `${initValue}`,
onChange: updateCallback,
});
const copyButton = Button({
className: 'sidebar-module-csscalc-valuebox-copybtn',
child: MaterialIcon('content_copy', 'norm'),
onClicked: (self) => {
Utils.execAsync(['wl-copy', entry.text]);
self.child.label = 'done';
Utils.timeout(1000, () => self.child.label = 'content_copy');
},
setup: setupCursorHover,
});
const wholeThing = Box({
className: 'sidebar-module-csscalc-valuebox',
vertical: true,
hexpand: true,
children: [
unitName,
Box({
children: [
entry,
copyButton,
]
})
],
attribute: {
updateValue: (value) => entry.text = `${value}`,
getValue: () => entry.text,
}
});
return wholeThing;
}
// Formula format is js expression, with `{{x}}` being the input value
const BidirectionalConversion = ({
unit1, unit2, unit1Default = 1,
formula1to2, formula2to1,
forcePrecision = false, precision = VALUE_DEFAULT_PRECISION,
}) => {
let updateLock = false;
const convert = (value, formula) => {
let thisValue;
try {
thisValue = eval(value)
} catch (error) {
thisValue = parseFloat(value);
}
// print(formula.replace('{{x}}', thisValue))
// print(eval(formula.replace('{{x}}', thisValue)))
const evalResult = eval(formula.replace('{{x}}', thisValue));
const result = forcePrecision ?
evalResult.toFixed(precision) : truncateToPrecision(evalResult, precision);
// print(result)
return result;
}
const unit1Box = ValueBox({
unit: unit1,
initValue: unit1Default,
updateCallback: (self) => {
if (updateLock) return;
updateLock = true;
const newValue = convert(self.text, formula1to2);
unit2Box.attribute.updateValue(newValue || 0);
updateLock = false;
},
});
const unit2Box = ValueBox({
unit: unit2,
initValue: truncateToPrecision(eval(formula1to2.replace('\{{x}}', unit1Default)), precision),
updateCallback: (self) => {
if (updateLock) return;
updateLock = true;
const newValue = convert(self.text, formula2to1);
unit1Box.attribute.updateValue(newValue || 0);
updateLock = false;
},
});
return Box({
className: 'txt spacing-h-10',
children: [
unit1Box,
MaterialIcon('swap_horiz', 'large'),
unit2Box,
]
})
}
return SidebarModule({
icon: MaterialIcon('autorenew', 'norm'),
name: getString('Conversions'),
child: Box({
vertical: true,
className: 'spacing-v-5',
children: conversions.map(BidirectionalConversion),
})
});
}
@@ -1,57 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
const { Box, Button, Icon, Label, Revealer } = Widget;
export default ({
icon,
name,
child,
revealChild = true,
}) => {
const headerButtonIcon = MaterialIcon(revealChild ? 'expand_less' : 'expand_more', 'norm');
const header = Button({
onClicked: () => {
content.revealChild = !content.revealChild;
headerButtonIcon.label = content.revealChild ? 'expand_less' : 'expand_more';
},
setup: setupCursorHover,
child: Box({
className: 'txt spacing-h-10',
children: [
icon,
Label({
className: 'txt-norm',
label: `${name}`,
useMarkup: true,
}),
Box({
hexpand: true,
}),
Box({
className: 'sidebar-module-btn-arrow',
homogeneous: true,
children: [headerButtonIcon],
})
]
})
});
const content = Revealer({
revealChild: revealChild,
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
className: 'margin-top-5',
homogeneous: true,
children: [child],
}),
});
return Box({
className: 'sidebar-module',
vertical: true,
children: [
header,
content,
]
});
}
@@ -1,26 +0,0 @@
const { Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
const { execAsync, exec } = Utils;
const { Box, Button, CenterBox, EventBox, Icon, Label, Scrollable } = Widget;
export default () => Box({
className: 'txt sidebar-module techfont',
children: [
Label({
label: getString('illogical-impulse')
}),
Box({ hexpand: true }),
Button({
className: 'sidebar-module-btn-arrow',
onClicked: () => execAsync(['xdg-open', 'https://github.com/end-4/dots-hyprland']).catch(print),
child: Icon({
className: 'txt txt-norm',
icon: 'github-symbolic',
}),
setup: setupCursorHover,
})
]
})
@@ -1,103 +0,0 @@
const { Gtk } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
const { Box, Button, EventBox, Icon, Label, Scrollable } = Widget;
import SidebarModule from './module.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { distroID, isArchDistro, isDebianDistro, hasFlatpak } from '../../.miscutils/system.js';
const scripts = [
{
icon: 'desktop-symbolic',
name: getString('Change screen resolution'),
command: `bash ${App.configDir}/modules/sideleft/tools/changeres.sh`,
enabled: true,
},
{
icon: 'nixos-symbolic',
name: getString('Trim system generations to 5'),
command: `sudo ${App.configDir}/scripts/quickscripts/nixos-trim-generations.sh 5 0 system`,
enabled: distroID == 'nixos',
},
{
icon: 'nixos-symbolic',
name: getString('Trim home manager generations to 5'),
command: `${App.configDir}/scripts/quickscripts/nixos-trim-generations.sh 5 0 home-manager`,
enabled: distroID == 'nixos',
},
{
icon: 'ubuntu-symbolic',
name: getString('Update packages'),
command: `sudo apt update && sudo apt upgrade -y`,
enabled: isDebianDistro,
},
{
icon: 'fedora-symbolic',
name: getString('Update packages'),
command: `sudo dnf upgrade -y`,
enabled: distroID == 'fedora',
},
{
icon: 'arch-symbolic',
name: getString('Update packages'),
command: `sudo pacman -Syyu`,
enabled: isArchDistro,
},
{
icon: 'arch-symbolic',
name: getString('Remove orphan packages'),
command: `sudo pacman -R (pacman -Qdtq)`,
enabled: isArchDistro,
},
{
icon: 'flatpak-symbolic',
name: getString('Uninstall unused flatpak packages'),
command: `flatpak uninstall --unused`,
enabled: hasFlatpak,
},
];
export default () => SidebarModule({
icon: MaterialIcon('code', 'norm'),
name: getString('Quick scripts'),
child: Box({
vertical: true,
className: 'spacing-v-5',
children: scripts.map((script) => {
if (!script.enabled) return null;
const scriptStateIcon = MaterialIcon('not_started', 'norm');
return Box({
className: 'spacing-h-5 txt',
children: [
Icon({
className: 'sidebar-module-btn-icon txt-large',
icon: script.icon,
}),
Label({
className: 'txt-small',
hpack: 'start',
hexpand: true,
label: script.name,
tooltipText: script.command,
}),
Button({
className: 'sidebar-module-scripts-button',
child: scriptStateIcon,
onClicked: () => {
closeEverything();
execAsync([`bash`, `-c`, `${userOptions.apps.terminal} fish -C "${script.command}"`]).catch(print)
.then(() => {
scriptStateIcon.label = 'done';
})
},
setup: setupCursorHover,
}),
],
})
}),
})
});
-273
View File
@@ -1,273 +0,0 @@
import GLib from 'gi://GLib';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Button, Label, Overlay } = Widget;
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import Todo from "../../services/todo.js";
import { TodoWidget } from "./todolist.js";
import { getCalendarLayout } from "./calendar_layout.js";
const AGS_CONFIG_FILE = `${App.configDir}/user_options.jsonc`;
let calendarJson = getCalendarLayout(undefined, true);
let monthshift = 0;
function getDateInXMonthsTime(x) {
var currentDate = new Date(); // Get the current date
var targetMonth = currentDate.getMonth() + x; // Calculate the target month
var targetYear = currentDate.getFullYear(); // Get the current year
// Adjust the year and month if necessary
targetYear += Math.floor(targetMonth / 12);
targetMonth = (targetMonth % 12 + 12) % 12;
// Create a new date object with the target year and month
var targetDate = new Date(targetYear, targetMonth, 1);
// Set the day to the last day of the month to get the desired date
// targetDate.setDate(0);
return targetDate;
}
const weekDays = [ // MONDAY IS THE FIRST DAY OF THE WEEK :HESRIGHTYOUKNOW:
{ day: getString('Mo'), today: 0 },
{ day: getString('Tu'), today: 0 },
{ day: getString('We'), today: 0 },
{ day: getString('Th'), today: 0 },
{ day: getString('Fr'), today: 0 },
{ day: getString('Sa'), today: 0 },
{ day: getString('Su'), today: 0 },
]
const CalendarDay = (day, today) => Widget.Button({
className: `sidebar-calendar-btn ${today == 1 ? 'sidebar-calendar-btn-today' : (today == -1 ? 'sidebar-calendar-btn-othermonth' : '')}`,
child: Widget.Overlay({
child: Box({}),
overlays: [Label({
hpack: 'center',
className: 'txt-smallie txt-semibold sidebar-calendar-btn-txt',
label: String(day),
})],
})
})
const CalendarWidget = () => {
const calendarMonthYear = Widget.Button({
className: 'txt txt-large sidebar-calendar-monthyear-btn',
onClicked: () => shiftCalendarXMonths(0),
setup: (button) => {
button.label = `${new Date().toLocaleString('default', { month: 'long' })} ${new Date().getFullYear()}`;
setupCursorHover(button);
}
});
const addCalendarChildren = (box, calendarJson) => {
const children = box.get_children();
for (let i = 0; i < children.length; i++) {
const child = children[i];
child.destroy();
}
box.children = calendarJson.map((row, i) => Widget.Box({
className: 'spacing-h-5',
children: row.map((day, i) => CalendarDay(day.day, day.today)),
}))
}
function shiftCalendarXMonths(x) {
if (x == 0) monthshift = 0;
else monthshift += x;
var newDate;
if (monthshift == 0) newDate = new Date();
else newDate = getDateInXMonthsTime(monthshift);
calendarJson = getCalendarLayout(newDate, (monthshift == 0));
calendarMonthYear.label = `${monthshift == 0 ? '' : '• '}${newDate.toLocaleString('default', { month: 'long' })} ${newDate.getFullYear()}`;
addCalendarChildren(calendarDays, calendarJson);
}
const calendarHeader = Widget.Box({
className: 'spacing-h-5 sidebar-calendar-header',
setup: (box) => {
box.pack_start(calendarMonthYear, false, false, 0);
box.pack_end(Widget.Box({
className: 'spacing-h-5',
children: [
Button({
className: 'sidebar-calendar-monthshift-btn',
onClicked: () => shiftCalendarXMonths(-1),
child: MaterialIcon('chevron_left', 'norm'),
setup: setupCursorHover,
}),
Button({
className: 'sidebar-calendar-monthshift-btn',
onClicked: () => shiftCalendarXMonths(1),
child: MaterialIcon('chevron_right', 'norm'),
setup: setupCursorHover,
})
]
}), false, false, 0);
}
})
const calendarDays = Widget.Box({
hexpand: true,
vertical: true,
className: 'spacing-v-5',
setup: (box) => {
addCalendarChildren(box, calendarJson);
}
});
return Widget.EventBox({
onScrollUp: () => shiftCalendarXMonths(-1),
onScrollDown: () => shiftCalendarXMonths(1),
child: Widget.Box({
hpack: 'center',
children: [
Widget.Box({
hexpand: true,
vertical: true,
className: 'spacing-v-5',
children: [
calendarHeader,
Widget.Box({
homogeneous: true,
className: 'spacing-h-5',
children: weekDays.map((day, i) => CalendarDay(day.day, day.today))
}),
calendarDays,
]
})
]
})
});
};
export const ModuleCalendar = () => {
const defaultShown = 'calendar';
const navrailButton = (stackItemName, icon, name) => Widget.Button({
className: 'button-minsize sidebar-navrail-btn txt-small spacing-h-5',
onClicked: (button) => {
contentStack.shown = stackItemName;
const kids = button.get_parent().get_children();
for (let i = 0; i < kids.length; i++) {
if (kids[i] != button) kids[i].toggleClassName('sidebar-navrail-btn-active', false);
else button.toggleClassName('sidebar-navrail-btn-active', true);
}
},
child: Box({
className: 'spacing-v-5',
vertical: true,
children: [
Label({
className: `txt icon-material txt-hugeass`,
label: icon,
}),
Label({
label: name,
className: 'txt txt-smallie',
}),
]
}),
setup: (button) => Utils.timeout(1, () => {
setupCursorHover(button);
button.toggleClassName('sidebar-navrail-btn-active', defaultShown === stackItemName);
})
});
const navrail = Box({
vpack: 'center',
homogeneous: true,
vertical: true,
className: 'sidebar-navrail spacing-v-10',
children: [
navrailButton('calendar', 'calendar_month', getString('Calendar')),
navrailButton('todo', 'done_outline', getString('To Do')),
]
});
const contentStack = Widget.Stack({
hexpand: true,
children: {
'calendar': CalendarWidget(),
'todo': TodoWidget(),
},
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
setup: (stack) => Utils.timeout(1, () => {
stack.shown = defaultShown;
})
})
const CollapseButtonIcon = (collapse) => MaterialIcon(collapse ? 'expand_more' : 'expand_less', 'norm');
const CollapseButton = (collapse) => {
const collapseButtonIcon = CollapseButtonIcon(collapse);
return Button({
hpack: 'start',
vpack: 'start',
className: 'margin-top-5 margin-left-5 margin-bottom-5',
onClicked: () => {
mainStack.shown = (mainStack.shown == 'expanded') ? 'collapsed' : 'expanded';
Utils.execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key "sidebar.calendar.expandByDefault" \
--value ${!userOptions.sidebar.calendar.expandByDefault} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
},
setup: setupCursorHover,
child: Box({
className: 'sidebar-calendar-btn-arrow txt',
homogeneous: true,
children: [collapseButtonIcon],
}),
tooltipText: collapse ? getString('Collapse calendar') : getString('Expand calendar'),
})
}
const date = Variable('', {
poll: [
userOptions.time.interval,
() => GLib.DateTime.new_now_local().format(userOptions.time.calendarDateFormat),
],
})
const collapsedWidget = Box({
className: 'spacing-h-5',
children: [
CollapseButton(false),
Widget.Label({
vpack: 'center',
className: 'txt txt-small sidebar-calendar-collapsed-pill',
label: date.bind(),
}),
Widget.Label({
vpack: 'center',
className: 'txt txt-small sidebar-calendar-collapsed-pill',
label: `${Todo.todo_json.length} ${getString('To do tasks')}`,
setup: (self) => self.hook(Todo, (self) => {
self.label = `${Todo.todo_json.length} ${getString('To do tasks')}`
}, 'updated')
}),
]
})
const mainStack = Widget.Stack({
className: 'sidebar-group',
homogeneous: false,
children: {
'collapsed': collapsedWidget,
'expanded': Box({
className: 'spacing-h-5',
children: [
Overlay({
child: navrail,
overlays: [CollapseButton(true)],
}),
contentStack
]
}),
},
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
shown: userOptions.sidebar.calendar.expandByDefault ? 'expanded' : 'collapsed',
})
return mainStack;
}
@@ -1,222 +0,0 @@
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Button, Icon, Label, Revealer, Scrollable, Slider, Stack } = Widget;
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
import { iconExists, substitute } from '../../.miscutils/icons.js';
const AppVolume = (stream) => Box({
className: 'sidebar-volmixer-stream spacing-h-10',
children: [
Icon({
className: 'sidebar-volmixer-stream-appicon',
vpack: 'center',
tooltipText: stream.stream.name,
setup: (self) => {
self.hook(stream, (self) => {
self.icon = substitute(
stream["icon-name"] ||
stream.stream["icon-name"] ||
stream.stream["application-id"] ||
stream.stream["name"]);
})
},
}),
Box({
hexpand: true,
vpack: 'center',
vertical: true,
className: 'spacing-v-5',
children: [
Label({
xalign: 0,
maxWidthChars: 1,
truncate: 'end',
label: stream.description,
className: 'txt-small',
setup: (self) => self.hook(stream, (self) => {
self.label = `${stream.stream.name}${stream.description}`
})
}),
Slider({
drawValue: false,
hpack: 'fill',
className: 'sidebar-volmixer-stream-slider',
value: stream.volume,
min: 0, max: 1,
onChange: ({ value }) => {
stream.volume = value;
},
setup: (self) => self.hook(stream, (self) => {
self.value = stream.volume;
self.adjustment["step-increment"] = 0.1;
})
}),
// Box({
// homogeneous: true,
// className: 'test',
// children: [AnimatedSlider({
// className: 'sidebar-volmixer-stream-slider',
// value: stream.volume,
// })],
// })
]
})
]
});
const AudioDevices = (input = false) => {
const dropdownShown = Variable(false);
const DeviceStream = (stream) => Button({
tooltipText: stream.description,
child: Box({
className: 'txt spacing-h-10',
children: [
iconExists(stream.iconName) ? Icon({
className: 'txt-norm symbolic-icon',
icon: stream.iconName,
}) : MaterialIcon(input ? 'mic_external_on' : 'media_output', 'norm'),
Label({
hexpand: true,
xalign: 0,
className: 'txt-small',
truncate: 'end',
maxWidthChars: 1,
label: stream.description,
}),
],
}),
onClicked: (self) => {
if (input) Audio.microphone = stream;
else Audio.speaker = stream;
dropdownShown.value = false;
},
setup: setupCursorHover,
})
const activeDevice = Button({
onClicked: () => { dropdownShown.value = !dropdownShown.value; },
child: Box({
className: 'txt spacing-h-10',
children: [
MaterialIcon(input ? 'mic_external_on' : 'media_output', 'norm'),
Label({
hexpand: true,
xalign: 0,
className: 'txt-small',
truncate: 'end',
maxWidthChars: 1,
label: `${input ? '[In]' : '[Out]'}`,
setup: (self) => self.hook(Audio, (self) => {
self.label = `${input ? '[In]' : '[Out]'} ${input ? Audio.microphone.description : Audio.speaker.description}`;
})
}),
Label({
className: `icon-material txt-norm`,
setup: (self) => self.hook(dropdownShown, (self) => {
self.label = dropdownShown.value ? 'expand_less' : 'expand_more';
})
})
],
}),
setup: setupCursorHover,
});
const deviceSelector = Revealer({
transition: 'slide_down',
revealChild: dropdownShown.bind("value"),
transitionDuration: userOptions.animations.durationSmall,
child: Box({
vertical: true,
children: [
Box({ className: 'separator-line margin-top-5 margin-bottom-5' }),
Box({
vertical: true,
className: 'spacing-v-5 margin-top-5',
attribute: {
'updateStreams': (self) => {
const streams = input ? Audio.microphones : Audio.speakers;
self.children = streams.map(stream => DeviceStream(stream));
},
},
setup: (self) => self
.hook(Audio, self.attribute.updateStreams, 'stream-added')
.hook(Audio, self.attribute.updateStreams, 'stream-removed')
,
}),
]
})
})
return Box({
hpack: 'fill',
className: 'sidebar-volmixer-deviceselector',
vertical: true,
children: [
activeDevice,
deviceSelector,
]
})
}
export default (props) => {
const emptyContent = Box({
homogeneous: true,
children: [Box({
vertical: true,
vpack: 'center',
className: 'txt spacing-v-10',
children: [
Box({
vertical: true,
className: 'spacing-v-5 txt-subtext',
children: [
MaterialIcon('brand_awareness', 'gigantic'),
Label({ label: getString('No audio source'), className: 'txt-small' }),
]
}),
]
})]
});
const appList = Scrollable({
vexpand: true,
child: Box({
attribute: {
'updateStreams': (self) => {
const streams = Audio.apps;
self.children = streams.map(stream => AppVolume(stream));
},
},
vertical: true,
className: 'spacing-v-5',
setup: (self) => self
.hook(Audio, self.attribute.updateStreams, 'stream-added')
.hook(Audio, self.attribute.updateStreams, 'stream-removed')
,
})
})
const devices = Box({
vertical: true,
className: 'spacing-v-5',
children: [
AudioDevices(false),
AudioDevices(true),
]
})
const mainContent = Stack({
children: {
'empty': emptyContent,
'list': appList,
},
setup: (self) => self.hook(Audio, (self) => {
self.shown = (Audio.apps.length > 0 ? 'list' : 'empty')
}),
})
return Box({
...props,
className: 'spacing-v-5',
vertical: true,
children: [
mainContent,
devices,
]
});
}

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