From 22fa13cb191b8fc700fdfccfcc7ff149fdde4fd7 Mon Sep 17 00:00:00 2001 From: Itess Date: Sun, 27 Apr 2025 15:43:52 +0200 Subject: feat: add hyprpicker waybar module --- config/waybar/ModulesCustom | 7 +++++++ config/waybar/style/[0 VERTICAL] Golden Noir.css | 1 + config/waybar/style/[0 VERTICAL] Oglo Chicklets.css | 1 + config/waybar/style/[0 VERTICAL] [Catpuccin] Mocha.css | 1 + config/waybar/style/[Black & White] Monochrome.css | 1 + config/waybar/style/[Catppuccin] Frappe.css | 1 + config/waybar/style/[Catppuccin] Latte.css | 1 + config/waybar/style/[Catppuccin] Mocha.css | 1 + config/waybar/style/[Colored] Chroma Glow.css | 1 + config/waybar/style/[Colored] Translucent.css | 1 + config/waybar/style/[Colorful] Aurora Blossom.css | 1 + config/waybar/style/[Colorful] Aurora.css | 1 + config/waybar/style/[Colorful] Oglo Chicklets.css | 1 + config/waybar/style/[Colorful] Rainbow Spectrum.css | 1 + config/waybar/style/[Dark] Golden Eclipse.css | 1 + config/waybar/style/[Dark] Golden Noir.css | 1 + config/waybar/style/[Dark] Latte-Wallust combined v2.css | 1 + config/waybar/style/[Dark] Latte-Wallust combined.css | 1 + config/waybar/style/[Dark] Purpl.css | 1 + config/waybar/style/[Dark] Wallust Obsidian Edge.css | 1 + config/waybar/style/[Extra] Arrow.css | 1 + config/waybar/style/[Extra] Crimson.css | 1 + config/waybar/style/[Extra] EverForest.css | 1 + config/waybar/style/[Extra] ML4W starter.css | 1 + config/waybar/style/[Extra] Mauve.css | 1 + config/waybar/style/[Extra] Modern-Combined - Transparent.css | 1 + config/waybar/style/[Extra] Neon Circuit.css | 1 + config/waybar/style/[Extra] Prismatic Glow.css | 1 + config/waybar/style/[Extra] Rose Pine.css | 1 + config/waybar/style/[Extra] Simple Pink.css | 1 + config/waybar/style/[Light] Monochrome Contrast.css | 1 + config/waybar/style/[Light] Obsidian Glow.css | 1 + config/waybar/style/[Rainbow] RGB Bordered.css | 1 + config/waybar/style/[Retro] Simple Style.css | 1 + config/waybar/style/[Transparent] Crystal Clear.css | 1 + config/waybar/style/[VERTICAL] [Catpuccin] Mocha.css | 1 + config/waybar/style/[WALLUST] ML4W-modern-mixed.css | 1 + config/waybar/style/[WALLUST] ML4W-modern.css | 1 + config/waybar/style/[Wallust Bordered] Chroma Fusion Edge.css | 1 + config/waybar/style/[Wallust Bordered] Chroma Simple.css | 1 + config/waybar/style/[Wallust Transparent] Crystal Clear.css | 1 + config/waybar/style/[Wallust] Box type.css | 1 + config/waybar/style/[Wallust] Chroma Edge.css | 1 + config/waybar/style/[Wallust] Chroma Fusion.css | 1 + config/waybar/style/[Wallust] Chroma Tally V2.css | 1 + config/waybar/style/[Wallust] Chroma Tally.css | 1 + config/waybar/style/[Wallust] Colored.css | 1 + config/waybar/style/[Wallust] Simple.css | 1 + 48 files changed, 54 insertions(+) diff --git a/config/waybar/ModulesCustom b/config/waybar/ModulesCustom index bde9bbc2..c06cd7ac 100644 --- a/config/waybar/ModulesCustom +++ b/config/waybar/ModulesCustom @@ -17,6 +17,13 @@ "tooltip": true, }, +"custom/hyprpicker": { + "format": "", + "on-click": "hyprpicker | wl-copy", + "tooltip": true, + "tooltip-format": "Hyprpicker", +}, + "custom/file_manager": { "format": " ", "on-click": "xdg-open . &", diff --git a/config/waybar/style/[0 VERTICAL] Golden Noir.css b/config/waybar/style/[0 VERTICAL] Golden Noir.css index 8aa3ad74..c64fedf9 100644 --- a/config/waybar/style/[0 VERTICAL] Golden Noir.css +++ b/config/waybar/style/[0 VERTICAL] Golden Noir.css @@ -140,6 +140,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[0 VERTICAL] Oglo Chicklets.css b/config/waybar/style/[0 VERTICAL] Oglo Chicklets.css index 81ce148b..3a6084cb 100644 --- a/config/waybar/style/[0 VERTICAL] Oglo Chicklets.css +++ b/config/waybar/style/[0 VERTICAL] Oglo Chicklets.css @@ -102,6 +102,7 @@ button.active { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[0 VERTICAL] [Catpuccin] Mocha.css b/config/waybar/style/[0 VERTICAL] [Catpuccin] Mocha.css index 37b67a43..971dc40f 100644 --- a/config/waybar/style/[0 VERTICAL] [Catpuccin] Mocha.css +++ b/config/waybar/style/[0 VERTICAL] [Catpuccin] Mocha.css @@ -112,6 +112,7 @@ tooltip label { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Black & White] Monochrome.css b/config/waybar/style/[Black & White] Monochrome.css index 6106422a..700bebfc 100644 --- a/config/waybar/style/[Black & White] Monochrome.css +++ b/config/waybar/style/[Black & White] Monochrome.css @@ -149,6 +149,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Catppuccin] Frappe.css b/config/waybar/style/[Catppuccin] Frappe.css index c9a02d0f..82f79678 100644 --- a/config/waybar/style/[Catppuccin] Frappe.css +++ b/config/waybar/style/[Catppuccin] Frappe.css @@ -113,6 +113,7 @@ window#waybar.hidden { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Catppuccin] Latte.css b/config/waybar/style/[Catppuccin] Latte.css index b87c543f..80608e53 100644 --- a/config/waybar/style/[Catppuccin] Latte.css +++ b/config/waybar/style/[Catppuccin] Latte.css @@ -112,6 +112,7 @@ window#waybar.hidden { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Catppuccin] Mocha.css b/config/waybar/style/[Catppuccin] Mocha.css index 74892b69..67f4efa5 100644 --- a/config/waybar/style/[Catppuccin] Mocha.css +++ b/config/waybar/style/[Catppuccin] Mocha.css @@ -135,6 +135,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Colored] Chroma Glow.css b/config/waybar/style/[Colored] Chroma Glow.css index cc1b0de8..2497d69f 100644 --- a/config/waybar/style/[Colored] Chroma Glow.css +++ b/config/waybar/style/[Colored] Chroma Glow.css @@ -136,6 +136,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Colored] Translucent.css b/config/waybar/style/[Colored] Translucent.css index 0a69da90..50803ef7 100644 --- a/config/waybar/style/[Colored] Translucent.css +++ b/config/waybar/style/[Colored] Translucent.css @@ -137,6 +137,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Colorful] Aurora Blossom.css b/config/waybar/style/[Colorful] Aurora Blossom.css index 003dabbf..dbd405d2 100644 --- a/config/waybar/style/[Colorful] Aurora Blossom.css +++ b/config/waybar/style/[Colorful] Aurora Blossom.css @@ -128,6 +128,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Colorful] Aurora.css b/config/waybar/style/[Colorful] Aurora.css index debbc873..92c058c6 100644 --- a/config/waybar/style/[Colorful] Aurora.css +++ b/config/waybar/style/[Colorful] Aurora.css @@ -117,6 +117,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Colorful] Oglo Chicklets.css b/config/waybar/style/[Colorful] Oglo Chicklets.css index 98efcc2b..b5ac3584 100644 --- a/config/waybar/style/[Colorful] Oglo Chicklets.css +++ b/config/waybar/style/[Colorful] Oglo Chicklets.css @@ -102,6 +102,7 @@ button.active { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Colorful] Rainbow Spectrum.css b/config/waybar/style/[Colorful] Rainbow Spectrum.css index fd4e5cb5..6ca5906f 100644 --- a/config/waybar/style/[Colorful] Rainbow Spectrum.css +++ b/config/waybar/style/[Colorful] Rainbow Spectrum.css @@ -120,6 +120,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Dark] Golden Eclipse.css b/config/waybar/style/[Dark] Golden Eclipse.css index b2d1079f..af3160a6 100644 --- a/config/waybar/style/[Dark] Golden Eclipse.css +++ b/config/waybar/style/[Dark] Golden Eclipse.css @@ -75,6 +75,7 @@ window#waybar.hidden { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Dark] Golden Noir.css b/config/waybar/style/[Dark] Golden Noir.css index 9fe7b9c8..17025266 100644 --- a/config/waybar/style/[Dark] Golden Noir.css +++ b/config/waybar/style/[Dark] Golden Noir.css @@ -140,6 +140,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Dark] Latte-Wallust combined v2.css b/config/waybar/style/[Dark] Latte-Wallust combined v2.css index a937724c..46d55346 100644 --- a/config/waybar/style/[Dark] Latte-Wallust combined v2.css +++ b/config/waybar/style/[Dark] Latte-Wallust combined v2.css @@ -154,6 +154,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Dark] Latte-Wallust combined.css b/config/waybar/style/[Dark] Latte-Wallust combined.css index 51533e8e..ea5c08a5 100644 --- a/config/waybar/style/[Dark] Latte-Wallust combined.css +++ b/config/waybar/style/[Dark] Latte-Wallust combined.css @@ -159,6 +159,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Dark] Purpl.css b/config/waybar/style/[Dark] Purpl.css index c2ded5ff..5e2ff8aa 100644 --- a/config/waybar/style/[Dark] Purpl.css +++ b/config/waybar/style/[Dark] Purpl.css @@ -144,6 +144,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Dark] Wallust Obsidian Edge.css b/config/waybar/style/[Dark] Wallust Obsidian Edge.css index 22998299..94ad7cac 100644 --- a/config/waybar/style/[Dark] Wallust Obsidian Edge.css +++ b/config/waybar/style/[Dark] Wallust Obsidian Edge.css @@ -130,6 +130,7 @@ tooltip label { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Arrow.css b/config/waybar/style/[Extra] Arrow.css index 16aab612..9435d226 100644 --- a/config/waybar/style/[Extra] Arrow.css +++ b/config/waybar/style/[Extra] Arrow.css @@ -106,6 +106,7 @@ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Crimson.css b/config/waybar/style/[Extra] Crimson.css index a71f89e6..cf9e7db2 100644 --- a/config/waybar/style/[Extra] Crimson.css +++ b/config/waybar/style/[Extra] Crimson.css @@ -128,6 +128,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] EverForest.css b/config/waybar/style/[Extra] EverForest.css index ad2b51bc..f0014762 100644 --- a/config/waybar/style/[Extra] EverForest.css +++ b/config/waybar/style/[Extra] EverForest.css @@ -308,6 +308,7 @@ window#waybar.hidden { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] ML4W starter.css b/config/waybar/style/[Extra] ML4W starter.css index 79456a84..8d651da6 100644 --- a/config/waybar/style/[Extra] ML4W starter.css +++ b/config/waybar/style/[Extra] ML4W starter.css @@ -177,6 +177,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Mauve.css b/config/waybar/style/[Extra] Mauve.css index 816ed777..ec24bec7 100644 --- a/config/waybar/style/[Extra] Mauve.css +++ b/config/waybar/style/[Extra] Mauve.css @@ -147,6 +147,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Modern-Combined - Transparent.css b/config/waybar/style/[Extra] Modern-Combined - Transparent.css index f4184817..c4ff7197 100644 --- a/config/waybar/style/[Extra] Modern-Combined - Transparent.css +++ b/config/waybar/style/[Extra] Modern-Combined - Transparent.css @@ -161,6 +161,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Neon Circuit.css b/config/waybar/style/[Extra] Neon Circuit.css index 2415841a..7fbb39a5 100644 --- a/config/waybar/style/[Extra] Neon Circuit.css +++ b/config/waybar/style/[Extra] Neon Circuit.css @@ -125,6 +125,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Prismatic Glow.css b/config/waybar/style/[Extra] Prismatic Glow.css index cbcedfc6..8179352d 100644 --- a/config/waybar/style/[Extra] Prismatic Glow.css +++ b/config/waybar/style/[Extra] Prismatic Glow.css @@ -172,6 +172,7 @@ window#waybar.empty { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Rose Pine.css b/config/waybar/style/[Extra] Rose Pine.css index 1503355a..023b03a2 100644 --- a/config/waybar/style/[Extra] Rose Pine.css +++ b/config/waybar/style/[Extra] Rose Pine.css @@ -148,6 +148,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Extra] Simple Pink.css b/config/waybar/style/[Extra] Simple Pink.css index 84b2491f..db63a02f 100644 --- a/config/waybar/style/[Extra] Simple Pink.css +++ b/config/waybar/style/[Extra] Simple Pink.css @@ -140,6 +140,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Light] Monochrome Contrast.css b/config/waybar/style/[Light] Monochrome Contrast.css index 6e8a2e41..95b34fcc 100644 --- a/config/waybar/style/[Light] Monochrome Contrast.css +++ b/config/waybar/style/[Light] Monochrome Contrast.css @@ -129,6 +129,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Light] Obsidian Glow.css b/config/waybar/style/[Light] Obsidian Glow.css index da8bb502..692ce5d5 100644 --- a/config/waybar/style/[Light] Obsidian Glow.css +++ b/config/waybar/style/[Light] Obsidian Glow.css @@ -116,6 +116,7 @@ tooltip label { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Rainbow] RGB Bordered.css b/config/waybar/style/[Rainbow] RGB Bordered.css index e2df8c39..b38ae40d 100644 --- a/config/waybar/style/[Rainbow] RGB Bordered.css +++ b/config/waybar/style/[Rainbow] RGB Bordered.css @@ -136,6 +136,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Retro] Simple Style.css b/config/waybar/style/[Retro] Simple Style.css index fc50013c..8a601487 100644 --- a/config/waybar/style/[Retro] Simple Style.css +++ b/config/waybar/style/[Retro] Simple Style.css @@ -90,6 +90,7 @@ window#waybar { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Transparent] Crystal Clear.css b/config/waybar/style/[Transparent] Crystal Clear.css index b0cbaaf1..b355c176 100644 --- a/config/waybar/style/[Transparent] Crystal Clear.css +++ b/config/waybar/style/[Transparent] Crystal Clear.css @@ -111,6 +111,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[VERTICAL] [Catpuccin] Mocha.css b/config/waybar/style/[VERTICAL] [Catpuccin] Mocha.css index cd2d9165..d265506c 100644 --- a/config/waybar/style/[VERTICAL] [Catpuccin] Mocha.css +++ b/config/waybar/style/[VERTICAL] [Catpuccin] Mocha.css @@ -111,6 +111,7 @@ tooltip label { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[WALLUST] ML4W-modern-mixed.css b/config/waybar/style/[WALLUST] ML4W-modern-mixed.css index 5df79cb6..f1b64745 100644 --- a/config/waybar/style/[WALLUST] ML4W-modern-mixed.css +++ b/config/waybar/style/[WALLUST] ML4W-modern-mixed.css @@ -161,6 +161,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[WALLUST] ML4W-modern.css b/config/waybar/style/[WALLUST] ML4W-modern.css index b2a97488..048f972b 100644 --- a/config/waybar/style/[WALLUST] ML4W-modern.css +++ b/config/waybar/style/[WALLUST] ML4W-modern.css @@ -168,6 +168,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust Bordered] Chroma Fusion Edge.css b/config/waybar/style/[Wallust Bordered] Chroma Fusion Edge.css index e3224529..812dbf6f 100644 --- a/config/waybar/style/[Wallust Bordered] Chroma Fusion Edge.css +++ b/config/waybar/style/[Wallust Bordered] Chroma Fusion Edge.css @@ -100,6 +100,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust Bordered] Chroma Simple.css b/config/waybar/style/[Wallust Bordered] Chroma Simple.css index 63d66b26..3bf56789 100644 --- a/config/waybar/style/[Wallust Bordered] Chroma Simple.css +++ b/config/waybar/style/[Wallust Bordered] Chroma Simple.css @@ -125,6 +125,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust Transparent] Crystal Clear.css b/config/waybar/style/[Wallust Transparent] Crystal Clear.css index 54c7f2f3..cddee7e7 100644 --- a/config/waybar/style/[Wallust Transparent] Crystal Clear.css +++ b/config/waybar/style/[Wallust Transparent] Crystal Clear.css @@ -144,6 +144,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Box type.css b/config/waybar/style/[Wallust] Box type.css index 7c53ef92..84c85cf6 100644 --- a/config/waybar/style/[Wallust] Box type.css +++ b/config/waybar/style/[Wallust] Box type.css @@ -125,6 +125,7 @@ window#waybar.empty #window { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Chroma Edge.css b/config/waybar/style/[Wallust] Chroma Edge.css index 0cbaa6c0..3530c3af 100644 --- a/config/waybar/style/[Wallust] Chroma Edge.css +++ b/config/waybar/style/[Wallust] Chroma Edge.css @@ -128,6 +128,7 @@ tooltip label{ #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Chroma Fusion.css b/config/waybar/style/[Wallust] Chroma Fusion.css index 079c266a..d740c78f 100644 --- a/config/waybar/style/[Wallust] Chroma Fusion.css +++ b/config/waybar/style/[Wallust] Chroma Fusion.css @@ -101,6 +101,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Chroma Tally V2.css b/config/waybar/style/[Wallust] Chroma Tally V2.css index 8251d950..8082331b 100644 --- a/config/waybar/style/[Wallust] Chroma Tally V2.css +++ b/config/waybar/style/[Wallust] Chroma Tally V2.css @@ -113,6 +113,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Chroma Tally.css b/config/waybar/style/[Wallust] Chroma Tally.css index c9938eb3..a6fd1ee9 100644 --- a/config/waybar/style/[Wallust] Chroma Tally.css +++ b/config/waybar/style/[Wallust] Chroma Tally.css @@ -112,6 +112,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Colored.css b/config/waybar/style/[Wallust] Colored.css index 381417dd..435f3651 100644 --- a/config/waybar/style/[Wallust] Colored.css +++ b/config/waybar/style/[Wallust] Colored.css @@ -153,6 +153,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, diff --git a/config/waybar/style/[Wallust] Simple.css b/config/waybar/style/[Wallust] Simple.css index 0990a80c..c2206c10 100644 --- a/config/waybar/style/[Wallust] Simple.css +++ b/config/waybar/style/[Wallust] Simple.css @@ -132,6 +132,7 @@ tooltip { #custom-swaync, #custom-tty, #custom-updater, +#custom-hyprpicker, #custom-weather, #custom-weather.clearNight, #custom-weather.cloudyFoggyDay, -- cgit v1.2.3 From 6594a935a8c0c4b3bc90e6d5f5d74829c06c53f7 Mon Sep 17 00:00:00 2001 From: aditya-an1l Date: Thu, 22 May 2025 11:08:00 +0530 Subject: feat: Add Power Info (level and status) in Hyprlock Window - Display current power level (battery percentage) and power status (full, charging, discharging) at the bottom right section of Hyprlock - This feature allows laptop user to view the power info when their device are locked, especially if the device is getting discharged. --- config/hypr/hyprlock.conf | 12 ++++++++++++ config/hypr/scripts/Power.sh | 9 +++++++++ 2 files changed, 21 insertions(+) create mode 100644 config/hypr/scripts/Power.sh diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index a0d075cb..5222138a 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -156,6 +156,18 @@ label { valign = bottom } +# battery +label { + monitor = + text = cmd[update:1000] echo " "$($Scripts/Power.sh)" " + color = $color13 + font_size = 18 + font_family = Victor Mono Bold Oblique + position = 0, 30 + halign = right + valign = bottom +} + # weather edit the scripts for locations # weather scripts are located in ~/.config/hypr/UserScripts Weather.sh and/or Weather.py # see https://github.com/JaKooLit/Hyprland-Dots/wiki/TIPS#%EF%B8%8F-weather-app-related-for-waybar-and-hyprlock diff --git a/config/hypr/scripts/Power.sh b/config/hypr/scripts/Power.sh new file mode 100644 index 00000000..42431ea9 --- /dev/null +++ b/config/hypr/scripts/Power.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +for i in {0..3}; do + if [ -f /sys/class/power_supply/BAT$i/capacity ]; then + battery_level=$(cat /sys/class/power_supply/BAT$i/status) + battery_capacity=$(cat /sys/class/power_supply/BAT$i/capacity) + echo "Power: $battery_capacity% ($battery_level)" + fi +done -- cgit v1.2.3 From 4478adb2b0c65fab3c43621d1bf76f14fd6aaae2 Mon Sep 17 00:00:00 2001 From: JaKooLit Date: Sun, 25 May 2025 21:40:41 +0900 Subject: updated version for development --- config/hypr/v2.3.15 | 5 ----- config/hypr/v2.3.16 | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 config/hypr/v2.3.15 create mode 100644 config/hypr/v2.3.16 diff --git a/config/hypr/v2.3.15 b/config/hypr/v2.3.15 deleted file mode 100644 index 31b3414d..00000000 --- a/config/hypr/v2.3.15 +++ /dev/null @@ -1,5 +0,0 @@ -### https://github.com/JaKooLit ### -## https://github.com/JaKooLit/Hyprland-Dots -## This is to have a reference of which version would be - -## note that this will always be higher than the released versions \ No newline at end of file diff --git a/config/hypr/v2.3.16 b/config/hypr/v2.3.16 new file mode 100644 index 00000000..31b3414d --- /dev/null +++ b/config/hypr/v2.3.16 @@ -0,0 +1,5 @@ +### https://github.com/JaKooLit ### +## https://github.com/JaKooLit/Hyprland-Dots +## This is to have a reference of which version would be + +## note that this will always be higher than the released versions \ No newline at end of file -- cgit v1.2.3 From 2c33cef6fdee97ac9a13f0f4bf49158aa48c9f03 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sun, 25 May 2025 20:02:03 +0530 Subject: Improved Dropdown terminal --- config/hypr/UserConfigs/UserKeybinds.conf | 2 +- config/hypr/scripts/Dropterminal.sh | 65 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100755 config/hypr/scripts/Dropterminal.sh diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index 871f2ffb..ce501d85 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -39,7 +39,7 @@ bind = $mainMod SHIFT, F, fullscreen # whole full screen bind = $mainMod CTRL, F, fullscreen, 1 # fake full screen bind = $mainMod, SPACE, togglefloating, #Float Mode bind = $mainMod ALT, SPACE, exec, hyprctl dispatch workspaceopt allfloat #All Float Mode -bind = $mainMod SHIFT, Return, exec, [float; move 15% 5%; size 70% 60%] $term # Dropdown terminal +bind = $mainMod SHIFT, Return, exec, $scriptsDir/Dropterminal.sh $term # Dropdown terminal # Desktop zooming or magnifier bind = $mainMod ALT, mouse_down, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor * 2.0}')" diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh new file mode 100755 index 00000000..a160c3e9 --- /dev/null +++ b/config/hypr/scripts/Dropterminal.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ ## +# Dropdown Terminal Usage: ./dropdown.sh [foot|kitty] + +TERMINAL="$1" +SPECIAL_WS="special:scratchpad" + +# Validate input and set CLASS and CMD +case "$TERMINAL" in + foot) + CLASS="foot-dropterminal" + TERMINAL_CMD="foot --app-id $CLASS" + ;; + kitty) + CLASS="kitty-dropterminal" + TERMINAL_CMD="kitty --class $CLASS" + ;; + *) + echo "Invalid or missing terminal argument. Usage: $0 [foot|kitty]" + exit 1 + ;; +esac + +# Get the current workspace +CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') + +# Function to check if terminal exists +terminal_exists() { + hyprctl clients -j | jq -e --arg CLASS "$CLASS" 'any(.[]; .class == $CLASS)' >/dev/null 2>&1 +} + +# Function to check if terminal is in special workspace +terminal_in_special() { + hyprctl clients -j | jq -e --arg CLASS "$CLASS" 'any(.[]; .class == $CLASS and .workspace.name == "special:scratchpad")' >/dev/null 2>&1 +} + +# Function to get terminal address +get_terminal_address() { + hyprctl clients -j | jq -r --arg CLASS "$CLASS" '.[] | select(.class == $CLASS) | .address' +} + +if terminal_exists; then + TERMINAL_ADDR=$(get_terminal_address) + + if terminal_in_special; then + echo "Bringing terminal to workspace $CURRENT_WS and pinning" + hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$TERMINAL_ADDR" + hyprctl dispatch pin "address:$TERMINAL_ADDR" + hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" + else + echo "Unpinning and hiding terminal to special workspace" + hyprctl dispatch pin "address:$TERMINAL_ADDR" # Unpin (toggle) + sleep 0.1 + hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" + fi +else + echo "Creating new dropdown terminal with command: $TERMINAL_CMD" + hyprctl dispatch exec "[float; move 25% 5%; size 50% 50%] $TERMINAL_CMD" + sleep 0.5 + if terminal_exists; then + TERMINAL_ADDR=$(get_terminal_address) + hyprctl dispatch pin "address:$TERMINAL_ADDR" + hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" + fi +fi -- cgit v1.2.3 From c6c06f0448413454b9ea58af7526c55c360b0e97 Mon Sep 17 00:00:00 2001 From: JaKooLit Date: Tue, 27 May 2025 03:58:55 +0900 Subject: updated Power.sh, renamed to Battery.sh since it is about battery information --- config/hypr/hyprlock-1080p.conf | 12 ++++++++++++ config/hypr/hyprlock.conf | 4 ++-- config/hypr/scripts/Battery.sh | 9 +++++++++ config/hypr/scripts/Power.sh | 9 --------- 4 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 config/hypr/scripts/Battery.sh delete mode 100644 config/hypr/scripts/Power.sh diff --git a/config/hypr/hyprlock-1080p.conf b/config/hypr/hyprlock-1080p.conf index a0e105e0..70c00c16 100644 --- a/config/hypr/hyprlock-1080p.conf +++ b/config/hypr/hyprlock-1080p.conf @@ -156,6 +156,18 @@ label { valign = bottom } +# battery information +label { + monitor = + text = cmd[update:1000] echo " "$($Scripts/Battery.sh)" " + color = $color13 + font_size = 16 + font_family = Victor Mono Bold Oblique + position = 0, 50 + halign = right + valign = bottom +} + # weather edit the scripts for locations # weather scripts are located in ~/.config/hypr/UserScripts Weather.sh and/or Weather.py # see https://github.com/JaKooLit/Hyprland-Dots/wiki/TIPS#%EF%B8%8F-weather-app-related-for-waybar-and-hyprlock diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index 80a94fb1..b67bba51 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -157,10 +157,10 @@ label { valign = bottom } -# battery +# battery information label { monitor = - text = cmd[update:1000] echo " "$($Scripts/Power.sh)" " + text = cmd[update:1000] echo " "$($Scripts/Battery.sh)" " color = $color13 font_size = 18 font_family = Victor Mono Bold Oblique diff --git a/config/hypr/scripts/Battery.sh b/config/hypr/scripts/Battery.sh new file mode 100644 index 00000000..d7830058 --- /dev/null +++ b/config/hypr/scripts/Battery.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +for i in {0..3}; do + if [ -f /sys/class/power_supply/BAT$i/capacity ]; then + battery_level=$(cat /sys/class/power_supply/BAT$i/status) + battery_capacity=$(cat /sys/class/power_supply/BAT$i/capacity) + echo "Battery: $battery_capacity% ($battery_level)" + fi +done diff --git a/config/hypr/scripts/Power.sh b/config/hypr/scripts/Power.sh deleted file mode 100644 index 42431ea9..00000000 --- a/config/hypr/scripts/Power.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -for i in {0..3}; do - if [ -f /sys/class/power_supply/BAT$i/capacity ]; then - battery_level=$(cat /sys/class/power_supply/BAT$i/status) - battery_capacity=$(cat /sys/class/power_supply/BAT$i/capacity) - echo "Power: $battery_capacity% ($battery_level)" - fi -done -- cgit v1.2.3 From 78a46392e550170b47fc62cc189fcd0d5ac7e5c2 Mon Sep 17 00:00:00 2001 From: JaKooLit Date: Tue, 27 May 2025 04:03:56 +0900 Subject: updated hyprlock 1080p --- config/hypr/hyprlock-1080p.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/hyprlock-1080p.conf b/config/hypr/hyprlock-1080p.conf index 70c00c16..14f2f35e 100644 --- a/config/hypr/hyprlock-1080p.conf +++ b/config/hypr/hyprlock-1080p.conf @@ -163,7 +163,7 @@ label { color = $color13 font_size = 16 font_family = Victor Mono Bold Oblique - position = 0, 50 + position = 0, 30 halign = right valign = bottom } -- cgit v1.2.3 From 84466963633538013e84c74c2d8b2ce33e06c504 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Tue, 27 May 2025 10:11:45 +0530 Subject: Updated dropdown terminal script to use addressed based window tracking instead of class --- config/hypr/scripts/Dropterminal.sh | 140 ++++++++++++++++++++++++++++-------- 1 file changed, 109 insertions(+), 31 deletions(-) diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index a160c3e9..98420a24 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -1,65 +1,143 @@ #!/bin/bash # /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ ## -# Dropdown Terminal Usage: ./dropdown.sh [foot|kitty] +# Dropdown Terminal +# Usage: ./dropdown.sh [-d] +# Example: ./dropdown.sh foot +# ./dropdown.sh -d foot (with debug output) +# ./dropdown.sh "kitty -e zsh" +# ./dropdown.sh "alacritty --working-directory /home/user" -TERMINAL="$1" +DEBUG=false SPECIAL_WS="special:scratchpad" +ADDR_FILE="/tmp/dropdown_terminal_addr" -# Validate input and set CLASS and CMD -case "$TERMINAL" in - foot) - CLASS="foot-dropterminal" - TERMINAL_CMD="foot --app-id $CLASS" - ;; - kitty) - CLASS="kitty-dropterminal" - TERMINAL_CMD="kitty --class $CLASS" - ;; - *) - echo "Invalid or missing terminal argument. Usage: $0 [foot|kitty]" - exit 1 - ;; -esac +# Parse arguments +if [ "$1" = "-d" ]; then + DEBUG=true + shift +fi + +TERMINAL_CMD="$1" + +# Debug echo function +debug_echo() { + if [ "$DEBUG" = true ]; then + echo "$@" + fi +} + +# Validate input +if [ -z "$TERMINAL_CMD" ]; then + echo "Missing terminal command. Usage: $0 [-d] " + echo "Examples:" + echo " $0 foot" + echo " $0 -d foot (with debug output)" + echo " $0 'kitty -e zsh'" + echo " $0 'alacritty --working-directory /home/user'" + exit 1 +fi # Get the current workspace CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') +# Function to get stored terminal address +get_terminal_address() { + if [ -f "$ADDR_FILE" ] && [ -s "$ADDR_FILE" ]; then + cat "$ADDR_FILE" + fi +} + # Function to check if terminal exists terminal_exists() { - hyprctl clients -j | jq -e --arg CLASS "$CLASS" 'any(.[]; .class == $CLASS)' >/dev/null 2>&1 + local addr=$(get_terminal_address) + if [ -n "$addr" ]; then + hyprctl clients -j | jq -e --arg ADDR "$addr" 'any(.[]; .address == $ADDR)' >/dev/null 2>&1 + else + return 1 + fi } # Function to check if terminal is in special workspace terminal_in_special() { - hyprctl clients -j | jq -e --arg CLASS "$CLASS" 'any(.[]; .class == $CLASS and .workspace.name == "special:scratchpad")' >/dev/null 2>&1 + local addr=$(get_terminal_address) + if [ -n "$addr" ]; then + hyprctl clients -j | jq -e --arg ADDR "$addr" 'any(.[]; .address == $ADDR and .workspace.name == "special:scratchpad")' >/dev/null 2>&1 + else + return 1 + fi } -# Function to get terminal address -get_terminal_address() { - hyprctl clients -j | jq -r --arg CLASS "$CLASS" '.[] | select(.class == $CLASS) | .address' +# Function to spawn terminal and capture its address +spawn_terminal() { + debug_echo "Creating new dropdown terminal with command: $TERMINAL_CMD" + + # Get window count and list before spawning + local windows_before=$(hyprctl clients -j) + local count_before=$(echo "$windows_before" | jq 'length') + + # Launch terminal with rules applied from the start + hyprctl dispatch exec "[float; move 25% 5%; size 50% 50%; pin] $TERMINAL_CMD" + + # Wait for window to appear + sleep 1 + + # Get windows after spawning + local windows_after=$(hyprctl clients -j) + local count_after=$(echo "$windows_after" | jq 'length') + + if [ "$count_after" -gt "$count_before" ]; then + # Find the new window by comparing before/after lists + local new_addr=$(comm -13 \ + <(echo "$windows_before" | jq -r '.[].address' | sort) \ + <(echo "$windows_after" | jq -r '.[].address' | sort) \ + | head -1) + + if [ -n "$new_addr" ] && [ "$new_addr" != "null" ]; then + # Store the address + echo "$new_addr" > "$ADDR_FILE" + debug_echo "Terminal created with address: $new_addr" + return 0 + fi + fi + + # Fallback: try to find by the most recently mapped window + local new_addr=$(hyprctl clients -j | jq -r 'sort_by(.focusHistoryID) | .[-1] | .address') + + if [ -n "$new_addr" ] && [ "$new_addr" != "null" ]; then + echo "$new_addr" > "$ADDR_FILE" + debug_echo "Terminal created with address: $new_addr (fallback method)" + return 0 + fi + + debug_echo "Failed to get terminal address" + return 1 } +# Main logic if terminal_exists; then TERMINAL_ADDR=$(get_terminal_address) + debug_echo "Found existing terminal: $TERMINAL_ADDR" if terminal_in_special; then - echo "Bringing terminal to workspace $CURRENT_WS and pinning" + debug_echo "Bringing terminal to workspace $CURRENT_WS and pinning" hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$TERMINAL_ADDR" hyprctl dispatch pin "address:$TERMINAL_ADDR" hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" else - echo "Unpinning and hiding terminal to special workspace" + debug_echo "Unpinning and hiding terminal to special workspace" hyprctl dispatch pin "address:$TERMINAL_ADDR" # Unpin (toggle) sleep 0.1 hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" fi else - echo "Creating new dropdown terminal with command: $TERMINAL_CMD" - hyprctl dispatch exec "[float; move 25% 5%; size 50% 50%] $TERMINAL_CMD" - sleep 0.5 - if terminal_exists; then + debug_echo "No existing terminal found, creating new one" + if spawn_terminal; then TERMINAL_ADDR=$(get_terminal_address) - hyprctl dispatch pin "address:$TERMINAL_ADDR" - hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" + if [ -n "$TERMINAL_ADDR" ]; then + hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" + fi + else + echo "Failed to create terminal" + exit 1 fi -fi +fi \ No newline at end of file -- cgit v1.2.3 From c0943736e57b52d883c45d43d21adfb3067099b0 Mon Sep 17 00:00:00 2001 From: Humblemonk Date: Tue, 27 May 2025 00:48:38 -0400 Subject: Remove trailing whitespace from WindowRules.conf Noticed a trailing whitespace in the latest WindowRules.conf. --- config/hypr/UserConfigs/WindowRules.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/hypr/UserConfigs/WindowRules.conf b/config/hypr/UserConfigs/WindowRules.conf index 661b3a17..099cd2c8 100644 --- a/config/hypr/UserConfigs/WindowRules.conf +++ b/config/hypr/UserConfigs/WindowRules.conf @@ -44,7 +44,7 @@ windowrule = tag +screenshare, class:^(com.obsproject.Studio)$ windowrule = tag +im, class:^([Dd]iscord|[Ww]ebCord|[Vv]esktop)$ windowrule = tag +im, class:^([Ff]erdium)$ windowrule = tag +im, class:^([Ww]hatsapp-for-linux)$ -windowrule = tag +im, class:^(ZapZap|com.rtosta.zapzap)$ +windowrule = tag +im, class:^(ZapZap|com.rtosta.zapzap)$ windowrule = tag +im, class:^(org.telegram.desktop|io.github.tdesktop_x64.TDesktop)$ windowrule = tag +im, class:^(teams-for-linux)$ @@ -219,4 +219,4 @@ layerrule = ignorezero, notifications #layerrule = ignorezero, #layerrule = ignorezero, overview -#layerrule = blur, overview \ No newline at end of file +#layerrule = blur, overview -- cgit v1.2.3 From b56edcff4d48d215ad26e1c64729a8ea7c311f22 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Tue, 27 May 2025 21:45:24 +0530 Subject: Added animation similar to pyprland --- config/hypr/scripts/Dropterminal.sh | 196 ++++++++++++++++++++++++++++++------ 1 file changed, 168 insertions(+), 28 deletions(-) diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index 98420a24..51cdf31f 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -1,16 +1,21 @@ #!/bin/bash # /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ ## # Dropdown Terminal -# Usage: ./dropdown.sh [-d] -# Example: ./dropdown.sh foot -# ./dropdown.sh -d foot (with debug output) -# ./dropdown.sh "kitty -e zsh" -# ./dropdown.sh "alacritty --working-directory /home/user" +# Usage: ./Dropdown.sh [-d] +# Example: ./Dropdown.sh foot +# ./Dropdown.sh -d foot (with debug output) +# ./Dropdown.sh "kitty -e zsh" +# ./Dropdown.sh "alacritty --working-directory /home/user" DEBUG=false SPECIAL_WS="special:scratchpad" ADDR_FILE="/tmp/dropdown_terminal_addr" +# Animation settings +ANIMATION_DURATION=100 # milliseconds +SLIDE_STEPS=10 +SLIDE_DELAY=5 # milliseconds between steps + # Parse arguments if [ "$1" = "-d" ]; then DEBUG=true @@ -37,6 +42,91 @@ if [ -z "$TERMINAL_CMD" ]; then exit 1 fi +# Function to get window geometry +get_window_geometry() { + local addr="$1" + hyprctl clients -j | jq -r --arg ADDR "$addr" '.[] | select(.address == $ADDR) | "\(.at[0]) \(.at[1]) \(.size[0]) \(.size[1])"' +} + +# Function to animate window slide down (show) +animate_slide_down() { + local addr="$1" + local target_x="$2" + local target_y="$3" + local width="$4" + local height="$5" + + debug_echo "Animating slide down for window $addr to position $target_x,$target_y" + + # Start position (above screen) + local start_y=$((target_y - height - 50)) + + # Calculate step size + local step_y=$(((target_y - start_y) / SLIDE_STEPS)) + + # Move window to start position instantly (off-screen) + hyprctl dispatch movewindowpixel "exact $target_x $start_y,address:$addr" >/dev/null 2>&1 + sleep 0.05 + + # Animate slide down + for i in $(seq 1 $SLIDE_STEPS); do + local current_y=$((start_y + (step_y * i))) + hyprctl dispatch movewindowpixel "exact $target_x $current_y,address:$addr" >/dev/null 2>&1 + sleep 0.03 + done + + # Ensure final position is exact + hyprctl dispatch movewindowpixel "exact $target_x $target_y,address:$addr" >/dev/null 2>&1 +} + +# Function to animate window slide up (hide) +animate_slide_up() { + local addr="$1" + local start_x="$2" + local start_y="$3" + local width="$4" + local height="$5" + + debug_echo "Animating slide up for window $addr from position $start_x,$start_y" + + # End position (above screen) + local end_y=$((start_y - height - 50)) + + # Calculate step size + local step_y=$(((start_y - end_y) / SLIDE_STEPS)) + + # Animate slide up + for i in $(seq 1 $SLIDE_STEPS); do + local current_y=$((start_y - (step_y * i))) + hyprctl dispatch movewindowpixel "exact $start_x $current_y,address:$addr" >/dev/null 2>&1 + sleep 0.03 + done + + debug_echo "Slide up animation completed" +} + +# Function to get monitor info for centering +get_monitor_info() { + hyprctl monitors -j | jq -r '.[0] | "\(.x) \(.y) \(.width) \(.height)"' +} + +# Function to calculate dropdown position +calculate_dropdown_position() { + local monitor_info=$(get_monitor_info) + local mon_x=$(echo $monitor_info | cut -d' ' -f1) + local mon_y=$(echo $monitor_info | cut -d' ' -f2) + local mon_width=$(echo $monitor_info | cut -d' ' -f3) + local mon_height=$(echo $monitor_info | cut -d' ' -f4) + + # Calculate 50% width, 50% height, centered horizontally, 5% from top + local width=$((mon_width / 2)) + local height=$((mon_height / 2)) + local x=$((mon_x + (mon_width - width) / 2)) + local y=$((mon_y + mon_height / 20)) # 5% from top + + echo "$x $y $width $height" +} + # Get the current workspace CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') @@ -71,41 +161,57 @@ terminal_in_special() { spawn_terminal() { debug_echo "Creating new dropdown terminal with command: $TERMINAL_CMD" - # Get window count and list before spawning - local windows_before=$(hyprctl clients -j) - local count_before=$(echo "$windows_before" | jq 'length') + # Calculate dropdown position for later use + pos_info=$(calculate_dropdown_position) + target_x=$(echo $pos_info | cut -d' ' -f1) + target_y=$(echo $pos_info | cut -d' ' -f2) + width=$(echo $pos_info | cut -d' ' -f3) + height=$(echo $pos_info | cut -d' ' -f4) + + debug_echo "Target position: ${target_x}x${target_y}, size: ${width}x${height}" - # Launch terminal with rules applied from the start - hyprctl dispatch exec "[float; move 25% 5%; size 50% 50%; pin] $TERMINAL_CMD" + # Get window count before spawning + windows_before=$(hyprctl clients -j) + count_before=$(echo "$windows_before" | jq 'length') + + # Launch terminal directly in special workspace to avoid visible spawn + hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" # Wait for window to appear - sleep 1 + sleep 0.1 # Get windows after spawning - local windows_after=$(hyprctl clients -j) - local count_after=$(echo "$windows_after" | jq 'length') + windows_after=$(hyprctl clients -j) + count_after=$(echo "$windows_after" | jq 'length') + + new_addr="" if [ "$count_after" -gt "$count_before" ]; then # Find the new window by comparing before/after lists - local new_addr=$(comm -13 \ + new_addr=$(comm -13 \ <(echo "$windows_before" | jq -r '.[].address' | sort) \ <(echo "$windows_after" | jq -r '.[].address' | sort) \ | head -1) - - if [ -n "$new_addr" ] && [ "$new_addr" != "null" ]; then - # Store the address - echo "$new_addr" > "$ADDR_FILE" - debug_echo "Terminal created with address: $new_addr" - return 0 - fi fi # Fallback: try to find by the most recently mapped window - local new_addr=$(hyprctl clients -j | jq -r 'sort_by(.focusHistoryID) | .[-1] | .address') + if [ -z "$new_addr" ] || [ "$new_addr" = "null" ]; then + new_addr=$(hyprctl clients -j | jq -r 'sort_by(.focusHistoryID) | .[-1] | .address') + fi if [ -n "$new_addr" ] && [ "$new_addr" != "null" ]; then + # Store the address echo "$new_addr" > "$ADDR_FILE" - debug_echo "Terminal created with address: $new_addr (fallback method)" + debug_echo "Terminal created with address: $new_addr in special workspace" + + # Small delay to ensure it's properly in special workspace + sleep 0.2 + + # Now bring it back with the same animation as subsequent shows + hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$new_addr" + hyprctl dispatch pin "address:$new_addr" + animate_slide_down "$new_addr" "$target_x" "$target_y" "$width" "$height" + return 0 fi @@ -119,15 +225,49 @@ if terminal_exists; then debug_echo "Found existing terminal: $TERMINAL_ADDR" if terminal_in_special; then - debug_echo "Bringing terminal to workspace $CURRENT_WS and pinning" + debug_echo "Bringing terminal from scratchpad with slide down animation" + + # Calculate target position + pos_info=$(calculate_dropdown_position) + target_x=$(echo $pos_info | cut -d' ' -f1) + target_y=$(echo $pos_info | cut -d' ' -f2) + width=$(echo $pos_info | cut -d' ' -f3) + height=$(echo $pos_info | cut -d' ' -f4) + + # Move to current workspace and pin hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$TERMINAL_ADDR" hyprctl dispatch pin "address:$TERMINAL_ADDR" + + # Set size and animate slide down + hyprctl dispatch resizewindowpixel "exact $width $height,address:$TERMINAL_ADDR" + animate_slide_down "$TERMINAL_ADDR" "$target_x" "$target_y" "$width" "$height" + hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" else - debug_echo "Unpinning and hiding terminal to special workspace" - hyprctl dispatch pin "address:$TERMINAL_ADDR" # Unpin (toggle) - sleep 0.1 - hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" + debug_echo "Hiding terminal to scratchpad with slide up animation" + + # Get current geometry for animation + geometry=$(get_window_geometry "$TERMINAL_ADDR") + if [ -n "$geometry" ]; then + curr_x=$(echo $geometry | cut -d' ' -f1) + curr_y=$(echo $geometry | cut -d' ' -f2) + curr_width=$(echo $geometry | cut -d' ' -f3) + curr_height=$(echo $geometry | cut -d' ' -f4) + + debug_echo "Current geometry: ${curr_x},${curr_y} ${curr_width}x${curr_height}" + + # Animate slide up first + animate_slide_up "$TERMINAL_ADDR" "$curr_x" "$curr_y" "$curr_width" "$curr_height" + + # Small delay then move to special workspace and unpin + sleep 0.1 + hyprctl dispatch pin "address:$TERMINAL_ADDR" # Unpin (toggle) + hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" + else + debug_echo "Could not get window geometry, moving to scratchpad without animation" + hyprctl dispatch pin "address:$TERMINAL_ADDR" + hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" + fi fi else debug_echo "No existing terminal found, creating new one" -- cgit v1.2.3 From d8aee89ba261d17597deff3fe00a7907adf240e2 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sat, 31 May 2025 08:18:33 +0530 Subject: Dropdown terminal improvements - Round 2 --- config/hypr/scripts/Dropterminal.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index 51cdf31f..a8e1cda3 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -11,9 +11,15 @@ DEBUG=false SPECIAL_WS="special:scratchpad" ADDR_FILE="/tmp/dropdown_terminal_addr" +# Dropdown size and position configuration (percentages) +WIDTH_PERCENT=50 # Width as percentage of screen width +HEIGHT_PERCENT=50 # Height as percentage of screen height +X_PERCENT=25 # X position as percentage from left (25% centers a 50% width window) +Y_PERCENT=5 # Y position as percentage from top + # Animation settings ANIMATION_DURATION=100 # milliseconds -SLIDE_STEPS=10 +SLIDE_STEPS=5 SLIDE_DELAY=5 # milliseconds between steps # Parse arguments @@ -39,6 +45,12 @@ if [ -z "$TERMINAL_CMD" ]; then echo " $0 -d foot (with debug output)" echo " $0 'kitty -e zsh'" echo " $0 'alacritty --working-directory /home/user'" + echo "" + echo "Edit the script to modify size and position:" + echo " WIDTH_PERCENT - Width as percentage of screen (default: 50)" + echo " HEIGHT_PERCENT - Height as percentage of screen (default: 50)" + echo " X_PERCENT - X position from left as percentage (default: 25)" + echo " Y_PERCENT - Y position from top as percentage (default: 5)" exit 1 fi @@ -118,11 +130,11 @@ calculate_dropdown_position() { local mon_width=$(echo $monitor_info | cut -d' ' -f3) local mon_height=$(echo $monitor_info | cut -d' ' -f4) - # Calculate 50% width, 50% height, centered horizontally, 5% from top - local width=$((mon_width / 2)) - local height=$((mon_height / 2)) - local x=$((mon_x + (mon_width - width) / 2)) - local y=$((mon_y + mon_height / 20)) # 5% from top + # Calculate position and size based on percentages + local width=$((mon_width * WIDTH_PERCENT / 100)) + local height=$((mon_height * HEIGHT_PERCENT / 100)) + local x=$((mon_x + (mon_width * X_PERCENT / 100))) + local y=$((mon_y + (mon_height * Y_PERCENT / 100))) echo "$x $y $width $height" } @@ -175,7 +187,7 @@ spawn_terminal() { count_before=$(echo "$windows_before" | jq 'length') # Launch terminal directly in special workspace to avoid visible spawn - hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" + hyprctl dispatch exec "[float; size $width $height; stayfocused; workspace special:scratchpad silent] $TERMINAL_CMD" # Wait for window to appear sleep 0.1 @@ -208,7 +220,8 @@ spawn_terminal() { sleep 0.2 # Now bring it back with the same animation as subsequent shows - hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$new_addr" + # Use movetoworkspacesilent to avoid affecting workspace history + hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$new_addr" hyprctl dispatch pin "address:$new_addr" animate_slide_down "$new_addr" "$target_x" "$target_y" "$width" "$height" @@ -234,8 +247,8 @@ if terminal_exists; then width=$(echo $pos_info | cut -d' ' -f3) height=$(echo $pos_info | cut -d' ' -f4) - # Move to current workspace and pin - hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$TERMINAL_ADDR" + # Use movetoworkspacesilent to avoid affecting workspace history + hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$TERMINAL_ADDR" hyprctl dispatch pin "address:$TERMINAL_ADDR" # Set size and animate slide down @@ -276,8 +289,5 @@ else if [ -n "$TERMINAL_ADDR" ]; then hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" fi - else - echo "Failed to create terminal" - exit 1 fi fi \ No newline at end of file -- cgit v1.2.3 From 713f9498329cd15457abe3d65b07ae9481510a22 Mon Sep 17 00:00:00 2001 From: "Ja.KooLit" <85185940+JaKooLit@users.noreply.github.com> Date: Sat, 31 May 2025 20:28:08 +0000 Subject: Revert "Dropdown terminal improvements - Round 2" --- config/hypr/scripts/Dropterminal.sh | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index a8e1cda3..51cdf31f 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -11,15 +11,9 @@ DEBUG=false SPECIAL_WS="special:scratchpad" ADDR_FILE="/tmp/dropdown_terminal_addr" -# Dropdown size and position configuration (percentages) -WIDTH_PERCENT=50 # Width as percentage of screen width -HEIGHT_PERCENT=50 # Height as percentage of screen height -X_PERCENT=25 # X position as percentage from left (25% centers a 50% width window) -Y_PERCENT=5 # Y position as percentage from top - # Animation settings ANIMATION_DURATION=100 # milliseconds -SLIDE_STEPS=5 +SLIDE_STEPS=10 SLIDE_DELAY=5 # milliseconds between steps # Parse arguments @@ -45,12 +39,6 @@ if [ -z "$TERMINAL_CMD" ]; then echo " $0 -d foot (with debug output)" echo " $0 'kitty -e zsh'" echo " $0 'alacritty --working-directory /home/user'" - echo "" - echo "Edit the script to modify size and position:" - echo " WIDTH_PERCENT - Width as percentage of screen (default: 50)" - echo " HEIGHT_PERCENT - Height as percentage of screen (default: 50)" - echo " X_PERCENT - X position from left as percentage (default: 25)" - echo " Y_PERCENT - Y position from top as percentage (default: 5)" exit 1 fi @@ -130,11 +118,11 @@ calculate_dropdown_position() { local mon_width=$(echo $monitor_info | cut -d' ' -f3) local mon_height=$(echo $monitor_info | cut -d' ' -f4) - # Calculate position and size based on percentages - local width=$((mon_width * WIDTH_PERCENT / 100)) - local height=$((mon_height * HEIGHT_PERCENT / 100)) - local x=$((mon_x + (mon_width * X_PERCENT / 100))) - local y=$((mon_y + (mon_height * Y_PERCENT / 100))) + # Calculate 50% width, 50% height, centered horizontally, 5% from top + local width=$((mon_width / 2)) + local height=$((mon_height / 2)) + local x=$((mon_x + (mon_width - width) / 2)) + local y=$((mon_y + mon_height / 20)) # 5% from top echo "$x $y $width $height" } @@ -187,7 +175,7 @@ spawn_terminal() { count_before=$(echo "$windows_before" | jq 'length') # Launch terminal directly in special workspace to avoid visible spawn - hyprctl dispatch exec "[float; size $width $height; stayfocused; workspace special:scratchpad silent] $TERMINAL_CMD" + hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" # Wait for window to appear sleep 0.1 @@ -220,8 +208,7 @@ spawn_terminal() { sleep 0.2 # Now bring it back with the same animation as subsequent shows - # Use movetoworkspacesilent to avoid affecting workspace history - hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$new_addr" + hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$new_addr" hyprctl dispatch pin "address:$new_addr" animate_slide_down "$new_addr" "$target_x" "$target_y" "$width" "$height" @@ -247,8 +234,8 @@ if terminal_exists; then width=$(echo $pos_info | cut -d' ' -f3) height=$(echo $pos_info | cut -d' ' -f4) - # Use movetoworkspacesilent to avoid affecting workspace history - hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$TERMINAL_ADDR" + # Move to current workspace and pin + hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$TERMINAL_ADDR" hyprctl dispatch pin "address:$TERMINAL_ADDR" # Set size and animate slide down @@ -289,5 +276,8 @@ else if [ -n "$TERMINAL_ADDR" ]; then hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" fi + else + echo "Failed to create terminal" + exit 1 fi fi \ No newline at end of file -- cgit v1.2.3 From 4564b38d1b84888f153802cc5b4e9c32de4aa8a3 Mon Sep 17 00:00:00 2001 From: "Ja.KooLit" <85185940+JaKooLit@users.noreply.github.com> Date: Sat, 31 May 2025 20:37:06 +0000 Subject: Revert "Revert "Dropdown terminal improvements - Round 2"" --- config/hypr/scripts/Dropterminal.sh | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index 51cdf31f..a8e1cda3 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -11,9 +11,15 @@ DEBUG=false SPECIAL_WS="special:scratchpad" ADDR_FILE="/tmp/dropdown_terminal_addr" +# Dropdown size and position configuration (percentages) +WIDTH_PERCENT=50 # Width as percentage of screen width +HEIGHT_PERCENT=50 # Height as percentage of screen height +X_PERCENT=25 # X position as percentage from left (25% centers a 50% width window) +Y_PERCENT=5 # Y position as percentage from top + # Animation settings ANIMATION_DURATION=100 # milliseconds -SLIDE_STEPS=10 +SLIDE_STEPS=5 SLIDE_DELAY=5 # milliseconds between steps # Parse arguments @@ -39,6 +45,12 @@ if [ -z "$TERMINAL_CMD" ]; then echo " $0 -d foot (with debug output)" echo " $0 'kitty -e zsh'" echo " $0 'alacritty --working-directory /home/user'" + echo "" + echo "Edit the script to modify size and position:" + echo " WIDTH_PERCENT - Width as percentage of screen (default: 50)" + echo " HEIGHT_PERCENT - Height as percentage of screen (default: 50)" + echo " X_PERCENT - X position from left as percentage (default: 25)" + echo " Y_PERCENT - Y position from top as percentage (default: 5)" exit 1 fi @@ -118,11 +130,11 @@ calculate_dropdown_position() { local mon_width=$(echo $monitor_info | cut -d' ' -f3) local mon_height=$(echo $monitor_info | cut -d' ' -f4) - # Calculate 50% width, 50% height, centered horizontally, 5% from top - local width=$((mon_width / 2)) - local height=$((mon_height / 2)) - local x=$((mon_x + (mon_width - width) / 2)) - local y=$((mon_y + mon_height / 20)) # 5% from top + # Calculate position and size based on percentages + local width=$((mon_width * WIDTH_PERCENT / 100)) + local height=$((mon_height * HEIGHT_PERCENT / 100)) + local x=$((mon_x + (mon_width * X_PERCENT / 100))) + local y=$((mon_y + (mon_height * Y_PERCENT / 100))) echo "$x $y $width $height" } @@ -175,7 +187,7 @@ spawn_terminal() { count_before=$(echo "$windows_before" | jq 'length') # Launch terminal directly in special workspace to avoid visible spawn - hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" + hyprctl dispatch exec "[float; size $width $height; stayfocused; workspace special:scratchpad silent] $TERMINAL_CMD" # Wait for window to appear sleep 0.1 @@ -208,7 +220,8 @@ spawn_terminal() { sleep 0.2 # Now bring it back with the same animation as subsequent shows - hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$new_addr" + # Use movetoworkspacesilent to avoid affecting workspace history + hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$new_addr" hyprctl dispatch pin "address:$new_addr" animate_slide_down "$new_addr" "$target_x" "$target_y" "$width" "$height" @@ -234,8 +247,8 @@ if terminal_exists; then width=$(echo $pos_info | cut -d' ' -f3) height=$(echo $pos_info | cut -d' ' -f4) - # Move to current workspace and pin - hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$TERMINAL_ADDR" + # Use movetoworkspacesilent to avoid affecting workspace history + hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$TERMINAL_ADDR" hyprctl dispatch pin "address:$TERMINAL_ADDR" # Set size and animate slide down @@ -276,8 +289,5 @@ else if [ -n "$TERMINAL_ADDR" ]; then hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" fi - else - echo "Failed to create terminal" - exit 1 fi fi \ No newline at end of file -- cgit v1.2.3 From e9c7d8a3882b1166c0ed99e4501e465937089b05 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sun, 1 Jun 2025 08:45:47 +0530 Subject: Fixed drop down terminal focus --- config/hypr/scripts/Dropterminal.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index a8e1cda3..fa5b899b 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -187,7 +187,7 @@ spawn_terminal() { count_before=$(echo "$windows_before" | jq 'length') # Launch terminal directly in special workspace to avoid visible spawn - hyprctl dispatch exec "[float; size $width $height; stayfocused; workspace special:scratchpad silent] $TERMINAL_CMD" + hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" # Wait for window to appear sleep 0.1 -- cgit v1.2.3 From 30ed636ba6c51b417cccb5acde1fbb8221b55b84 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sun, 1 Jun 2025 08:48:40 +0530 Subject: SwayNC DND bypass for volume and brightness notification --- config/hypr/scripts/Brightness.sh | 2 +- config/hypr/scripts/BrightnessKbd.sh | 2 +- config/hypr/scripts/Volume.sh | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/config/hypr/scripts/Brightness.sh b/config/hypr/scripts/Brightness.sh index 8e5d525a..bf28fc8c 100755 --- a/config/hypr/scripts/Brightness.sh +++ b/config/hypr/scripts/Brightness.sh @@ -29,7 +29,7 @@ get_icon() { # Notify notify_user() { - notify-send -e -h string:x-canonical-private-synchronous:brightness_notif -h int:value:$current -u low -i $icon "Screen" "Brightness:$current%" + notify-send -e -h string:x-canonical-private-synchronous:brightness_notif -h int:value:$current -h boolean:SWAYNC_BYPASS_DND:true -u low -i $icon "Screen" "Brightness:$current%" } # Change brightness diff --git a/config/hypr/scripts/BrightnessKbd.sh b/config/hypr/scripts/BrightnessKbd.sh index 4c56bc03..24737b73 100755 --- a/config/hypr/scripts/BrightnessKbd.sh +++ b/config/hypr/scripts/BrightnessKbd.sh @@ -26,7 +26,7 @@ get_icon() { } # Notify notify_user() { - notify-send -e -h string:x-canonical-private-synchronous:brightness_notif -h int:value:$current -u low -i "$icon" "Keyboard" "Brightness:$current%" + notify-send -e -h string:x-canonical-private-synchronous:brightness_notif -h int:value:$current -h boolean:SWAYNC_BYPASS_DND:true -u low -i "$icon" "Keyboard" "Brightness:$current%" } # Change brightness diff --git a/config/hypr/scripts/Volume.sh b/config/hypr/scripts/Volume.sh index b205f8f9..8efdb55c 100755 --- a/config/hypr/scripts/Volume.sh +++ b/config/hypr/scripts/Volume.sh @@ -32,9 +32,9 @@ get_icon() { # Notify notify_user() { if [[ "$(get_volume)" == "Muted" ]]; then - notify-send -e -h string:x-canonical-private-synchronous:volume_notif -u low -i "$(get_icon)" " Volume:" " Muted" + notify-send -e -h string:x-canonical-private-synchronous:volume_notif -h boolean:SWAYNC_BYPASS_DND:true -u low -i "$(get_icon)" " Volume:" " Muted" else - notify-send -e -h int:value:"$(get_volume | sed 's/%//')" -h string:x-canonical-private-synchronous:volume_notif -u low -i "$(get_icon)" " Volume Level:" " $(get_volume)" && + notify-send -e -h int:value:"$(get_volume | sed 's/%//')" -h string:x-canonical-private-synchronous:volume_notif -h boolean:SWAYNC_BYPASS_DND:true -u low -i "$(get_icon)" " Volume Level:" " $(get_volume)" && "$sDIR/Sounds.sh" --volume fi } @@ -60,18 +60,18 @@ dec_volume() { # Toggle Mute toggle_mute() { if [ "$(pamixer --get-mute)" == "false" ]; then - pamixer -m && notify-send -e -u low -i "$iDIR/volume-mute.png" " Mute" + pamixer -m && notify-send -e -u low -h boolean:SWAYNC_BYPASS_DND:true -i "$iDIR/volume-mute.png" " Mute" elif [ "$(pamixer --get-mute)" == "true" ]; then - pamixer -u && notify-send -e -u low -i "$(get_icon)" " Volume:" " Switched ON" + pamixer -u && notify-send -e -u low -h boolean:SWAYNC_BYPASS_DND:true -i "$(get_icon)" " Volume:" " Switched ON" fi } # Toggle Mic toggle_mic() { if [ "$(pamixer --default-source --get-mute)" == "false" ]; then - pamixer --default-source -m && notify-send -e -u low -i "$iDIR/microphone-mute.png" " Microphone:" " Switched OFF" + pamixer --default-source -m && notify-send -e -u low -h boolean:SWAYNC_BYPASS_DND:true -i "$iDIR/microphone-mute.png" " Microphone:" " Switched OFF" elif [ "$(pamixer --default-source --get-mute)" == "true" ]; then - pamixer -u --default-source u && notify-send -e -u low -i "$iDIR/microphone.png" " Microphone:" " Switched ON" + pamixer -u --default-source u && notify-send -e -u low -h boolean:SWAYNC_BYPASS_DND:true -i "$iDIR/microphone.png" " Microphone:" " Switched ON" fi } # Get Mic Icon @@ -98,7 +98,7 @@ get_mic_volume() { notify_mic_user() { volume=$(get_mic_volume) icon=$(get_mic_icon) - notify-send -e -h int:value:"$volume" -h "string:x-canonical-private-synchronous:volume_notif" -u low -i "$icon" " Mic Level:" " $volume" + notify-send -e -h int:value:"$volume" -h "string:x-canonical-private-synchronous:volume_notif" -h boolean:SWAYNC_BYPASS_DND:true -u low -i "$icon" " Mic Level:" " $volume" } # Increase MIC Volume -- cgit v1.2.3 From 7ac48640209a5c3792504ea1986560551c0ff2cf Mon Sep 17 00:00:00 2001 From: CristianSw <60692725+CristianSw@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:15:17 +0300 Subject: Added Romanian translation for Readme file --- README.md | 182 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 84 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 6ad87ded..e576b41b 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,12 @@
@@ -29,7 +29,7 @@

Sparkles - KooL's Hyprland Dotfiles Showcase + Prezentarea fișierelor Dotfiles Hyprland ale lui KooL Sparkles

@@ -39,173 +39,159 @@ https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 -### 📹 A video walkthroughs -- at the bottom +### 📹 Ghiduri video +- la finalul paginii -### 🎞️ AGS Overview DEMO -- in case you wonder, here is a short demo of AGS overview [Youtube LINK](https://youtu.be/zY5SLNPBJTs) +### 🎞️ Demo AGS Overview +- în caz că te întrebi, aici este un demo scurt al AGS overview [Link YouTube](https://youtu.be/zY5SLNPBJTs) --- -[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALLATION)](https://git.io/typing-svg) -### 🚩 🏁 Auto Distro-Hyprland install scripts cloning and starting 🇵🇭 -> [!CAUTION] -> If you are using FISH SHELL, DO NOT use this function. Clone the Distro-Hyprland and ran install.sh instead +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALARE)](https://git.io/typing-svg) +### 🚩 🏁 Scripturi automate de instalare Hyprland pentru distribuții, clonare și pornire 🇵🇭 +> [!ATENȚIE] +> Dacă folosești FISH SHELL, NU utiliza această funcție. Clonează Distro-Hyprland și rulează install.sh în schimb. -- NOTE: you need package `curl` for this to work +- NOTĂ: ai nevoie de pachetul `curl` pentru ca aceasta să funcționeze ```bash sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) ``` -- you can now use above command to automatically clone the Distro-Hyprland install scripts below -- it will clone the install scripts and start the `install.sh` 😎 +- acum poți folosi comanda de mai sus pentru a clona automat scripturile de instalare Distro-Hyprland de mai jos +- va clona scripturile de instalare și va porni `install.sh` 😎 - -### 👁️‍🗨️ My Hyprland install Scripts 👁️‍🗨️ -- Automated Hyprland Scripts for Distro of choice which will pull this dotfiles if opted to install these configurations +### 👁️‍🗨️ Scripturile mele de instalare Hyprland 👁️‍🗨️ +- Scripturi automate Hyprland pentru distribuția aleasă, care vor descărca aceste dotfiles dacă optezi pentru instalarea acestor configurații - [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) - - [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) - - [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) - - [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) - - [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) - - [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) - [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) -- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) +- [Ubuntu 25.04 - (FAZĂ ALPHA)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + --- -### 🪧 Attention 🪧 -- This repo does NOT contain or will NOT install any packages. These are only pre-configured-hyprland configs or dotfiles -- refer to install scripts what packages needed to install... but atleast, Hyprland packages is needed 😏😏😏 duh!! -- This repo will be pulled by the Distro-Hyprland install scripts above if you opt to download pre-configured dots +### 🪧 Atenție 🪧 +- Acest repo NU conține și NU va instala niciun pachet. Acestea sunt doar configurații Hyprland pre-configurate sau dotfiles +- consultă scripturile de instalare pentru a vedea ce pachete trebuie instalate... dar cel puțin, pachetele Hyprland sunt necesare 😏😏😏 evident!! +- Acest repo va fi descărcat de scripturile de instalare Distro-Hyprland de mai sus dacă optezi pentru descărcarea dotfiles-urilor pre-configurate -### 👀 Screenshots 👀 -- All screenshots are collected here [Screenshots](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) +### 👀 Capturi de ecran 👀 +- Toate capturile de ecran sunt colectate aici [Capturi de ecran](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) -### 📦 Whats new? -- To easily track changes, I will be updating the [CHANGELOGS](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) Screenshots will be included if worth mentioning the changes! +### 📦 Ce mai e nou? +- Pentru a urmări ușor modificările, voi actualiza [Jurnalul de modificări](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Capturile de ecran vor fi incluse dacă modificările merită menționate! -> [!NOTE] -> Kindly note that by defeault, Kools Dots are adjusted / configured for 2k (1440p) display without scaling. +> [!NOTĂ] +> Reține că, în mod implicit, dotfiles-urile lui Kool sunt ajustate/configurate pentru afișaje 2k (1440p) fără scalare. -### 💥 Copying / Installation / Update instructions 💥 -- [`MORE INFO HERE`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) -> [!Note] -> The auto copy script "copy.sh" will create backups of intended directories to be copied. However, still a good idea to manually backup just incase script failed to backup! -- clone this repo by using git. Change directory, make executable and run the script +### 💥 Instrucțiuni de copiere / instalare / actualizare 💥 +- [`MAI MULTE INFORMAȚII AICI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +> [!Notă] +> Scriptul automat de copiere „copy.sh” va crea copii de rezervă ale directoarelor care urmează să fie copiate. Totuși, este o idee bună să faci manual o copie de rezervă, în caz că scriptul nu reușește să o facă! -> to download from Master branch +- clonează acest repo folosind git. Schimbă directorul, fă scriptul executabil și rulează-l + +> pentru a descărca din ramura Master ```bash git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git cd Hyprland-Dots ``` -> to download from Development branch (development and testing) +> pentru a descărca din ramura Development (dezvoltare și testare) ```bash git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development cd Hyprland-Dots ``` -- automatic copy/install of pre-configured dots (recommended for updating) +- copiere/instalare automată a dotfiles-urilor pre-configurate (recomandat pentru actualizări) ```bash chmod +x copy.sh ./copy.sh ``` -- to copy/install from releases (stable) (note this is 1 version older than in main) +- pentru a copia/instala din versiuni (stabile) (notă: aceasta este cu o versiune mai veche decât cea din ramura principală) ```bash chmod +x release.sh ./release.sh ``` -- UPGRADE.sh function +- Funcția UPGRADE.sh > [!IMPORTANT] -> You need rsync for it to work -> you should have already up and running KooL's Hyprland before using this function +> Ai nevoie de rsync pentru ca aceasta să funcționeze +> trebuie să ai deja configurat și funcțional Hyprland-ul lui KooL înainte de a folosi această funcție ```bash chmod +x upgrade.sh ./upgrade.sh ``` -## ❗❗❗ DEBIAN AND UBUNTU HEADS UP! -- I am getting ridiculously amount of messages for updating your KooL Hyprland dotfiles. I have made a BIG note on [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) - +## ❗❗❗ ATENȚIE PENTRU UTILIZATORII DEBIAN ȘI UBUNTU! +- Primesc o mulțime de mesaje despre actualizarea dotfiles-urilor Hyprland ale lui KooL. Am făcut o notă mare în [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) -#### ⚠️⚠️⚠️ ATTENTION - BACKUPS CREATED by SCRIPT -> [!CAUTION] -> copy.sh, release.sh and even upgrade.sh creates a backup! -> Kindly investigate manually contents on your $HOME/.config -> Delete manually all the backups which you dont need +#### ⚠️⚠️⚠️ ATENȚIE - COPII DE REZERVĂ CREATE DE SCRIPT +> [!ATENȚIE] +> copy.sh, release.sh și chiar upgrade.sh creează o copie de rezervă! +> Verifică manual conținutul din $HOME/.config +> Șterge manual toate copiile de rezervă de care nu ai nevoie -#### 🛎️ a small note on wallpapers -- by default, only few wallpapers will be copied (1 each dark and light plus 3 more). You will be offered to download more wallpapers. You can preview/check the additional wallpapers from [`THIS`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link +#### 🛎️ o mică notă despre imagini de fundal +- în mod implicit, doar câteva imagini de fundal vor fi copiate (1 pentru modul întunecat și deschis, plus încă 3). Ți se va oferi opțiunea de a descărca mai multe imagini de fundal. Poți previzualiza/verifica imaginile de fundal suplimentare de la [`ACEST`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link +#### ⚠️⚠️⚠️ OBLIGATORIU! după copierea / instalarea acestor dotfiles ++ Apasă SUPER W și setează o imagine de fundal. Aceasta este și pentru a inițializa wallust pentru temele waybar, kitty (tty) și rofi. Totuși, dacă folosești copy.sh sau release.sh, va exista o imagine de fundal inițială presetată și nu va trebui să faci asta -#### ⚠️⚠️⚠️ A MUST! after copying / Installing these dots -+ Press SUPER W and set a wallpaper. This is also to initiate wallust for waybar, kitty (tty) and rofi themes. However, If you use the copy.sh or the release.sh, there will be a preset initial Wallpaper and you dont have to do this ++ Proprietari de Nvidia. Asigură-te că editezi `~/.config/hypr/UserConfigs/ENVariables.conf` (foarte recomandat). +- Utilizatori / proprietari de Nvidia, după instalare, verifică [`ACESTA`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) -+ Nvidia Owners. Make sure to edit your `~/.config/hypr/UserConfigs/ENVariables.conf` (highly recommended). -- NVIDIA users / owners, after installation, check [`THIS`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) ++ Dacă ți-ai setat deja propriile comenzi rapide, monitoare etc., doar copiază-le din copia de rezervă creată înainte de a te deconecta sau reporni. (recomandat) -+ If you have already set your own keybinds, monitors, etc.... Just copy over from backup created before log-out or reboot. (recommended) +#### 📖 Probleme cunoscute și posibile soluții +- verifică această pagină [Întrebări frecvente](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) și [PROBLEME NESOLUȚIONATE](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) +#### 🙋 ÎNTREBĂRI ?!?! ⁉️ +- Întrebări frecvente! Da, poți folosi aceste dotfiles pe alte distribuții! Asigură-te doar că instalezi pachetele corespunzătoare mai întâi! Dacă te face să te simți mai bine, folosesc aceeași configurație pe Gentoo-ul meu :) +- SFAT RAPID! Apasă pe modulul HINT! din Waybar (notă: disponibil doar în layout-urile Waybar implicit și Simple-L [SUS]). Poate fi lansat cu comanda rapidă `SUPER H` +- Mai multe întrebări? click aici pentru a răsfoi acest [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) +- Dacă vrei vechile configurații, acestea sunt colectate în repo-ul meu „Archive”. Vezi [AICI](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) -#### 📖 Known issues and possible solutions -- check out this page [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) and [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) +#### ⌨ Comenzi rapide +- Comenzi rapide [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) +#### 🙏 Cerere specială +- Dacă ai îmbunătățiri pentru dotfiles sau configurații, nu ezita să trimiți un PR pentru îmbunătățiri. Întotdeauna primesc cu bucurie îmbunătățiri, deoarece și eu învăț, la fel ca voi! -#### 🙋 QUESTIONS ?!?! ⁉️ -- FAQ! Yes you can use these dotfiles to other distro! Just ensure to install proper packages first! If it makes you feel better, I use same config on my Gentoo:) -- QUICK HINT! Click the HINT! Waybar module (note only available in Waybar default and Simple-L [TOP] layout). Can be launched by Keybind `SUPER H` -- More question? click here browse through this [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) -- If you want the old configs, it is collected on my "Archive" repo. See [HERE](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) +#### ✍️ Contribuții +- Vrei să contribui? Click [`AICI`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) pentru un ghid despre cum să contribui -#### ⌨ Keybinds -- Keybinds [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) +#### 🤷‍♂️ DE FĂCUT! +- [ ] Ajustarea dotfiles-urilor - 🚧 în progres constant +- ~~[ ] Posibil trecerea la starship? Deși starship are teme limitate comparativ cu oh-my-zsh.~~ fără planuri pentru moment -#### 🙏 Special request -- If you have improvements on the dotfiles or configuration, feel free to submit a PR for improvement. I always welcome improvements as I am also just learning just like you guys! +#### 🔮 Server Discord +- te invit să te alături serverului meu [Discord](https://discord.com/invite/kool-tech-world) +#### 💖 Suport +- o stea pe repo-urile mele de Github ar fi minunată 🌟 -#### ✍️ Contributing -- Want to contribute? Click [`HERE`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) for a guide how to contribute +- Abonează-te la canalul meu de YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) - -#### 🤷‍♂️ TO DO! -- [ ] Tweak dots - 🚧 in constant progress -- ~~[ ] Quite possibly switch to starship? Although starship has limited themes compared to oh-my-zsh.~~ no plans for now - - -#### 🔮 Discord Server -- kindly join my [Discord](https://discord.com/invite/kool-tech-world) - - -#### 💖 Support -- a Star on my Github repos would be nice 🌟 - -- Subscribe to my Youtube Channel [YouTube](https://www.youtube.com/@Ja.KooLit) - -- you can also give support through coffee's or btc 😊 +- de asemenea, poți oferi suport prin cafele sau btc 😊 [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) -or +sau [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) -Or you can donate cryto on my btc wallet :) +Sau poți dona criptomonede pe portofelul meu btc :) > 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i ![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) - - -## 🫰 Thank you for the stars 🩷 +## 🫰 Mulțumesc pentru stele 🩷 [![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) -- cgit v1.2.3 From aedeb295cc7602c820646e66c0a00af1302326b0 Mon Sep 17 00:00:00 2001 From: CristianSw <60692725+CristianSw@users.noreply.github.com> Date: Fri, 6 Jun 2025 11:16:49 +0300 Subject: Fixed romanian translate and reverted main READ.me file --- README.md | 182 +++++++++++++++++++++++++++++-------------------------- README.ro.md | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+), 84 deletions(-) create mode 100644 README.ro.md diff --git a/README.md b/README.md index e576b41b..6ad87ded 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,12 @@
@@ -29,7 +29,7 @@

Sparkles - Prezentarea fișierelor Dotfiles Hyprland ale lui KooL + KooL's Hyprland Dotfiles Showcase Sparkles

@@ -39,159 +39,173 @@ https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 -### 📹 Ghiduri video -- la finalul paginii +### 📹 A video walkthroughs +- at the bottom -### 🎞️ Demo AGS Overview -- în caz că te întrebi, aici este un demo scurt al AGS overview [Link YouTube](https://youtu.be/zY5SLNPBJTs) +### 🎞️ AGS Overview DEMO +- in case you wonder, here is a short demo of AGS overview [Youtube LINK](https://youtu.be/zY5SLNPBJTs) --- -[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALARE)](https://git.io/typing-svg) -### 🚩 🏁 Scripturi automate de instalare Hyprland pentru distribuții, clonare și pornire 🇵🇭 -> [!ATENȚIE] -> Dacă folosești FISH SHELL, NU utiliza această funcție. Clonează Distro-Hyprland și rulează install.sh în schimb. +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALLATION)](https://git.io/typing-svg) +### 🚩 🏁 Auto Distro-Hyprland install scripts cloning and starting 🇵🇭 +> [!CAUTION] +> If you are using FISH SHELL, DO NOT use this function. Clone the Distro-Hyprland and ran install.sh instead -- NOTĂ: ai nevoie de pachetul `curl` pentru ca aceasta să funcționeze +- NOTE: you need package `curl` for this to work ```bash sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) ``` -- acum poți folosi comanda de mai sus pentru a clona automat scripturile de instalare Distro-Hyprland de mai jos -- va clona scripturile de instalare și va porni `install.sh` 😎 +- you can now use above command to automatically clone the Distro-Hyprland install scripts below +- it will clone the install scripts and start the `install.sh` 😎 -### 👁️‍🗨️ Scripturile mele de instalare Hyprland 👁️‍🗨️ -- Scripturi automate Hyprland pentru distribuția aleasă, care vor descărca aceste dotfiles dacă optezi pentru instalarea acestor configurații + +### 👁️‍🗨️ My Hyprland install Scripts 👁️‍🗨️ +- Automated Hyprland Scripts for Distro of choice which will pull this dotfiles if opted to install these configurations - [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) + - [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) + - [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) + - [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) + - [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) + - [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) - [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) -- [Ubuntu 25.04 - (FAZĂ ALPHA)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) - +- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) --- -### 🪧 Atenție 🪧 -- Acest repo NU conține și NU va instala niciun pachet. Acestea sunt doar configurații Hyprland pre-configurate sau dotfiles -- consultă scripturile de instalare pentru a vedea ce pachete trebuie instalate... dar cel puțin, pachetele Hyprland sunt necesare 😏😏😏 evident!! -- Acest repo va fi descărcat de scripturile de instalare Distro-Hyprland de mai sus dacă optezi pentru descărcarea dotfiles-urilor pre-configurate +### 🪧 Attention 🪧 +- This repo does NOT contain or will NOT install any packages. These are only pre-configured-hyprland configs or dotfiles +- refer to install scripts what packages needed to install... but atleast, Hyprland packages is needed 😏😏😏 duh!! +- This repo will be pulled by the Distro-Hyprland install scripts above if you opt to download pre-configured dots -### 👀 Capturi de ecran 👀 -- Toate capturile de ecran sunt colectate aici [Capturi de ecran](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) +### 👀 Screenshots 👀 +- All screenshots are collected here [Screenshots](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) -### 📦 Ce mai e nou? -- Pentru a urmări ușor modificările, voi actualiza [Jurnalul de modificări](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Capturile de ecran vor fi incluse dacă modificările merită menționate! +### 📦 Whats new? +- To easily track changes, I will be updating the [CHANGELOGS](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) Screenshots will be included if worth mentioning the changes! -> [!NOTĂ] -> Reține că, în mod implicit, dotfiles-urile lui Kool sunt ajustate/configurate pentru afișaje 2k (1440p) fără scalare. +> [!NOTE] +> Kindly note that by defeault, Kools Dots are adjusted / configured for 2k (1440p) display without scaling. -### 💥 Instrucțiuni de copiere / instalare / actualizare 💥 -- [`MAI MULTE INFORMAȚII AICI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) -> [!Notă] -> Scriptul automat de copiere „copy.sh” va crea copii de rezervă ale directoarelor care urmează să fie copiate. Totuși, este o idee bună să faci manual o copie de rezervă, în caz că scriptul nu reușește să o facă! +### 💥 Copying / Installation / Update instructions 💥 +- [`MORE INFO HERE`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +> [!Note] +> The auto copy script "copy.sh" will create backups of intended directories to be copied. However, still a good idea to manually backup just incase script failed to backup! +- clone this repo by using git. Change directory, make executable and run the script -- clonează acest repo folosind git. Schimbă directorul, fă scriptul executabil și rulează-l - -> pentru a descărca din ramura Master +> to download from Master branch ```bash git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git cd Hyprland-Dots ``` -> pentru a descărca din ramura Development (dezvoltare și testare) +> to download from Development branch (development and testing) ```bash git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development cd Hyprland-Dots ``` -- copiere/instalare automată a dotfiles-urilor pre-configurate (recomandat pentru actualizări) +- automatic copy/install of pre-configured dots (recommended for updating) ```bash chmod +x copy.sh ./copy.sh ``` -- pentru a copia/instala din versiuni (stabile) (notă: aceasta este cu o versiune mai veche decât cea din ramura principală) +- to copy/install from releases (stable) (note this is 1 version older than in main) ```bash chmod +x release.sh ./release.sh ``` -- Funcția UPGRADE.sh +- UPGRADE.sh function > [!IMPORTANT] -> Ai nevoie de rsync pentru ca aceasta să funcționeze -> trebuie să ai deja configurat și funcțional Hyprland-ul lui KooL înainte de a folosi această funcție +> You need rsync for it to work +> you should have already up and running KooL's Hyprland before using this function ```bash chmod +x upgrade.sh ./upgrade.sh ``` -## ❗❗❗ ATENȚIE PENTRU UTILIZATORII DEBIAN ȘI UBUNTU! -- Primesc o mulțime de mesaje despre actualizarea dotfiles-urilor Hyprland ale lui KooL. Am făcut o notă mare în [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +## ❗❗❗ DEBIAN AND UBUNTU HEADS UP! +- I am getting ridiculously amount of messages for updating your KooL Hyprland dotfiles. I have made a BIG note on [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + -#### ⚠️⚠️⚠️ ATENȚIE - COPII DE REZERVĂ CREATE DE SCRIPT -> [!ATENȚIE] -> copy.sh, release.sh și chiar upgrade.sh creează o copie de rezervă! -> Verifică manual conținutul din $HOME/.config -> Șterge manual toate copiile de rezervă de care nu ai nevoie +#### ⚠️⚠️⚠️ ATTENTION - BACKUPS CREATED by SCRIPT +> [!CAUTION] +> copy.sh, release.sh and even upgrade.sh creates a backup! +> Kindly investigate manually contents on your $HOME/.config +> Delete manually all the backups which you dont need -#### 🛎️ o mică notă despre imagini de fundal -- în mod implicit, doar câteva imagini de fundal vor fi copiate (1 pentru modul întunecat și deschis, plus încă 3). Ți se va oferi opțiunea de a descărca mai multe imagini de fundal. Poți previzualiza/verifica imaginile de fundal suplimentare de la [`ACEST`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link +#### 🛎️ a small note on wallpapers +- by default, only few wallpapers will be copied (1 each dark and light plus 3 more). You will be offered to download more wallpapers. You can preview/check the additional wallpapers from [`THIS`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link -#### ⚠️⚠️⚠️ OBLIGATORIU! după copierea / instalarea acestor dotfiles -+ Apasă SUPER W și setează o imagine de fundal. Aceasta este și pentru a inițializa wallust pentru temele waybar, kitty (tty) și rofi. Totuși, dacă folosești copy.sh sau release.sh, va exista o imagine de fundal inițială presetată și nu va trebui să faci asta -+ Proprietari de Nvidia. Asigură-te că editezi `~/.config/hypr/UserConfigs/ENVariables.conf` (foarte recomandat). -- Utilizatori / proprietari de Nvidia, după instalare, verifică [`ACESTA`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) +#### ⚠️⚠️⚠️ A MUST! after copying / Installing these dots ++ Press SUPER W and set a wallpaper. This is also to initiate wallust for waybar, kitty (tty) and rofi themes. However, If you use the copy.sh or the release.sh, there will be a preset initial Wallpaper and you dont have to do this -+ Dacă ți-ai setat deja propriile comenzi rapide, monitoare etc., doar copiază-le din copia de rezervă creată înainte de a te deconecta sau reporni. (recomandat) ++ Nvidia Owners. Make sure to edit your `~/.config/hypr/UserConfigs/ENVariables.conf` (highly recommended). +- NVIDIA users / owners, after installation, check [`THIS`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) -#### 📖 Probleme cunoscute și posibile soluții -- verifică această pagină [Întrebări frecvente](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) și [PROBLEME NESOLUȚIONATE](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) ++ If you have already set your own keybinds, monitors, etc.... Just copy over from backup created before log-out or reboot. (recommended) -#### 🙋 ÎNTREBĂRI ?!?! ⁉️ -- Întrebări frecvente! Da, poți folosi aceste dotfiles pe alte distribuții! Asigură-te doar că instalezi pachetele corespunzătoare mai întâi! Dacă te face să te simți mai bine, folosesc aceeași configurație pe Gentoo-ul meu :) -- SFAT RAPID! Apasă pe modulul HINT! din Waybar (notă: disponibil doar în layout-urile Waybar implicit și Simple-L [SUS]). Poate fi lansat cu comanda rapidă `SUPER H` -- Mai multe întrebări? click aici pentru a răsfoi acest [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) -- Dacă vrei vechile configurații, acestea sunt colectate în repo-ul meu „Archive”. Vezi [AICI](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) -#### ⌨ Comenzi rapide -- Comenzi rapide [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) +#### 📖 Known issues and possible solutions +- check out this page [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) and [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) -#### 🙏 Cerere specială -- Dacă ai îmbunătățiri pentru dotfiles sau configurații, nu ezita să trimiți un PR pentru îmbunătățiri. Întotdeauna primesc cu bucurie îmbunătățiri, deoarece și eu învăț, la fel ca voi! -#### ✍️ Contribuții -- Vrei să contribui? Click [`AICI`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) pentru un ghid despre cum să contribui +#### 🙋 QUESTIONS ?!?! ⁉️ +- FAQ! Yes you can use these dotfiles to other distro! Just ensure to install proper packages first! If it makes you feel better, I use same config on my Gentoo:) +- QUICK HINT! Click the HINT! Waybar module (note only available in Waybar default and Simple-L [TOP] layout). Can be launched by Keybind `SUPER H` +- More question? click here browse through this [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) +- If you want the old configs, it is collected on my "Archive" repo. See [HERE](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) -#### 🤷‍♂️ DE FĂCUT! -- [ ] Ajustarea dotfiles-urilor - 🚧 în progres constant -- ~~[ ] Posibil trecerea la starship? Deși starship are teme limitate comparativ cu oh-my-zsh.~~ fără planuri pentru moment +#### ⌨ Keybinds +- Keybinds [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) -#### 🔮 Server Discord -- te invit să te alături serverului meu [Discord](https://discord.com/invite/kool-tech-world) +#### 🙏 Special request +- If you have improvements on the dotfiles or configuration, feel free to submit a PR for improvement. I always welcome improvements as I am also just learning just like you guys! -#### 💖 Suport -- o stea pe repo-urile mele de Github ar fi minunată 🌟 -- Abonează-te la canalul meu de YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) +#### ✍️ Contributing +- Want to contribute? Click [`HERE`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) for a guide how to contribute -- de asemenea, poți oferi suport prin cafele sau btc 😊 + +#### 🤷‍♂️ TO DO! +- [ ] Tweak dots - 🚧 in constant progress +- ~~[ ] Quite possibly switch to starship? Although starship has limited themes compared to oh-my-zsh.~~ no plans for now + + +#### 🔮 Discord Server +- kindly join my [Discord](https://discord.com/invite/kool-tech-world) + + +#### 💖 Support +- a Star on my Github repos would be nice 🌟 + +- Subscribe to my Youtube Channel [YouTube](https://www.youtube.com/@Ja.KooLit) + +- you can also give support through coffee's or btc 😊 [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) -sau +or [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) -Sau poți dona criptomonede pe portofelul meu btc :) +Or you can donate cryto on my btc wallet :) > 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i ![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) -## 🫰 Mulțumesc pentru stele 🩷 + + +## 🫰 Thank you for the stars 🩷 [![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) diff --git a/README.ro.md b/README.ro.md new file mode 100644 index 00000000..1a03c936 --- /dev/null +++ b/README.ro.md @@ -0,0 +1,194 @@ +

+ +

+ +

+ +

+ +
+ +
+ +![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) + +
+
+ +

+ Sparkles + Prezentarea fișierelor Dotfiles Hyprland ale lui KooL + Sparkles +

+ +
+ +https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 + +
+ +### 📹 Ghiduri video +- la finalul paginii + +### 🎞️ Demo AGS Overview +- în caz că te întrebi, aici este un demo scurt al AGS overview [Link YouTube](https://youtu.be/zY5SLNPBJTs) + + + +--- +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALARE)](https://git.io/typing-svg) +### 🚩 🏁 Scripturi automate de instalare Hyprland pentru distribuții, clonare și pornire 🇵🇭 +> [!ATENȚIE] +> Dacă folosești FISH SHELL, NU utiliza această funcție. Clonează Distro-Hyprland și rulează install.sh în schimb. + +- NOTĂ: ai nevoie de pachetul `curl` pentru ca aceasta să funcționeze + +```bash +sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) +``` + +- acum poți folosi comanda de mai sus pentru a clona automat scripturile de instalare Distro-Hyprland de mai jos +- va clona scripturile de instalare și va porni `install.sh` 😎 + +### 👁️‍🗨️ Scripturile mele de instalare Hyprland 👁️‍🗨️ +- Scripturi automate Hyprland pentru distribuția aleasă, care vor descărca aceste dotfiles dacă optezi pentru instalarea acestor configurații + +- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) +- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) +- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) +- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) +- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) +- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) +- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) +- [Ubuntu 25.04 - (FAZĂ ALPHA)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + +--- + +### 🪧 Atenție 🪧 +- Acest repo NU conține și NU va instala niciun pachet. Acestea sunt doar configurații Hyprland pre-configurate sau dotfiles +- consultă scripturile de instalare pentru a vedea ce pachete trebuie instalate... dar cel puțin, pachetele Hyprland sunt necesare 😏😏😏 evident!! +- Acest repo va fi descărcat de scripturile de instalare Distro-Hyprland de mai sus dacă optezi pentru descărcarea dotfiles-urilor pre-configurate + +### 👀 Capturi de ecran 👀 +- Toate capturile de ecran sunt colectate aici [Capturi de ecran](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) + +### 📦 Ce mai e nou? +- Pentru a urmări ușor modificările, voi actualiza [Jurnalul de modificări](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Capturile de ecran vor fi incluse dacă modificările merită menționate! + +> [!NOTĂ] +> Reține că, în mod implicit, dotfiles-urile lui Kool sunt ajustate/configurate pentru afișaje 2k (1440p) fără scalare. + +### 💥 Instrucțiuni de copiere / instalare / actualizare 💥 +- [`MAI MULTE INFORMAȚII AICI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +> [!Notă] +> Scriptul automat de copiere „copy.sh” va crea copii de rezervă ale directoarelor care urmează să fie copiate. Totuși, este o idee bună să faci manual o copie de rezervă, în caz că scriptul nu reușește să o facă! + +- clonează acest repo folosind git. Schimbă directorul, fă scriptul executabil și rulează-l + +> pentru a descărca din ramura Master +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git +cd Hyprland-Dots +``` + +> pentru a descărca din ramura Development (dezvoltare și testare) +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development +cd Hyprland-Dots +``` + +- copiere/instalare automată a dotfiles-urilor pre-configurate (recomandat pentru actualizări) +```bash +chmod +x copy.sh +./copy.sh +``` + +- pentru a copia/instala din versiuni (stabile) (notă: aceasta este cu o versiune mai veche decât cea din ramura principală) +```bash +chmod +x release.sh +./release.sh +``` + +- Funcția UPGRADE.sh +> [!IMPORTANT] +> Ai nevoie de rsync pentru ca aceasta să funcționeze +> trebuie să ai deja configurat și funcțional Hyprland-ul lui KooL înainte de a folosi această funcție +```bash +chmod +x upgrade.sh +./upgrade.sh +``` + +## ❗❗❗ ATENȚIE PENTRU UTILIZATORII DEBIAN ȘI UBUNTU! +- Primesc o mulțime de mesaje despre actualizarea dotfiles-urilor Hyprland ale lui KooL. Am făcut o notă mare în [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + +#### ⚠️⚠️⚠️ ATENȚIE - COPII DE REZERVĂ CREATE DE SCRIPT +> [!ATENȚIE] +> copy.sh, release.sh și chiar upgrade.sh creează o copie de rezervă! +> Verifică manual conținutul din $HOME/.config +> Șterge manual toate copiile de rezervă de care nu ai nevoie + +#### 🛎️ o mică notă despre imagini de fundal +- în mod implicit, doar câteva imagini de fundal vor fi copiate (1 pentru modul întunecat și deschis, plus încă 3). Ți se va oferi opțiunea de a descărca mai multe imagini de fundal. Poți previzualiza/verifica imaginile de fundal suplimentare de la [`ACEST`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link + +#### ⚠️⚠️⚠️ OBLIGATORIU! după copierea / instalarea acestor dotfiles ++ Apasă SUPER W și setează o imagine de fundal. Aceasta este și pentru a inițializa wallust pentru temele waybar, kitty (tty) și rofi. Totuși, dacă folosești copy.sh sau release.sh, va exista o imagine de fundal inițială presetată și nu va trebui să faci asta + ++ Proprietari de Nvidia. Asigură-te că editezi `~/.config/hypr/UserConfigs/ENVariables.conf` (foarte recomandat). +- Utilizatori / proprietari de Nvidia, după instalare, verifică [`ACESTA`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) + ++ Dacă ți-ai setat deja propriile comenzi rapide, monitoare etc., doar copiază-le din copia de rezervă creată înainte de a te deconecta sau reporni. (recomandat) + +#### 📖 Probleme cunoscute și posibile soluții +- verifică această pagină [Întrebări frecvente](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) și [PROBLEME NESOLUȚIONATE](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) + +#### 🙋 ÎNTREBĂRI ?!?! ⁉️ +- Întrebări frecvente! Da, poți folosi aceste dotfiles pe alte distribuții! Asigură-te doar că instalezi pachetele corespunzătoare mai întâi! Dacă te face să te simți mai bine, folosesc aceeași configurație pe Gentoo-ul meu :) +- SFAT RAPID! Apasă pe modulul HINT! din Waybar (notă: disponibil doar în layout-urile Waybar implicit și Simple-L [SUS]). Poate fi lansat cu comanda rapidă `SUPER H` +- Mai multe întrebări? click aici pentru a răsfoi acest [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) +- Dacă vrei vechile configurații, acestea sunt colectate în repo-ul meu „Archive”. Vezi [AICI](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) + +#### ⌨ Comenzi rapide +- Comenzi rapide [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) + +#### 🙏 Cerere specială +- Dacă ai îmbunătățiri pentru dotfiles sau configurații, nu ezita să trimiți un PR pentru îmbunătățiri. Întotdeauna primesc cu bucurie îmbunătățiri, deoarece și eu învăț, la fel ca voi! + +#### ✍️ Contribuții +- Vrei să contribui? Click [`AICI`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) pentru un ghid despre cum să contribui + +#### 🤷‍♂️ DE FĂCUT! +- [ ] Ajustarea dotfiles-urilor - 🚧 în progres constant +- ~~[ ] Posibil trecerea la starship? Deși starship are teme limitate comparativ cu oh-my-zsh.~~ fără planuri pentru moment + +#### 🔮 Server Discord +- te invit să te alături serverului meu [Discord](https://discord.com/invite/kool-tech-world) + +#### 💖 Suport +- o stea pe repo-urile mele de Github ar fi minunată 🌟 + +- Abonează-te la canalul meu de YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) + +- de asemenea, poți oferi suport prin cafele sau btc 😊 + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) + +sau + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) + +Sau poți dona criptomonede pe portofelul meu btc :) +> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i + +![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) + +## 🫰 Mulțumesc pentru stele 🩷 +[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) \ No newline at end of file -- cgit v1.2.3 From a8a445db069b3201ff3c6121afab43f360a30d7c Mon Sep 17 00:00:00 2001 From: CristianSw <60692725+CristianSw@users.noreply.github.com> Date: Fri, 6 Jun 2025 11:24:02 +0300 Subject: Created i18n folder proposal for better structure for i18n files store translated READ.me files in dedicated folder --- README.de.md | 230 ------------------------------------------------------ README.jp.md | 228 ----------------------------------------------------- README.ro.md | 194 --------------------------------------------- i18n/README.de.md | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ i18n/README.jp.md | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++ i18n/README.ro.md | 194 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 652 insertions(+), 652 deletions(-) delete mode 100644 README.de.md delete mode 100644 README.jp.md delete mode 100644 README.ro.md create mode 100644 i18n/README.de.md create mode 100644 i18n/README.jp.md create mode 100644 i18n/README.ro.md diff --git a/README.de.md b/README.de.md deleted file mode 100644 index eed9def2..00000000 --- a/README.de.md +++ /dev/null @@ -1,230 +0,0 @@ -[![en](https://img.shields.io/badge/lang-en-yellow.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.md) -[![jp](https://img.shields.io/badge/lang-jp-blue.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.jp.md) - -

- -

- -

- -

- -
- -
- -![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) - -
-
- -

- Sparkles - KooL's Hyprland Dotfiles Showcase - Sparkles -

- -
- -https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 - -
- -### 📹 Ein Video Guide - -- folgt nach der Textanleitung - -### 🎞️ AGS Übersicht DEMO - -- Hier ist eine kurze Demo der AGS [Youtube LINK](https://youtu.be/zY5SLNPBJTs) - - - ---- - -[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALLATION)](https://git.io/typing-svg) - -### 🚩 🏁 Distro Hyprland Installationsskripte herunterladen und ausführen - -> [!VORSICHT] -> Wenn du die FISH-SHELL benutzt, VERWENDE diese Funktion NICHT. Klone stattdessen das Distro-Hyprland-Repository und führe install.sh aus. - -- HINWEIS: Das Paket `curl` muss installiert sein, um die Skripte herunterzuladen - -```bash -sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) -``` - -- Mit dem obigen Befehl kannst du jetzt automatisch die Hyprland Installationsskripte herunterladen und ausführen. -- Das Skript wird weitere Installationsskripte klonen und die `install.sh` starten. 😎 - -### 👁️‍🗨️ Meine Hyprland-Installationsskripte 👁️‍🗨️ - -- Automatisierte Hyprland-Skripte für ein Distro deiner Wahl. Diese Skripte laden, wenn ben;tigt, meine vorkonfigurierten Dotfiles -- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) - -- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) - -- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) - -- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) - -- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) - -- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) -- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) -- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) - ---- - -### 🪧 Achtung 🪧 - -- Dieses Repository enthält keine Pakete und wird keine Pakete installieren. Es enthält nur vorkonfigurierte Hyprland-Configs/Dotfiles. -- In den Installationsskripten kann man die benötigten Pakete finden. Zumindest müssen aber die Hyprland-Pakete installiert sein 😏😏😏 logisch!! -- Dieses Repository wird von den oben beschriebenen Distro Hyprland-Installationsskripten heruntergeladen, wenn du dich entscheidest, die vorkonfigurierten Dotfiles verwenden zu wollen. - -### 👀 Screenshots 👀 - -- Beispiel Screenshots findest du hier [Screenshots](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) - -### 📦 Whats new? - -- Um Änderungen leicht nachzuvollziehen, werde ich die [CHANGELOGS](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) regelmäßig aktualisieren. Es werden neue Screenshots hinzugefügt, wenn die Änderungen erwähnenswert sind! - -> [!NOTE] -> Bitte beachte, dass Kools Dots standardmäßig für einen 2K (1440p) Monitor ohne Skalierung angepasst und konfiguriert sind. - -### 💥 Kopieren / Installation / Update-Anleitung 💥 - -- [`Weiter Infos hier`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) - > [!Note] - > Das Kopierskript "copy.sh" erstellt Backups der zu kopierenden Konfigurationsverzeichnisse. Sollte das Skript fehlschlagen, empfiehlt es sich, manuell ein Backup zu erstellen. -- Klone das Repository mit Git, wechsle in das Verzeichnis, mache die Datei ausführbar und führe das Skript aus: - -> Um den Master-Branch herunterzuladen - -```bash -git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -cd Hyprland-Dots -``` - -> Um den Entwicklungs-Branch (Development & Testing) herunterzuladen: - -```bash -git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development -cd Hyprland-Dots -``` - -- Automatisiertes Kopieren und Installieren der vorkonfigurierten Dotfiles (empfohlen für Updates): - -```bash -chmod +x copy.sh -./copy.sh -``` - -- Kopieren und Installieren aus den Releases (stable) (beachte, dass dies eine Version älter als "main" ist): - -```bash -chmod +x release.sh -./release.sh -``` - -- UPGRADE.sh für ein Versionsupgrade - > [!IMPORTANT] - > rsync wird benötigt, damit es funktioniert. - > KooL's Hyprland sollte bereits laufen, bevor du dieses Skript verwendest. - -```bash -chmod +x upgrade.sh -./upgrade.sh -``` - -## ❗❗❗ DEBIAN AND UBUNTU INFORMATION! - -- Ich bekomme eine große Menge an Nachrichten über das Updaten eurer KooL Hyprland dotfiles. Es gibt dazu eine Info im [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) - -#### ⚠️⚠️⚠️ ACHTUNG - SKRIPT-ERSTELLTE BACKUPS - -> [!CAUTION] -> copy.sh, release.sh und auch upgrade.sh erstellen Backups! -> Schaue dir bitte manuell den Inhalt deines $HOME/.config Ordners an -> Entferne alle nicht mehr benötigten Backups bitte selbst - -#### 🛎️ kleiner Hinweis zu Hintergrundbildern - -- ständardmäßig werden nur einige Hintergründe kopiert (jeweils 1 dunkeles und helles plus 3 weitere). Dir wird angeboten werden, weitere Hintergrundbilder herunterzuladen. Du kannst dir die verfügbaren Hintergründe [`HIER`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) anschauen. - -#### ⚠️⚠️⚠️ WICHTIG! Nach dem Kopieren / Der Installation der Dotfiles - -- Drücke SUPER W und wähle ein Hintergrundbild. Desweiteren wird hierdurch wallust für waybar, kitty (tty) und die rofi Themes aktiviert. Wenn du copy.sh oder release.sh benutzt hast, wird ein Standard Hintergrund gesetzt sein und die Initialisierung ist bereits gesehen - -- Für Nvidia Benutzer. Stelle sicher, dass du deine `~/.config/hypr/UserConfigs/ENVariables.conf` anpasst (unbedingt empfohlen). - -* Für NVIDIA Benutzer, schaue dir diese Informationen [`HIER`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) an. - -- Wenn die bereits deine Keybinds, Monitoren, usw. eingestellt hast... Kopiere die Einstellungen von dem Backup vor dem Logout / Reboot. (empfohlen) - -#### 📖 Bekannte Probleme und mögliche Lösungen - -- Schau dir diese Seite an [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) und checke die [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) - -#### 🙋 FRAGEN ?!?! ⁉️ - -- FAQ! Die Dotfiles funktionieren auch auf anderen Distros! Stelle nur sicher, die richtigen Pakete vorher zu installieren! Falls du dich dann besser fühlst, ich benutze die selbe Konfiguration für mein Gentoo:) -- KLEINER HINWEIS! Klicke auf das HINT! Waybar Modul (Notiz, nur in Waybar default und Simple-L [TOP] Layout verfügbar). Kann auch mit der Tastenkombination `SUPER H` gestartet werden -- Weitere Fragen? Klicke hier um das [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) zu durchstöbern. -- Falls du eine ältere Version der Konfiguration haben möchtest, sind diese in meinem "Archive" Repository verfügbar. Siehe [HIER](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) - -#### ⌨ Keybinds - -- Keybinds [`KLICKE`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) - -#### 🙏 Hilfe gebraucht - -- Wenn du Verbesserungen der Dotfiles oder Konfigurationen hast, mache gerne einen PR für die Verbesserung. Ich heiße Verbesserungen immer Willkommen, da ich genau wie ihr Alle immer viel Neues lerne. - -#### ✍️ Contributing - -- Möchtest du contributen? Klicke [`HIER`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) für eine Anleitung. - -#### 🤷‍♂️ TO DO! - -- [ ] Dotfiles verbesser - 🚧 in ständiger Entwicklung -- ~~[ ] Vielleicht zu starship wechseln. Jedoch limitiere Themes im Vergleich zu oh-my-zsh.~~ momentan nicht geplant - -#### 🔮 Discord Server - -- Bitte joine meinem [Discord](https://discord.com/invite/kool-tech-world) - -#### 💖 Unterstützung - -- ein Star auf meinen Github repos wäre nett 🌟 - -- Abbonieren meinen Youtube Kanal [YouTube](https://www.youtube.com/@Ja.KooLit) - -- du kannst mich auch mit Kaffees oder BTC unterstützen 😊 - -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) - -oder - -[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) - -Oder du kannst auch Krypto an meine btc wallet spenden :) - -> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i - -![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) - -## 🫰 Vielen Dank für die stars 🩷 - -[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) diff --git a/README.jp.md b/README.jp.md deleted file mode 100644 index 84d64692..00000000 --- a/README.jp.md +++ /dev/null @@ -1,228 +0,0 @@ -[![en](https://img.shields.io/badge/lang-en-yellow.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.md) -[![de](https://img.shields.io/badge/lang-de-green.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.de.md) - -

- -

- -

- -

- -
- -
- -![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) - -
-
- -

- Sparkles - KooL's Hyprland Dotfiles Showcase - Sparkles -

- -
- -https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 - -
- -### 📹 動画による説明 - -- ページの下部へ - -### 🎞️ AGS概要デモ - -- 概要が気になる場合は、こちらにAGS概要の短いデモがあります [Youtube リンク](https://youtu.be/zY5SLNPBJTs) - - - ---- - -[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALLATION)](https://git.io/typing-svg) - -### 🚩 🏁 自動化された Distro-Hyprland のインストールスクリプトのクローンと起動 🇵🇭 - -> [注意!] -> FISH SHELLを使用している場合、この関数を使わないでください。代わりにDistro-Hyprlandをクローンしinstall.shを実行してください。 - -- 重要:これを動作させるには、`curl` パッケージが必要です。 - -```bash -sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) -``` - -- 上記のコマンドを使用して、Distro-Hyprland のインストールスクリプトを自動的にクローンできます。 -- インストールスクリプトをクローンし、`install.sh` を実行します😎 - -### 👁️‍🗨️ 私の Hyprland のインストールスクリプト 👁️‍🗨️ - -- 選択したディストロ向けの自動化された Hyprland スクリプトです。これらの設定をインストールするオプションを選択した場合、対応する dotfiles を取得します。 - -- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) - -- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) - -- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) - -- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) - -- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) - -- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) -- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) -- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) - ---- - -### 🪧 注意 🪧 - -- このリポジトリにはパッケージは含まれておらず、インストールもされません。含まれているのは、あらかじめ設定された Hyprland の設定ファイルや dotfiles のみです。 -- 必要なパッケージについてはインストールスクリプトを参照してください。ただし、少なくとも Hyprland のパッケージは必須です 😏😏😏 -- このリポジトリは、上記の Distro-Hyprland インストールスクリプトによって、プリセットの dotfiles をダウンロードするオプションを選択した場合に取得されます。 - -### 👀 スクリーンショット 👀 - -- すべてのスクリーンショットはここにまとめられています。 [スクリーンショット](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) - -### 📦 変更点 - -- 変更を簡単に追跡できるよう、[変更ログ](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) 変更が注目に値する場合はスクリーンショットも含めます! - -> [注意!] -> デフォルトでは、Kools Dots はスケーリングなしの 2K (1440p) ディスプレイ向けに調整・設定されています。 - -### 💥 コピー / インストール / アップデート手順 💥 - -- [`ここに詳細を記載しています`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) - > [注意!] - > 自動コピーのスクリプトである "copy.sh" は、コピー対象のディレクトリをバックアップします。しかし、スクリプトがバックアップに失敗する可能性もあるため、手動でバックアップを取るのも良い考えです! -- このリポジトリを git でクローンし、ディレクトリを移動して、実行可能にした後、スクリプトを実行してください。 - -> Master ブランチからダウンロードする場合 - -```bash -git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -cd Hyprland-Dots -``` - -> 開発ブランチ(Development)からダウンロードする場合(開発およびテスト用) - -```bash -git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development -cd Hyprland-Dots -``` - -- プリセット dotfiles の自動コピー/インストール(更新推奨) - -```bash -chmod +x copy.sh -./copy.sh -``` - -- リリース版(Stable)からコピー/インストール(メインより 1 バージョン古い点に注意) - -```bash -chmod +x release.sh -./release.sh -``` - -- UPGRADE.sh の関数について - > [重要!] - > これを動作させるには rsync が必要です。 - > この機能を使用する前に、KooL's Hyprland が既に動作している必要があります。 - -```bash -chmod +x upgrade.sh -./upgrade.sh -``` - -## ❗❗❗ DEBIAN および UBUNTU ユーザーへの注意! - -- KooL Hyprland の dotfiles 更新に関するメッセージが大量に届いています。 [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update)に大きく注意書きを記載しました。 - -#### ⚠️⚠️⚠️ スクリプトによって作成されたバックアップについての注意 - -> [超重要!] -> copy.sh、release.sh、そして upgrade.sh もバックアップを作成します! -> $HOME/.config の内容を手動で確認してください。 -> 不要なバックアップは手動で削除してください。 - -#### 🛎️ 壁紙に関するちょっとした注意 - -- デフォルトでは、ダークとライト各 1 枚+3 枚の壁紙のみがコピーされます。追加の壁紙をダウンロードするオプションが提供されます。追加の壁紙は[`THIS`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) リンクからプレビュー/確認できます。 - -#### ⚠️⚠️⚠️これらの dotfiles をコピー / インストールした後の必須事項 - -- SUPER + W を押して壁紙を設定してください。これにより、Waybar、Kitty(TTY)、Rofi のテーマ用に Wallust を初期化できます。ただし、copy.sh または release.sh を使用した場合は、初期壁紙がプリセットされているため、この手順は不要です。 - -- NVIDIA の所有者へ。`~/.config/hypr/UserConfigs/ENVariables.conf`を編集してください(強く推奨)。 - -* NVIDIA の所有者とユーザーへ。 インsトール後に [`THIS`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users)を確認してください。 - -- 既に独自のキー設定やモニター設定を行っている場合は、ログアウトや再起動前に作成されたバックアップからコピーしてください。(推奨) - -#### 📖 既知の問題と可能な解決策 - -- こちらのページを確認してください: [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) & [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) - -#### 🙋 質問対応 ⁉️ - -- FAQ! はい、これらの dotfiles は他のディストロでも使用できます!ただし、適切なパッケージを事前にインストールしてください!安心できるなら、私も Gentoo で同じ設定を使っています :) -- クイックヒント! Waybar モジュールの HINT! をクリックしてください。 (Waybar のデフォルトレイアウトおよび Simple-L [TOP] レイアウトでのみ利用可能)。キーバインドの `SUPER H`でも起動できます。 -- さらに質問がありますか? こちらをクリックして [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/)を参照してください。 -- 旧設定が欲しい場合, すべて "Archive" リポジトリにまとめています。詳しくは[HERE](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive)をご覧ください。 - -#### ⌨ キーバインド - -- キーバインドの説明はこちら: [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) - -#### 🙏 スペシャルリクエスト - -- dotfilesや設定の改善がある場合改善のためのPRをぜひ送ってください!私も皆さんと同じように学んでいるので、改善は大歓迎です! -- Waybar のスタイル(新しいパネルスタイルは微調整が必要)→ ご協力をお願いできますか?🙏 - -#### 🤷‍♂️ TO DO! - -- [ ] dotfiles の微調整 - 🚧 常に改善中 -- ~~[ ] Starship に切り替えるかも?(ただし、oh-my-zsh に比べてテーマが少ない)~~ → 今のところ予定なし - -#### 🔮 Discord サーバー - -- ぜひ [Discord](https://discord.com/invite/kool-tech-world)に参加してください! - -### 💖 サポート - -- GitHub のリポジトリにスターを付けてもらえると嬉しいです 🌟 - -- YouTube チャンネル登録もよろしく!→ [YouTube](https://www.youtube.com/@Ja.KooLit) - -- コーヒーや BTC でサポートも歓迎 😊 - -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) - -または - -[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) - -また、BTC での寄付も可能です - -> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i - -![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) - -## 🫰 スターありがとう 🩷 - -[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) diff --git a/README.ro.md b/README.ro.md deleted file mode 100644 index 1a03c936..00000000 --- a/README.ro.md +++ /dev/null @@ -1,194 +0,0 @@ -

- -

- -

- -

- -
- -
- -![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) - -
-
- -

- Sparkles - Prezentarea fișierelor Dotfiles Hyprland ale lui KooL - Sparkles -

- -
- -https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 - -
- -### 📹 Ghiduri video -- la finalul paginii - -### 🎞️ Demo AGS Overview -- în caz că te întrebi, aici este un demo scurt al AGS overview [Link YouTube](https://youtu.be/zY5SLNPBJTs) - - - ---- -[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALARE)](https://git.io/typing-svg) -### 🚩 🏁 Scripturi automate de instalare Hyprland pentru distribuții, clonare și pornire 🇵🇭 -> [!ATENȚIE] -> Dacă folosești FISH SHELL, NU utiliza această funcție. Clonează Distro-Hyprland și rulează install.sh în schimb. - -- NOTĂ: ai nevoie de pachetul `curl` pentru ca aceasta să funcționeze - -```bash -sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) -``` - -- acum poți folosi comanda de mai sus pentru a clona automat scripturile de instalare Distro-Hyprland de mai jos -- va clona scripturile de instalare și va porni `install.sh` 😎 - -### 👁️‍🗨️ Scripturile mele de instalare Hyprland 👁️‍🗨️ -- Scripturi automate Hyprland pentru distribuția aleasă, care vor descărca aceste dotfiles dacă optezi pentru instalarea acestor configurații - -- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) -- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) -- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) -- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) -- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) -- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) -- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) -- [Ubuntu 25.04 - (FAZĂ ALPHA)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) - ---- - -### 🪧 Atenție 🪧 -- Acest repo NU conține și NU va instala niciun pachet. Acestea sunt doar configurații Hyprland pre-configurate sau dotfiles -- consultă scripturile de instalare pentru a vedea ce pachete trebuie instalate... dar cel puțin, pachetele Hyprland sunt necesare 😏😏😏 evident!! -- Acest repo va fi descărcat de scripturile de instalare Distro-Hyprland de mai sus dacă optezi pentru descărcarea dotfiles-urilor pre-configurate - -### 👀 Capturi de ecran 👀 -- Toate capturile de ecran sunt colectate aici [Capturi de ecran](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) - -### 📦 Ce mai e nou? -- Pentru a urmări ușor modificările, voi actualiza [Jurnalul de modificări](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Capturile de ecran vor fi incluse dacă modificările merită menționate! - -> [!NOTĂ] -> Reține că, în mod implicit, dotfiles-urile lui Kool sunt ajustate/configurate pentru afișaje 2k (1440p) fără scalare. - -### 💥 Instrucțiuni de copiere / instalare / actualizare 💥 -- [`MAI MULTE INFORMAȚII AICI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) -> [!Notă] -> Scriptul automat de copiere „copy.sh” va crea copii de rezervă ale directoarelor care urmează să fie copiate. Totuși, este o idee bună să faci manual o copie de rezervă, în caz că scriptul nu reușește să o facă! - -- clonează acest repo folosind git. Schimbă directorul, fă scriptul executabil și rulează-l - -> pentru a descărca din ramura Master -```bash -git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -cd Hyprland-Dots -``` - -> pentru a descărca din ramura Development (dezvoltare și testare) -```bash -git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development -cd Hyprland-Dots -``` - -- copiere/instalare automată a dotfiles-urilor pre-configurate (recomandat pentru actualizări) -```bash -chmod +x copy.sh -./copy.sh -``` - -- pentru a copia/instala din versiuni (stabile) (notă: aceasta este cu o versiune mai veche decât cea din ramura principală) -```bash -chmod +x release.sh -./release.sh -``` - -- Funcția UPGRADE.sh -> [!IMPORTANT] -> Ai nevoie de rsync pentru ca aceasta să funcționeze -> trebuie să ai deja configurat și funcțional Hyprland-ul lui KooL înainte de a folosi această funcție -```bash -chmod +x upgrade.sh -./upgrade.sh -``` - -## ❗❗❗ ATENȚIE PENTRU UTILIZATORII DEBIAN ȘI UBUNTU! -- Primesc o mulțime de mesaje despre actualizarea dotfiles-urilor Hyprland ale lui KooL. Am făcut o notă mare în [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) - -#### ⚠️⚠️⚠️ ATENȚIE - COPII DE REZERVĂ CREATE DE SCRIPT -> [!ATENȚIE] -> copy.sh, release.sh și chiar upgrade.sh creează o copie de rezervă! -> Verifică manual conținutul din $HOME/.config -> Șterge manual toate copiile de rezervă de care nu ai nevoie - -#### 🛎️ o mică notă despre imagini de fundal -- în mod implicit, doar câteva imagini de fundal vor fi copiate (1 pentru modul întunecat și deschis, plus încă 3). Ți se va oferi opțiunea de a descărca mai multe imagini de fundal. Poți previzualiza/verifica imaginile de fundal suplimentare de la [`ACEST`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link - -#### ⚠️⚠️⚠️ OBLIGATORIU! după copierea / instalarea acestor dotfiles -+ Apasă SUPER W și setează o imagine de fundal. Aceasta este și pentru a inițializa wallust pentru temele waybar, kitty (tty) și rofi. Totuși, dacă folosești copy.sh sau release.sh, va exista o imagine de fundal inițială presetată și nu va trebui să faci asta - -+ Proprietari de Nvidia. Asigură-te că editezi `~/.config/hypr/UserConfigs/ENVariables.conf` (foarte recomandat). -- Utilizatori / proprietari de Nvidia, după instalare, verifică [`ACESTA`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) - -+ Dacă ți-ai setat deja propriile comenzi rapide, monitoare etc., doar copiază-le din copia de rezervă creată înainte de a te deconecta sau reporni. (recomandat) - -#### 📖 Probleme cunoscute și posibile soluții -- verifică această pagină [Întrebări frecvente](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) și [PROBLEME NESOLUȚIONATE](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) - -#### 🙋 ÎNTREBĂRI ?!?! ⁉️ -- Întrebări frecvente! Da, poți folosi aceste dotfiles pe alte distribuții! Asigură-te doar că instalezi pachetele corespunzătoare mai întâi! Dacă te face să te simți mai bine, folosesc aceeași configurație pe Gentoo-ul meu :) -- SFAT RAPID! Apasă pe modulul HINT! din Waybar (notă: disponibil doar în layout-urile Waybar implicit și Simple-L [SUS]). Poate fi lansat cu comanda rapidă `SUPER H` -- Mai multe întrebări? click aici pentru a răsfoi acest [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) -- Dacă vrei vechile configurații, acestea sunt colectate în repo-ul meu „Archive”. Vezi [AICI](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) - -#### ⌨ Comenzi rapide -- Comenzi rapide [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) - -#### 🙏 Cerere specială -- Dacă ai îmbunătățiri pentru dotfiles sau configurații, nu ezita să trimiți un PR pentru îmbunătățiri. Întotdeauna primesc cu bucurie îmbunătățiri, deoarece și eu învăț, la fel ca voi! - -#### ✍️ Contribuții -- Vrei să contribui? Click [`AICI`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) pentru un ghid despre cum să contribui - -#### 🤷‍♂️ DE FĂCUT! -- [ ] Ajustarea dotfiles-urilor - 🚧 în progres constant -- ~~[ ] Posibil trecerea la starship? Deși starship are teme limitate comparativ cu oh-my-zsh.~~ fără planuri pentru moment - -#### 🔮 Server Discord -- te invit să te alături serverului meu [Discord](https://discord.com/invite/kool-tech-world) - -#### 💖 Suport -- o stea pe repo-urile mele de Github ar fi minunată 🌟 - -- Abonează-te la canalul meu de YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) - -- de asemenea, poți oferi suport prin cafele sau btc 😊 - -[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) - -sau - -[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) - -Sau poți dona criptomonede pe portofelul meu btc :) -> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i - -![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) - -## 🫰 Mulțumesc pentru stele 🩷 -[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) \ No newline at end of file diff --git a/i18n/README.de.md b/i18n/README.de.md new file mode 100644 index 00000000..eed9def2 --- /dev/null +++ b/i18n/README.de.md @@ -0,0 +1,230 @@ +[![en](https://img.shields.io/badge/lang-en-yellow.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.md) +[![jp](https://img.shields.io/badge/lang-jp-blue.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.jp.md) + +

+ +

+ +

+ +

+ +
+ +
+ +![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) + +
+
+ +

+ Sparkles + KooL's Hyprland Dotfiles Showcase + Sparkles +

+ +
+ +https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 + +
+ +### 📹 Ein Video Guide + +- folgt nach der Textanleitung + +### 🎞️ AGS Übersicht DEMO + +- Hier ist eine kurze Demo der AGS [Youtube LINK](https://youtu.be/zY5SLNPBJTs) + + + +--- + +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALLATION)](https://git.io/typing-svg) + +### 🚩 🏁 Distro Hyprland Installationsskripte herunterladen und ausführen + +> [!VORSICHT] +> Wenn du die FISH-SHELL benutzt, VERWENDE diese Funktion NICHT. Klone stattdessen das Distro-Hyprland-Repository und führe install.sh aus. + +- HINWEIS: Das Paket `curl` muss installiert sein, um die Skripte herunterzuladen + +```bash +sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) +``` + +- Mit dem obigen Befehl kannst du jetzt automatisch die Hyprland Installationsskripte herunterladen und ausführen. +- Das Skript wird weitere Installationsskripte klonen und die `install.sh` starten. 😎 + +### 👁️‍🗨️ Meine Hyprland-Installationsskripte 👁️‍🗨️ + +- Automatisierte Hyprland-Skripte für ein Distro deiner Wahl. Diese Skripte laden, wenn ben;tigt, meine vorkonfigurierten Dotfiles +- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) + +- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) + +- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) + +- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) + +- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) + +- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) +- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) +- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + +--- + +### 🪧 Achtung 🪧 + +- Dieses Repository enthält keine Pakete und wird keine Pakete installieren. Es enthält nur vorkonfigurierte Hyprland-Configs/Dotfiles. +- In den Installationsskripten kann man die benötigten Pakete finden. Zumindest müssen aber die Hyprland-Pakete installiert sein 😏😏😏 logisch!! +- Dieses Repository wird von den oben beschriebenen Distro Hyprland-Installationsskripten heruntergeladen, wenn du dich entscheidest, die vorkonfigurierten Dotfiles verwenden zu wollen. + +### 👀 Screenshots 👀 + +- Beispiel Screenshots findest du hier [Screenshots](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) + +### 📦 Whats new? + +- Um Änderungen leicht nachzuvollziehen, werde ich die [CHANGELOGS](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) regelmäßig aktualisieren. Es werden neue Screenshots hinzugefügt, wenn die Änderungen erwähnenswert sind! + +> [!NOTE] +> Bitte beachte, dass Kools Dots standardmäßig für einen 2K (1440p) Monitor ohne Skalierung angepasst und konfiguriert sind. + +### 💥 Kopieren / Installation / Update-Anleitung 💥 + +- [`Weiter Infos hier`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + > [!Note] + > Das Kopierskript "copy.sh" erstellt Backups der zu kopierenden Konfigurationsverzeichnisse. Sollte das Skript fehlschlagen, empfiehlt es sich, manuell ein Backup zu erstellen. +- Klone das Repository mit Git, wechsle in das Verzeichnis, mache die Datei ausführbar und führe das Skript aus: + +> Um den Master-Branch herunterzuladen + +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git +cd Hyprland-Dots +``` + +> Um den Entwicklungs-Branch (Development & Testing) herunterzuladen: + +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development +cd Hyprland-Dots +``` + +- Automatisiertes Kopieren und Installieren der vorkonfigurierten Dotfiles (empfohlen für Updates): + +```bash +chmod +x copy.sh +./copy.sh +``` + +- Kopieren und Installieren aus den Releases (stable) (beachte, dass dies eine Version älter als "main" ist): + +```bash +chmod +x release.sh +./release.sh +``` + +- UPGRADE.sh für ein Versionsupgrade + > [!IMPORTANT] + > rsync wird benötigt, damit es funktioniert. + > KooL's Hyprland sollte bereits laufen, bevor du dieses Skript verwendest. + +```bash +chmod +x upgrade.sh +./upgrade.sh +``` + +## ❗❗❗ DEBIAN AND UBUNTU INFORMATION! + +- Ich bekomme eine große Menge an Nachrichten über das Updaten eurer KooL Hyprland dotfiles. Es gibt dazu eine Info im [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + +#### ⚠️⚠️⚠️ ACHTUNG - SKRIPT-ERSTELLTE BACKUPS + +> [!CAUTION] +> copy.sh, release.sh und auch upgrade.sh erstellen Backups! +> Schaue dir bitte manuell den Inhalt deines $HOME/.config Ordners an +> Entferne alle nicht mehr benötigten Backups bitte selbst + +#### 🛎️ kleiner Hinweis zu Hintergrundbildern + +- ständardmäßig werden nur einige Hintergründe kopiert (jeweils 1 dunkeles und helles plus 3 weitere). Dir wird angeboten werden, weitere Hintergrundbilder herunterzuladen. Du kannst dir die verfügbaren Hintergründe [`HIER`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) anschauen. + +#### ⚠️⚠️⚠️ WICHTIG! Nach dem Kopieren / Der Installation der Dotfiles + +- Drücke SUPER W und wähle ein Hintergrundbild. Desweiteren wird hierdurch wallust für waybar, kitty (tty) und die rofi Themes aktiviert. Wenn du copy.sh oder release.sh benutzt hast, wird ein Standard Hintergrund gesetzt sein und die Initialisierung ist bereits gesehen + +- Für Nvidia Benutzer. Stelle sicher, dass du deine `~/.config/hypr/UserConfigs/ENVariables.conf` anpasst (unbedingt empfohlen). + +* Für NVIDIA Benutzer, schaue dir diese Informationen [`HIER`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) an. + +- Wenn die bereits deine Keybinds, Monitoren, usw. eingestellt hast... Kopiere die Einstellungen von dem Backup vor dem Logout / Reboot. (empfohlen) + +#### 📖 Bekannte Probleme und mögliche Lösungen + +- Schau dir diese Seite an [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) und checke die [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) + +#### 🙋 FRAGEN ?!?! ⁉️ + +- FAQ! Die Dotfiles funktionieren auch auf anderen Distros! Stelle nur sicher, die richtigen Pakete vorher zu installieren! Falls du dich dann besser fühlst, ich benutze die selbe Konfiguration für mein Gentoo:) +- KLEINER HINWEIS! Klicke auf das HINT! Waybar Modul (Notiz, nur in Waybar default und Simple-L [TOP] Layout verfügbar). Kann auch mit der Tastenkombination `SUPER H` gestartet werden +- Weitere Fragen? Klicke hier um das [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) zu durchstöbern. +- Falls du eine ältere Version der Konfiguration haben möchtest, sind diese in meinem "Archive" Repository verfügbar. Siehe [HIER](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) + +#### ⌨ Keybinds + +- Keybinds [`KLICKE`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) + +#### 🙏 Hilfe gebraucht + +- Wenn du Verbesserungen der Dotfiles oder Konfigurationen hast, mache gerne einen PR für die Verbesserung. Ich heiße Verbesserungen immer Willkommen, da ich genau wie ihr Alle immer viel Neues lerne. + +#### ✍️ Contributing + +- Möchtest du contributen? Klicke [`HIER`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) für eine Anleitung. + +#### 🤷‍♂️ TO DO! + +- [ ] Dotfiles verbesser - 🚧 in ständiger Entwicklung +- ~~[ ] Vielleicht zu starship wechseln. Jedoch limitiere Themes im Vergleich zu oh-my-zsh.~~ momentan nicht geplant + +#### 🔮 Discord Server + +- Bitte joine meinem [Discord](https://discord.com/invite/kool-tech-world) + +#### 💖 Unterstützung + +- ein Star auf meinen Github repos wäre nett 🌟 + +- Abbonieren meinen Youtube Kanal [YouTube](https://www.youtube.com/@Ja.KooLit) + +- du kannst mich auch mit Kaffees oder BTC unterstützen 😊 + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) + +oder + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) + +Oder du kannst auch Krypto an meine btc wallet spenden :) + +> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i + +![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) + +## 🫰 Vielen Dank für die stars 🩷 + +[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) diff --git a/i18n/README.jp.md b/i18n/README.jp.md new file mode 100644 index 00000000..84d64692 --- /dev/null +++ b/i18n/README.jp.md @@ -0,0 +1,228 @@ +[![en](https://img.shields.io/badge/lang-en-yellow.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.md) +[![de](https://img.shields.io/badge/lang-de-green.svg)](https://github.com/JaKooLit/Hyprland-Dots/blob/main/README.de.md) + +

+ +

+ +

+ +

+ +
+ +
+ +![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) + +
+
+ +

+ Sparkles + KooL's Hyprland Dotfiles Showcase + Sparkles +

+ +
+ +https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 + +
+ +### 📹 動画による説明 + +- ページの下部へ + +### 🎞️ AGS概要デモ + +- 概要が気になる場合は、こちらにAGS概要の短いデモがあります [Youtube リンク](https://youtu.be/zY5SLNPBJTs) + + + +--- + +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALLATION)](https://git.io/typing-svg) + +### 🚩 🏁 自動化された Distro-Hyprland のインストールスクリプトのクローンと起動 🇵🇭 + +> [注意!] +> FISH SHELLを使用している場合、この関数を使わないでください。代わりにDistro-Hyprlandをクローンしinstall.shを実行してください。 + +- 重要:これを動作させるには、`curl` パッケージが必要です。 + +```bash +sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) +``` + +- 上記のコマンドを使用して、Distro-Hyprland のインストールスクリプトを自動的にクローンできます。 +- インストールスクリプトをクローンし、`install.sh` を実行します😎 + +### 👁️‍🗨️ 私の Hyprland のインストールスクリプト 👁️‍🗨️ + +- 選択したディストロ向けの自動化された Hyprland スクリプトです。これらの設定をインストールするオプションを選択した場合、対応する dotfiles を取得します。 + +- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) + +- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) + +- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) + +- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) + +- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) + +- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) +- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) +- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + +--- + +### 🪧 注意 🪧 + +- このリポジトリにはパッケージは含まれておらず、インストールもされません。含まれているのは、あらかじめ設定された Hyprland の設定ファイルや dotfiles のみです。 +- 必要なパッケージについてはインストールスクリプトを参照してください。ただし、少なくとも Hyprland のパッケージは必須です 😏😏😏 +- このリポジトリは、上記の Distro-Hyprland インストールスクリプトによって、プリセットの dotfiles をダウンロードするオプションを選択した場合に取得されます。 + +### 👀 スクリーンショット 👀 + +- すべてのスクリーンショットはここにまとめられています。 [スクリーンショット](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) + +### 📦 変更点 + +- 変更を簡単に追跡できるよう、[変更ログ](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) 変更が注目に値する場合はスクリーンショットも含めます! + +> [注意!] +> デフォルトでは、Kools Dots はスケーリングなしの 2K (1440p) ディスプレイ向けに調整・設定されています。 + +### 💥 コピー / インストール / アップデート手順 💥 + +- [`ここに詳細を記載しています`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + > [注意!] + > 自動コピーのスクリプトである "copy.sh" は、コピー対象のディレクトリをバックアップします。しかし、スクリプトがバックアップに失敗する可能性もあるため、手動でバックアップを取るのも良い考えです! +- このリポジトリを git でクローンし、ディレクトリを移動して、実行可能にした後、スクリプトを実行してください。 + +> Master ブランチからダウンロードする場合 + +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git +cd Hyprland-Dots +``` + +> 開発ブランチ(Development)からダウンロードする場合(開発およびテスト用) + +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development +cd Hyprland-Dots +``` + +- プリセット dotfiles の自動コピー/インストール(更新推奨) + +```bash +chmod +x copy.sh +./copy.sh +``` + +- リリース版(Stable)からコピー/インストール(メインより 1 バージョン古い点に注意) + +```bash +chmod +x release.sh +./release.sh +``` + +- UPGRADE.sh の関数について + > [重要!] + > これを動作させるには rsync が必要です。 + > この機能を使用する前に、KooL's Hyprland が既に動作している必要があります。 + +```bash +chmod +x upgrade.sh +./upgrade.sh +``` + +## ❗❗❗ DEBIAN および UBUNTU ユーザーへの注意! + +- KooL Hyprland の dotfiles 更新に関するメッセージが大量に届いています。 [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update)に大きく注意書きを記載しました。 + +#### ⚠️⚠️⚠️ スクリプトによって作成されたバックアップについての注意 + +> [超重要!] +> copy.sh、release.sh、そして upgrade.sh もバックアップを作成します! +> $HOME/.config の内容を手動で確認してください。 +> 不要なバックアップは手動で削除してください。 + +#### 🛎️ 壁紙に関するちょっとした注意 + +- デフォルトでは、ダークとライト各 1 枚+3 枚の壁紙のみがコピーされます。追加の壁紙をダウンロードするオプションが提供されます。追加の壁紙は[`THIS`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) リンクからプレビュー/確認できます。 + +#### ⚠️⚠️⚠️これらの dotfiles をコピー / インストールした後の必須事項 + +- SUPER + W を押して壁紙を設定してください。これにより、Waybar、Kitty(TTY)、Rofi のテーマ用に Wallust を初期化できます。ただし、copy.sh または release.sh を使用した場合は、初期壁紙がプリセットされているため、この手順は不要です。 + +- NVIDIA の所有者へ。`~/.config/hypr/UserConfigs/ENVariables.conf`を編集してください(強く推奨)。 + +* NVIDIA の所有者とユーザーへ。 インsトール後に [`THIS`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users)を確認してください。 + +- 既に独自のキー設定やモニター設定を行っている場合は、ログアウトや再起動前に作成されたバックアップからコピーしてください。(推奨) + +#### 📖 既知の問題と可能な解決策 + +- こちらのページを確認してください: [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) & [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) + +#### 🙋 質問対応 ⁉️ + +- FAQ! はい、これらの dotfiles は他のディストロでも使用できます!ただし、適切なパッケージを事前にインストールしてください!安心できるなら、私も Gentoo で同じ設定を使っています :) +- クイックヒント! Waybar モジュールの HINT! をクリックしてください。 (Waybar のデフォルトレイアウトおよび Simple-L [TOP] レイアウトでのみ利用可能)。キーバインドの `SUPER H`でも起動できます。 +- さらに質問がありますか? こちらをクリックして [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/)を参照してください。 +- 旧設定が欲しい場合, すべて "Archive" リポジトリにまとめています。詳しくは[HERE](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive)をご覧ください。 + +#### ⌨ キーバインド + +- キーバインドの説明はこちら: [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) + +#### 🙏 スペシャルリクエスト + +- dotfilesや設定の改善がある場合改善のためのPRをぜひ送ってください!私も皆さんと同じように学んでいるので、改善は大歓迎です! +- Waybar のスタイル(新しいパネルスタイルは微調整が必要)→ ご協力をお願いできますか?🙏 + +#### 🤷‍♂️ TO DO! + +- [ ] dotfiles の微調整 - 🚧 常に改善中 +- ~~[ ] Starship に切り替えるかも?(ただし、oh-my-zsh に比べてテーマが少ない)~~ → 今のところ予定なし + +#### 🔮 Discord サーバー + +- ぜひ [Discord](https://discord.com/invite/kool-tech-world)に参加してください! + +### 💖 サポート + +- GitHub のリポジトリにスターを付けてもらえると嬉しいです 🌟 + +- YouTube チャンネル登録もよろしく!→ [YouTube](https://www.youtube.com/@Ja.KooLit) + +- コーヒーや BTC でサポートも歓迎 😊 + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) + +または + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) + +また、BTC での寄付も可能です + +> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i + +![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) + +## 🫰 スターありがとう 🩷 + +[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) diff --git a/i18n/README.ro.md b/i18n/README.ro.md new file mode 100644 index 00000000..1a03c936 --- /dev/null +++ b/i18n/README.ro.md @@ -0,0 +1,194 @@ +

+ +

+ +

+ +

+ +
+ +
+ +![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) + +
+
+ +

+ Sparkles + Prezentarea fișierelor Dotfiles Hyprland ale lui KooL + Sparkles +

+ +
+ +https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 + +
+ +### 📹 Ghiduri video +- la finalul paginii + +### 🎞️ Demo AGS Overview +- în caz că te întrebi, aici este un demo scurt al AGS overview [Link YouTube](https://youtu.be/zY5SLNPBJTs) + + + +--- +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=INSTALARE)](https://git.io/typing-svg) +### 🚩 🏁 Scripturi automate de instalare Hyprland pentru distribuții, clonare și pornire 🇵🇭 +> [!ATENȚIE] +> Dacă folosești FISH SHELL, NU utiliza această funcție. Clonează Distro-Hyprland și rulează install.sh în schimb. + +- NOTĂ: ai nevoie de pachetul `curl` pentru ca aceasta să funcționeze + +```bash +sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) +``` + +- acum poți folosi comanda de mai sus pentru a clona automat scripturile de instalare Distro-Hyprland de mai jos +- va clona scripturile de instalare și va porni `install.sh` 😎 + +### 👁️‍🗨️ Scripturile mele de instalare Hyprland 👁️‍🗨️ +- Scripturi automate Hyprland pentru distribuția aleasă, care vor descărca aceste dotfiles dacă optezi pentru instalarea acestor configurații + +- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) +- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) +- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) +- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) +- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) +- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) +- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) +- [Ubuntu 25.04 - (FAZĂ ALPHA)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + +--- + +### 🪧 Atenție 🪧 +- Acest repo NU conține și NU va instala niciun pachet. Acestea sunt doar configurații Hyprland pre-configurate sau dotfiles +- consultă scripturile de instalare pentru a vedea ce pachete trebuie instalate... dar cel puțin, pachetele Hyprland sunt necesare 😏😏😏 evident!! +- Acest repo va fi descărcat de scripturile de instalare Distro-Hyprland de mai sus dacă optezi pentru descărcarea dotfiles-urilor pre-configurate + +### 👀 Capturi de ecran 👀 +- Toate capturile de ecran sunt colectate aici [Capturi de ecran](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) + +### 📦 Ce mai e nou? +- Pentru a urmări ușor modificările, voi actualiza [Jurnalul de modificări](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Capturile de ecran vor fi incluse dacă modificările merită menționate! + +> [!NOTĂ] +> Reține că, în mod implicit, dotfiles-urile lui Kool sunt ajustate/configurate pentru afișaje 2k (1440p) fără scalare. + +### 💥 Instrucțiuni de copiere / instalare / actualizare 💥 +- [`MAI MULTE INFORMAȚII AICI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +> [!Notă] +> Scriptul automat de copiere „copy.sh” va crea copii de rezervă ale directoarelor care urmează să fie copiate. Totuși, este o idee bună să faci manual o copie de rezervă, în caz că scriptul nu reușește să o facă! + +- clonează acest repo folosind git. Schimbă directorul, fă scriptul executabil și rulează-l + +> pentru a descărca din ramura Master +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git +cd Hyprland-Dots +``` + +> pentru a descărca din ramura Development (dezvoltare și testare) +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development +cd Hyprland-Dots +``` + +- copiere/instalare automată a dotfiles-urilor pre-configurate (recomandat pentru actualizări) +```bash +chmod +x copy.sh +./copy.sh +``` + +- pentru a copia/instala din versiuni (stabile) (notă: aceasta este cu o versiune mai veche decât cea din ramura principală) +```bash +chmod +x release.sh +./release.sh +``` + +- Funcția UPGRADE.sh +> [!IMPORTANT] +> Ai nevoie de rsync pentru ca aceasta să funcționeze +> trebuie să ai deja configurat și funcțional Hyprland-ul lui KooL înainte de a folosi această funcție +```bash +chmod +x upgrade.sh +./upgrade.sh +``` + +## ❗❗❗ ATENȚIE PENTRU UTILIZATORII DEBIAN ȘI UBUNTU! +- Primesc o mulțime de mesaje despre actualizarea dotfiles-urilor Hyprland ale lui KooL. Am făcut o notă mare în [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + +#### ⚠️⚠️⚠️ ATENȚIE - COPII DE REZERVĂ CREATE DE SCRIPT +> [!ATENȚIE] +> copy.sh, release.sh și chiar upgrade.sh creează o copie de rezervă! +> Verifică manual conținutul din $HOME/.config +> Șterge manual toate copiile de rezervă de care nu ai nevoie + +#### 🛎️ o mică notă despre imagini de fundal +- în mod implicit, doar câteva imagini de fundal vor fi copiate (1 pentru modul întunecat și deschis, plus încă 3). Ți se va oferi opțiunea de a descărca mai multe imagini de fundal. Poți previzualiza/verifica imaginile de fundal suplimentare de la [`ACEST`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link + +#### ⚠️⚠️⚠️ OBLIGATORIU! după copierea / instalarea acestor dotfiles ++ Apasă SUPER W și setează o imagine de fundal. Aceasta este și pentru a inițializa wallust pentru temele waybar, kitty (tty) și rofi. Totuși, dacă folosești copy.sh sau release.sh, va exista o imagine de fundal inițială presetată și nu va trebui să faci asta + ++ Proprietari de Nvidia. Asigură-te că editezi `~/.config/hypr/UserConfigs/ENVariables.conf` (foarte recomandat). +- Utilizatori / proprietari de Nvidia, după instalare, verifică [`ACESTA`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) + ++ Dacă ți-ai setat deja propriile comenzi rapide, monitoare etc., doar copiază-le din copia de rezervă creată înainte de a te deconecta sau reporni. (recomandat) + +#### 📖 Probleme cunoscute și posibile soluții +- verifică această pagină [Întrebări frecvente](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) și [PROBLEME NESOLUȚIONATE](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) + +#### 🙋 ÎNTREBĂRI ?!?! ⁉️ +- Întrebări frecvente! Da, poți folosi aceste dotfiles pe alte distribuții! Asigură-te doar că instalezi pachetele corespunzătoare mai întâi! Dacă te face să te simți mai bine, folosesc aceeași configurație pe Gentoo-ul meu :) +- SFAT RAPID! Apasă pe modulul HINT! din Waybar (notă: disponibil doar în layout-urile Waybar implicit și Simple-L [SUS]). Poate fi lansat cu comanda rapidă `SUPER H` +- Mai multe întrebări? click aici pentru a răsfoi acest [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) +- Dacă vrei vechile configurații, acestea sunt colectate în repo-ul meu „Archive”. Vezi [AICI](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) + +#### ⌨ Comenzi rapide +- Comenzi rapide [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) + +#### 🙏 Cerere specială +- Dacă ai îmbunătățiri pentru dotfiles sau configurații, nu ezita să trimiți un PR pentru îmbunătățiri. Întotdeauna primesc cu bucurie îmbunătățiri, deoarece și eu învăț, la fel ca voi! + +#### ✍️ Contribuții +- Vrei să contribui? Click [`AICI`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) pentru un ghid despre cum să contribui + +#### 🤷‍♂️ DE FĂCUT! +- [ ] Ajustarea dotfiles-urilor - 🚧 în progres constant +- ~~[ ] Posibil trecerea la starship? Deși starship are teme limitate comparativ cu oh-my-zsh.~~ fără planuri pentru moment + +#### 🔮 Server Discord +- te invit să te alături serverului meu [Discord](https://discord.com/invite/kool-tech-world) + +#### 💖 Suport +- o stea pe repo-urile mele de Github ar fi minunată 🌟 + +- Abonează-te la canalul meu de YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) + +- de asemenea, poți oferi suport prin cafele sau btc 😊 + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) + +sau + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) + +Sau poți dona criptomonede pe portofelul meu btc :) +> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i + +![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) + +## 🫰 Mulțumesc pentru stele 🩷 +[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) \ No newline at end of file -- cgit v1.2.3 From 7752a0c34d52d27909f674c609192a8b2467f97e Mon Sep 17 00:00:00 2001 From: CristianSw <60692725+CristianSw@users.noreply.github.com> Date: Fri, 6 Jun 2025 12:06:36 +0300 Subject: Added additional translation to cover all region languages Added: - Russian Translation - Ukrainian Translation --- i18n/README.ru.markdown | 194 ++++++++++++++++++++++++++++++++++++++++++++++++ i18n/README.uk.markdown | 194 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 388 insertions(+) create mode 100644 i18n/README.ru.markdown create mode 100644 i18n/README.uk.markdown diff --git a/i18n/README.ru.markdown b/i18n/README.ru.markdown new file mode 100644 index 00000000..d80a2f53 --- /dev/null +++ b/i18n/README.ru.markdown @@ -0,0 +1,194 @@ +

+ +

+ +

+ +

+ +
+ +
+ +![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) + +
+
+ +

+ Sparkles + Демонстрация Dotfiles Hyprland от KooL + Sparkles +

+ +
+ +https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 + +
+ +### 📹 Видеообзоры +- в конце страницы + +### 🎞️ Демо AGS Overview +- если интересно, вот короткое демо AGS overview [Ссылка на YouTube](https://youtu.be/zY5SLNPBJTs) + + + +--- +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=УСТАНОВКА)](https://git.io/typing-svg) +### 🚩 🏁 Автоматические скрипты установки Hyprland для дистрибутивов, клонирование и запуск 🇵🇭 +> [!ВНИМАНИЕ] +> Если вы используете FISH SHELL, НЕ используйте эту функцию. Вместо этого клонируйте Distro-Hyprland и запустите install.sh. + +- ПРИМЕЧАНИЕ: для работы требуется пакет `curl` + +```bash +sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) +``` + +- теперь вы можете использовать приведённую выше команду для автоматического клонирования скриптов установки Distro-Hyprland, указанных ниже +- она клонирует скрипты установки и запускает `install.sh` 😎 + +### 👁️‍🗨️ Мои скрипты установки Hyprland 👁️‍🗨️ +- Автоматические скрипты Hyprland для выбранного дистрибутива, которые загрузят эти dotfiles, если вы выберете установку этих конфигураций + +- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) +- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) +- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) +- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) +- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) +- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) +- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) +- [Ubuntu 25.04 - (АЛЬФА-СТАДИЯ)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + +--- + +### 🪧 Внимание 🪧 +- Этот репозиторий НЕ содержит и НЕ устанавливает пакеты. Это только предварительно настроенные конфигурации Hyprland или dotfiles +- обратитесь к скриптам установки, чтобы узнать, какие пакеты нужно установить... но, как минимум, пакеты Hyprland необходимы 😏😏😏 очевидно!! +- Этот репозиторий будет загружен скриптами установки Distro-Hyprland, указанными выше, если вы выберете загрузку предварительно настроенных dotfiles + +### 👀 Скриншоты 👀 +- Все скриншоты собраны здесь [Скриншоты](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) + +### 📦 Что нового? +- Чтобы легко отслеживать изменения, я буду обновлять [Журнал изменений](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Скриншоты будут включены, если изменения заслуживают упоминания! + +> [!ПРИМЕЧАНИЕ] +> Обратите внимание, что по умолчанию dotfiles от KooL настроены для дисплеев 2k (1440p) без масштабирования. + +### 💥 Инструкции по копированию / установке / обновлению 💥 +- [`БОЛЬШЕ ИНФОРМАЦИИ ЗДЕСЬ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +> [!Примечание] +> Автоматический скрипт копирования „copy.sh“ создаёт резервные копии директорий, которые будут скопированы. Тем не менее, рекомендуется сделать резервную копию вручную на случай, если скрипт не сможет этого сделать! + +- клонируйте этот репозиторий с помощью git. Перейдите в директорию, сделайте скрипт исполняемым и запустите его + +> для загрузки из ветки Master +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git +cd Hyprland-Dots +``` + +> для загрузки из ветки Development (разработка и тестирование) +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development +cd Hyprland-Dots +``` + +- автоматическое копирование/установка предварительно настроенных dotfiles (рекомендуется для обновлений) +```bash +chmod +x copy.sh +./copy.sh +``` + +- для копирования/установки из релизов (стабильные) (примечание: это на одну версию старше, чем в основной ветке) +```bash +chmod +x release.sh +./release.sh +``` + +- Функция UPGRADE.sh +> [!ВАЖНО] +> Для работы требуется rsync +> у вас уже должен быть настроен и запущен Hyprland от KooL перед использованием этой функции +```bash +chmod +x upgrade.sh +./upgrade.sh +``` + +## ❗❗❗ ВНИМАНИЕ ДЛЯ ПОЛЬЗОВАТЕЛЕЙ DEBIAN И UBUNTU! +- Я получаю огромное количество сообщений об обновлении dotfiles Hyprland от KooL. Я сделал большую заметку в [`ВИКИ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + +#### ⚠️⚠️⚠️ ВНИМАНИЕ - РЕЗЕРВНЫЕ КОПИИ, СОЗДАННЫЕ СКРИПТОМ +> [!ВНИМАНИЕ] +> copy.sh, release.sh и даже upgrade.sh создают резервную копию! +> Проверьте содержимое в $HOME/.config вручную +> Удалите вручную все ненужные резервные копии + +#### 🛎️ Небольшое замечание об обоях +- по умолчанию копируется только несколько обоев (по 1 для тёмного и светлого режима, плюс ещё 3). Вам будет предложено загрузить дополнительные обои. Вы можете просмотреть/проверить дополнительные обои по [`ЭТОЙ`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) ссылке + +#### ⚠️⚠️⚠️ ОБЯЗАТЕЛЬНО! после копирования / установки этих dotfiles ++ Нажмите SUPER W и установите обои. Это также необходимо для инициализации wallust для тем waybar, kitty (tty) и rofi. Однако, если вы используете copy.sh или release.sh, начальные обои уже будут установлены, и этого делать не придётся + ++ Владельцы Nvidia. Обязательно отредактируйте `~/.config/hypr/UserConfigs/ENVariables.conf` (настоятельно рекомендуется). +- Пользователи / владельцы Nvidia, после установки проверьте [`ЭТО`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) + ++ Если вы уже настроили свои горячие клавиши, мониторы и т.д., просто скопируйте их из созданной резервной копии перед выходом из системы или перезагрузкой. (рекомендуется) + +#### 📖 Известные проблемы и возможные решения +- ознакомьтесь с этой страницей [Часто задаваемые вопросы](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) и [НЕРЕШЁННЫЕ ПРОБЛЕМЫ](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) + +#### 🙋 ВОПРОСЫ ?!?! ⁉️ +- Часто задаваемые вопросы! Да, вы можете использовать эти dotfiles на других дистрибутивах! Просто убедитесь, что сначала установлены соответствующие пакеты! Если вам от этого легче, я использую ту же конфигурацию на моём Gentoo :) +- БЫСТРЫЙ СОВЕТ! Нажмите на модуль HINT! в Waybar (примечание: доступно только в стандартном и Simple-L [ВЕРХНЕМ] макете Waybar). Можно запустить с помощью горячей клавиши `SUPER H` +- Ещё вопросы? щёлкните здесь, чтобы просмотреть эту [ВИКИ](https://github.com/JaKooLit/Hyprland-Dots/wiki/) +- Если вам нужны старые конфигурации, они собраны в моём репозитории „Archive“. Смотрите [ЗДЕСЬ](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) + +#### ⌨ Горячие клавиши +- Горячие клавиши [`ЩЁЛКНИТЕ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) + +#### 🙏 Особая просьба +- Если у вас есть улучшения для dotfiles или конфигураций, не стесняйтесь отправить PR для улучшений. Я всегда приветствую улучшения, так как тоже учусь, как и вы! + +#### ✍️ Вклад +- Хотите внести вклад? Щёлкните [`ЗДЕСЬ`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) для руководства по внесению вклада + +#### 🤷‍♂️ ЧТО ДЕЛАТЬ! +- [ ] Настройка dotfiles - 🚧 в постоянном прогрессе +- ~~[ ] Возможно, переход на starship? Хотя у starship ограниченные темы по сравнению с oh-my-zsh.~~ пока планов нет + +#### 🔮 Сервер Discord +- приглашаю присоединиться к моему [Discord](https://discord.com/invite/kool-tech-world) + +#### 💖 Поддержка +- звезда на моих репозиториях GitHub была бы замечательной 🌟 + +- Подпишитесь на мой канал YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) + +- также вы можете поддержать через кофе или btc 😊 + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) + +или + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) + +Или вы можете пожертвовать криптовалюту на мой btc-кошелёк :) +> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i + +![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) + +## 🫰 Спасибо за звёзды 🩷 +[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) \ No newline at end of file diff --git a/i18n/README.uk.markdown b/i18n/README.uk.markdown new file mode 100644 index 00000000..04d6ad27 --- /dev/null +++ b/i18n/README.uk.markdown @@ -0,0 +1,194 @@ +

+ +

+ +

+ +

+ +
+ +
+ +![GitHub Repo stars](https://img.shields.io/github/stars/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) ![GitHub last commit](https://img.shields.io/github/last-commit/JaKooLit/Hyprland-Dots?style=for-the-badge&color=b4befe) ![GitHub repo size](https://img.shields.io/github/repo-size/JaKooLit/Hyprland-Dots?style=for-the-badge&color=cba6f7) + +
+
+ +

+ Sparkles + Презентація Dotfiles Hyprland від KooL + Sparkles +

+ +
+ +https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 + +
+ +### 📹 Відеоогляди +- у кінці сторінки + +### 🎞️ Демо AGS Overview +- якщо вам цікаво, ось коротке демо AGS overview [Посилання на YouTube](https://youtu.be/zY5SLNPBJTs) + + + +--- +[![Typing SVG](https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=700&size=22&pause=1000&color=F7077E&vCenter=true&width=435&height=30&lines=ВСТАНОВЛЕННЯ)](https://git.io/typing-svg) +### 🚩 🏁 Автоматичні скрипти встановлення Hyprland для дистрибутивів, клонування та запуск 🇵🇭 +> [!УВАГА] +> Якщо ви використовуєте FISH SHELL, НЕ використовуйте цю функцію. Натомість клонуйте Distro-Hyprland і запустіть install.sh. + +- ПРИМІТКА: для роботи потрібен пакет `curl` + +```bash +sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distro-Hyprland.sh) +``` + +- тепер ви можете використовувати наведену вище команду для автоматичного клонування скриптів встановлення Distro-Hyprland, зазначених нижче +- вона клонує скрипти встановлення та запускає `install.sh` 😎 + +### 👁️‍🗨️ Мої скрипти встановлення Hyprland 👁️‍🗨️ +- Автоматичні скрипти Hyprland для обраного дистрибутива, які завантажать ці dotfiles, якщо ви оберете встановлення цих конфігурацій + +- [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) +- [OpenSUSE(Tumbleweed)](https://github.com/JaKooLit/OpenSuse-Hyprland) +- [Fedora-Linux](https://github.com/JaKooLit/Fedora-Hyprland) +- [Debian-Linux (Trixie & SID)](https://github.com/JaKooLit/Debian-Hyprland) +- [NixOS](https://github.com/JaKooLit/NixOS-Hyprland) +- [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) +- [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) +- [Ubuntu 25.04 - (АЛЬФА-ЕТАП)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) + +--- + +### 🪧 Увага 🪧 +- Цей репозиторій НЕ містить і НЕ встановлює жодних пакетів. Це лише попередньо налаштовані конфігурації Hyprland або dotfiles +- зверніться до скриптів встановлення, щоб дізнатися, які пакети потрібно встановити... але принаймні пакети Hyprland потрібні 😏😏😏 очевидно!! +- Цей репозиторій буде завантажено скриптами встановлення Distro-Hyprland, зазначеними вище, якщо ви оберете завантаження попередньо налаштованих dotfiles + +### 👀 Скріншоти 👀 +- Усі скріншоти зібрано тут [Скріншоти](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) + +### 📦 Що нового? +- Щоб легко відстежувати зміни, я оновлюватиму [Журнал змін](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs). Скріншоти будуть додані, якщо зміни варті згадки! + +> [!ПРИМІТКА] +> Зверніть увагу, що за замовчуванням dotfiles від KooL налаштовані для дисплеїв 2k (1440p) без масштабування. + +### 💥 Інструкції з копіювання / встановлення / оновлення 💥 +- [`БІЛЬШЕ ІНФОРМАЦІЇ ТУТ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +> [!Примітака] +> Автоматичний скрипт копіювання „copy.sh“ створює резервні копії директорій, які будуть скопійовані. Проте рекомендується зробити резервну копію вручну на випадок, якщо скрипт не зможе цього зробити! + +- клонуйте цей репозиторій за допомогою git. Перейдіть до директорії, зробіть скрипт виконуваним і запустіть його + +> для завантаження з гілки Master +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git +cd Hyprland-Dots +``` + +> для завантаження з гілки Development (розробка та тестування) +```bash +git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development +cd Hyprland-Dots +``` + +- автоматичне копіювання/встановлення попередньо налаштованих dotfiles (рекомендується для оновлень) +```bash +chmod +x copy.sh +./copy.sh +``` + +- для копіювання/встановлення з релізів (стабільні) (примітка: це на одну версію старше, ніж у основній гілці) +```bash +chmod +x release.sh +./release.sh +``` + +- Функція UPGRADE.sh +> [!ВАЖЛИВО] +> Для роботи потрібен rsync +> у вас уже має бути налаштований і запущений Hyprland від KooL перед використанням цієї функції +```bash +chmod +x upgrade.sh +./upgrade.sh +``` + +## ❗❗❗ УВАГА ДЛЯ КОРИСТУВАЧІВ DEBIAN ТА UBUNTU! +- Я отримую величезну кількість повідомлень щодо оновлення dotfiles Hyprland від KooL. Я зробив велику примітку у [`ВІКІ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + +#### ⚠️⚠️⚠️ УВАГА - РЕЗЕРВНІ КОПІЇ, СТВОРЕНІ СКРИПТОМ +> [!УВАГА] +> copy.sh, release.sh і навіть upgrade.sh створюють резервну копію! +> Перевірте вміст у $HOME/.config вручну +> Видаліть вручну всі непотрібні резервні копії + +#### 🛎️ Невелика примітка про шпалери +- за замовчуванням копіюється лише кілька шпалер (по 1 для темного та світлого режиму, плюс ще 3). Вам буде запропоновано завантажити додаткові шпалери. Ви можете переглянути/перевірити додаткові шпалери за [`ЦИМ`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) посиланням + +#### ⚠️⚠️⚠️ ОБОВ’ЯЗКОВО! після копіювання / встановлення цих dotfiles ++ Натисніть SUPER W і встановіть шпалери. Це також необхідно для ініціалізації wallust для тем waybar, kitty (tty) і rofi. Однак, якщо ви використовуєте copy.sh або release.sh, початкові шпалери вже будуть встановлені, і цього робити не доведеться + ++ Власники Nvidia. Обов’язково відредагуйте `~/.config/hypr/UserConfigs/ENVariables.conf` (настійно рекомендується). +- Користувачі / власники Nvidia, після встановлення перевірте [`ЦЕ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) + ++ Якщо ви вже налаштували власні гарячі клавіші, монітори тощо, просто скопіюйте їх із створеної резервної копії перед виходом із системи або перезавантаженням. (рекомендується) + +#### 📖 Відомі проблеми та можливі рішення +- перегляньте цю сторінку [Поширені запитання](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) та [НЕРОЗВ’ЯЗАНІ ПРОБЛЕМИ](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) + +#### 🙋 ЗАПИТАННЯ ?!?! ⁉️ +- Поширені запитання! Так, ви можете використовувати ці dotfiles на інших дистрибутивах! Просто переконайтеся, що спочатку встановлено відповідні пакети! Якщо вам від цього легше, я використовую ту саму конфігурацію на моєму Gentoo :) +- ШВИДКА ПОРАДА! Натисніть на модуль HINT! у Waybar (примітка: доступно лише у стандартному та Simple-L [ВЕРХНЬОМУ] макеті Waybar). Можна запустити за допомогою гарячої клавіші `SUPER H` +- Ще запитання? натисніть тут, щоб переглянути цю [ВІКІ](https://github.com/JaKooLit/Hyprland-Dots/wiki/) +- Якщо вам потрібні старі конфігурації, вони зібрані в моєму репозиторії „Archive“. Дивіться [ТУТ](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) + +#### ⌨ Гарячі клавіші +- Гарячі клавіші [`КЛІКНІТЬ`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) + +#### 🙏 Особливе прохання +- Якщо у вас є покращення для dotfiles або конфігурацій, не соромтеся надіслати PR для покращень. Я завжди вітаю покращення, адже я також вчуся, як і ви! + +#### ✍️ Внесок +- Хочете зробити внесок? Клікніть [`ТУТ`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) для посібника зі внесення внеску + +#### 🤷‍♂️ ЩО РОБИТИ! +- [ ] Налаштування dotfiles - 🚧 у постійному прогресі +- ~~[ ] Можливо, перехід на starship? Хоча у starship обмежені теми порівняно з oh-my-zsh.~~ поки що планів немає + +#### 🔮 Сервер Discord +- запрошую приєднатися до мого [Discord](https://discord.com/invite/kool-tech-world) + +#### 💖 Підтримка +- зірка на моїх репозиторіях GitHub була б чудовою 🌟 + +- Підпишіться на мій канал YouTube [YouTube](https://www.youtube.com/@Ja.KooLit) + +- також ви можете підтримати через каву або btc 😊 + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/jakoolit) + +або + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/JaKooLit) + +Або ви можете пожертвувати криптовалюту на мій btc-гаманець :) +> 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i + +![Bitcoin](https://github.com/user-attachments/assets/7ed32f8f-c499-46f0-a53c-3f6fbd343699) + +## 🫰 Дякую за зірки 🩷 +[![Stargazers over time](https://starchart.cc/JaKooLit/Hyprland-Dots.svg?variant=adaptive)](https://starchart.cc/JaKooLit/Hyprland-Dots) \ No newline at end of file -- cgit v1.2.3 From 952aa63147c9fb28f6ace6f0bc7ccf45ced1299a Mon Sep 17 00:00:00 2001 From: Kiran George Date: Mon, 9 Jun 2025 11:30:08 +0530 Subject: Overview v2 --- config/hypr/UserConfigs/UserKeybinds.conf | 2 +- config/hypr/UserConfigs/WindowRules.conf | 4 + config/quickshell/GlobalStates.qml | 12 + config/quickshell/config.json | 38 ++ config/quickshell/modules/common/Appearance.qml | 214 +++++++ config/quickshell/modules/common/ConfigOptions.qml | 42 ++ config/quickshell/modules/common/Directories.qml | 19 + .../modules/common/functions/color_utils.js | 85 +++ .../modules/common/functions/file_utils.js | 9 + .../modules/common/functions/fuzzysort.js | 682 +++++++++++++++++++++ .../modules/common/functions/levendist.js | 141 +++++ .../modules/common/functions/object_utils.js | 45 ++ .../modules/common/functions/string_utils.js | 188 ++++++ .../modules/common/widgets/CliphistImage.qml | 101 +++ .../modules/common/widgets/DialogButton.qml | 38 ++ .../modules/common/widgets/MaterialSymbol.qml | 30 + .../common/widgets/PointingHandInteraction.qml | 7 + .../modules/common/widgets/RippleButton.qml | 185 ++++++ .../modules/common/widgets/RoundCorner.qml | 64 ++ .../common/widgets/StyledRectangularShadow.qml | 13 + .../modules/common/widgets/StyledText.qml | 14 + .../modules/common/widgets/StyledTextArea.qml | 15 + .../modules/common/widgets/StyledToolTip.qml | 60 ++ config/quickshell/modules/overview/Overview.qml | 279 +++++++++ .../quickshell/modules/overview/OverviewWidget.qml | 341 +++++++++++ .../quickshell/modules/overview/OverviewWindow.qml | 94 +++ config/quickshell/modules/overview/SearchItem.qml | 220 +++++++ .../quickshell/modules/overview/SearchWidget.qml | 425 +++++++++++++ config/quickshell/services/AppSearch.qml | 116 ++++ config/quickshell/services/ConfigLoader.qml | 116 ++++ config/quickshell/services/HyprlandData.qml | 69 +++ config/quickshell/services/HyprlandKeybinds.qml | 73 +++ config/quickshell/services/MaterialThemeLoader.qml | 58 ++ config/quickshell/shell.qml | 27 + config/wallust/templates/qml_color.json | 21 + config/wallust/wallust.toml | 3 + 36 files changed, 3849 insertions(+), 1 deletion(-) create mode 100644 config/quickshell/GlobalStates.qml create mode 100644 config/quickshell/config.json create mode 100644 config/quickshell/modules/common/Appearance.qml create mode 100644 config/quickshell/modules/common/ConfigOptions.qml create mode 100644 config/quickshell/modules/common/Directories.qml create mode 100644 config/quickshell/modules/common/functions/color_utils.js create mode 100644 config/quickshell/modules/common/functions/file_utils.js create mode 100644 config/quickshell/modules/common/functions/fuzzysort.js create mode 100644 config/quickshell/modules/common/functions/levendist.js create mode 100644 config/quickshell/modules/common/functions/object_utils.js create mode 100644 config/quickshell/modules/common/functions/string_utils.js create mode 100644 config/quickshell/modules/common/widgets/CliphistImage.qml create mode 100644 config/quickshell/modules/common/widgets/DialogButton.qml create mode 100644 config/quickshell/modules/common/widgets/MaterialSymbol.qml create mode 100644 config/quickshell/modules/common/widgets/PointingHandInteraction.qml create mode 100644 config/quickshell/modules/common/widgets/RippleButton.qml create mode 100644 config/quickshell/modules/common/widgets/RoundCorner.qml create mode 100644 config/quickshell/modules/common/widgets/StyledRectangularShadow.qml create mode 100644 config/quickshell/modules/common/widgets/StyledText.qml create mode 100644 config/quickshell/modules/common/widgets/StyledTextArea.qml create mode 100644 config/quickshell/modules/common/widgets/StyledToolTip.qml create mode 100644 config/quickshell/modules/overview/Overview.qml create mode 100644 config/quickshell/modules/overview/OverviewWidget.qml create mode 100644 config/quickshell/modules/overview/OverviewWindow.qml create mode 100644 config/quickshell/modules/overview/SearchItem.qml create mode 100644 config/quickshell/modules/overview/SearchWidget.qml create mode 100644 config/quickshell/services/AppSearch.qml create mode 100644 config/quickshell/services/ConfigLoader.qml create mode 100644 config/quickshell/services/HyprlandData.qml create mode 100644 config/quickshell/services/HyprlandKeybinds.qml create mode 100644 config/quickshell/services/MaterialThemeLoader.qml create mode 100644 config/quickshell/shell.qml create mode 100644 config/wallust/templates/qml_color.json diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index ce501d85..c92352fc 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -18,7 +18,7 @@ source= $UserConfigs/01-UserDefaults.conf #bindr = $mainMod, $mainMod_L, exec, pkill rofi || rofi -show drun -modi drun,filebrowser,run,window # Super Key to Launch rofi menu bind = $mainMod, D, exec, pkill rofi || true && rofi -show drun -modi drun,filebrowser,run,window # Main Menu (APP Launcher) bind = $mainMod, B, exec, xdg-open "https://" # default browser -bind = $mainMod, A, exec, pkill rofi || true && ags -t 'overview' # desktop overview (if installed) +bind = $mainMod, A, global, quickshell:overviewToggle # desktop overview (if installed) bind = $mainMod, Return, exec, $term #terminal bind = $mainMod, E, exec, $files #file manager diff --git a/config/hypr/UserConfigs/WindowRules.conf b/config/hypr/UserConfigs/WindowRules.conf index 099cd2c8..4485a8f5 100644 --- a/config/hypr/UserConfigs/WindowRules.conf +++ b/config/hypr/UserConfigs/WindowRules.conf @@ -211,6 +211,10 @@ layerrule = blur, rofi layerrule = ignorezero, rofi layerrule = blur, notifications layerrule = ignorezero, notifications +layerrule = blur, quickshell:overview +layerrule = ignorezero, quickshell:overview +layerrule = ignorealpha 0.5, quickshell:overview + #layerrule = ignorealpha 0.5, tag:notif* #layerrule = ignorezero, class:^([Rr]ofi)$ diff --git a/config/quickshell/GlobalStates.qml b/config/quickshell/GlobalStates.qml new file mode 100644 index 00000000..7875645c --- /dev/null +++ b/config/quickshell/GlobalStates.qml @@ -0,0 +1,12 @@ +import "root:/modules/common/" +import QtQuick +import Quickshell +import Quickshell.Hyprland +import Quickshell.Io +pragma Singleton +pragma ComponentBehavior: Bound + +Singleton { + id: root + property bool overviewOpen: false +} \ No newline at end of file diff --git a/config/quickshell/config.json b/config/quickshell/config.json new file mode 100644 index 00000000..f98f9f69 --- /dev/null +++ b/config/quickshell/config.json @@ -0,0 +1,38 @@ +{ + "ui": { + "theme": "dark", + "scale": 1.25 + }, + "features": { + "animations": true + }, + "appearance": { + "fakeScreenRounding": 1 + }, + "overview": { + "scale": 0.15, + "numOfRows": 2, + "numOfCols": 5, + "showXwaylandIndicator": true, + "windowPadding": 6, + "position": 1 + }, + "resources": { + "updateInterval": 3000 + }, + "hacks": { + "arbitraryRaceConditionDelay": 20 + }, + "search": { + "searchEnabled": false, + "nonAppResultDelay": 30, + "prefix": { + "action": "/", + "clipboard": ";", + "emojis": ":" + } + }, + "bar": { + "bottom": false + } +} \ No newline at end of file diff --git a/config/quickshell/modules/common/Appearance.qml b/config/quickshell/modules/common/Appearance.qml new file mode 100644 index 00000000..45a4894d --- /dev/null +++ b/config/quickshell/modules/common/Appearance.qml @@ -0,0 +1,214 @@ +import QtQuick +import Quickshell +import "root:/modules/common/functions/color_utils.js" as ColorUtils +pragma Singleton +pragma ComponentBehavior: Bound + + +Singleton { + id: root + property QtObject m3colors + property QtObject animation + property QtObject animationCurves + property QtObject colors + property QtObject rounding + property QtObject font + property QtObject sizes + + property real transparency: 0.5 + property real contentTransparency: 0.1 + property real workpaceTransparency: 0.8 + // property real transparency: 0.15 + // property real contentTransparency: 0.5 + property string background_image: "file:///home/itachi/.config/rofi/.current_wallpaper" + + m3colors: QtObject { + property bool darkmode: true + property bool transparent: true + + property color m3background: "#161217" + property color m3onBackground: "#EAE0E7" + property color m3surfaceContainerLow: "#1F1A1F" + property color m3surfaceContainer: "#231E23" + property color m3surfaceContainerHigh: "#2D282E" + property color m3surfaceContainerHighest: "#383339" + property color m3onSurface: "#EAE0E7" + property color m3onSurfaceVariant: "#CFC3CD" + property color m3outline: "#cba6f7" + property color m3scrim: "#000000" + property color m3shadow: "#000000" + property color m3primary: "#E5B6F2" + property color m3primaryContainer: "#5D386A" + property color m3secondary: "#D5C0D7" + property color m3secondaryContainer: "#534457" + property color m3onPrimary: "#452152" + property color m3onPrimaryContainer: "#F9D8FF" + property color m3onSecondaryContainer: "#F2DCF3" + property color m3outlineVariant: "#4C444D" + + property color colTooltip: "#1e1e2e" + property color colOnTooltip: "#F8F9FA" + } + + colors: QtObject { + property color colSubtext: m3colors.m3outline + property color colLayer0: ColorUtils.transparentize(m3colors.m3background, root.transparency) + property color colLayer1: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainerLow, m3colors.m3background, 0.7), root.contentTransparency); + property color colOnLayer1: m3colors.m3onSurfaceVariant; + property color colLayer2: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainer, m3colors.m3surfaceContainerHigh, 0.55), root.contentTransparency) + property color colOnLayer2: m3colors.m3onSurface; + property color colLayer1Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer1, colOnLayer1, 0.92), root.contentTransparency) + property color colLayer1Active: ColorUtils.transparentize(ColorUtils.mix(colLayer1, colOnLayer1, 0.85), root.contentTransparency); + property color colLayer2Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer2, colOnLayer2, 0.90), root.contentTransparency) + property color colLayer2Active: ColorUtils.transparentize(ColorUtils.mix(colLayer2, colOnLayer2, 0.80), root.contentTransparency); + property color colPrimary: m3colors.m3primary + property color colPrimaryHover: ColorUtils.mix(colors.colPrimary, colLayer1Hover, 0.87) + property color colPrimaryActive: ColorUtils.mix(colors.colPrimary, colLayer1Active, 0.7) + property color colShadow: ColorUtils.transparentize(m3colors.m3shadow, 0.7) + } + + rounding: QtObject { + property int unsharpen: 2 + property int verysmall: 8 + property int small: 12 + property int normal: 17 + property int large: 23 + property int verylarge: 30 + property int veryverylarge: 60 + property int full: 9999 + property int screenRounding: veryverylarge + property int windowRounding: veryverylarge + } + + font: QtObject { + property QtObject family: QtObject { + property string main: "Open Sans" + property string title: "JetBrains Mono NF" + property string iconMaterial: "FiraConde Nerd Font" + property string iconNerd: "SpaceMono NF" + property string monospace: "JetBrains Mono NF" + property string reading: "Readex Pro" + } + property QtObject pixelSize: QtObject { + property int smallest: 10 + property int smaller: 13 + property int small: 15 + property int normal: 16 + property int large: 17 + property int larger: 19 + property int huge: 22 + property int hugeass: 23 + property int title: 28 + } + } + + animationCurves: QtObject { + readonly property list expressiveFastSpatial: [0.42, 1.67, 0.21, 0.90, 1, 1] // Default, 350ms + readonly property list expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1.00, 1, 1] // Default, 500ms + readonly property list expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1] // Default, 650ms + readonly property list expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1] // Default, 200ms + readonly property list emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1] + readonly property list emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1] + readonly property list emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1] + readonly property list standard: [0.2, 0, 0, 1, 1, 1] + readonly property list standardAccel: [0.3, 0, 1, 1, 1, 1] + readonly property list standardDecel: [0, 0, 0, 1, 1, 1] + } + + animation: QtObject { + property QtObject elementMove: QtObject { + property int duration: 500 + property int type: Easing.BezierSpline + property list bezierCurve: animationCurves.expressiveDefaultSpatial + property int velocity: 650 + property Component numberAnimation: Component { + NumberAnimation { + duration: root.animation.elementMove.duration + easing.type: root.animation.elementMove.type + easing.bezierCurve: root.animation.elementMove.bezierCurve + } + } + property Component colorAnimation: Component { + ColorAnimation { + duration: root.animation.elementMove.duration + easing.type: root.animation.elementMove.type + easing.bezierCurve: root.animation.elementMove.bezierCurve + } + } + } + property QtObject elementMoveEnter: QtObject { + property int duration: 400 + property int type: Easing.BezierSpline + property list bezierCurve: animationCurves.emphasizedDecel + property int velocity: 650 + property Component numberAnimation: Component { + NumberAnimation { + duration: root.animation.elementMoveEnter.duration + easing.type: root.animation.elementMoveEnter.type + easing.bezierCurve: root.animation.elementMoveEnter.bezierCurve + } + } + } + property QtObject elementMoveExit: QtObject { + property int duration: 200 + property int type: Easing.BezierSpline + property list bezierCurve: animationCurves.emphasizedAccel + property int velocity: 650 + property Component numberAnimation: Component { + NumberAnimation { + duration: root.animation.elementMoveExit.duration + easing.type: root.animation.elementMoveExit.type + easing.bezierCurve: root.animation.elementMoveExit.bezierCurve + } + } + } + property QtObject elementMoveFast: QtObject { + property int duration: 200 + property int type: Easing.BezierSpline + property list bezierCurve: animationCurves.expressiveEffects + property int velocity: 850 + property Component colorAnimation: Component { ColorAnimation { + duration: root.animation.elementMoveFast.duration + easing.type: root.animation.elementMoveFast.type + easing.bezierCurve: root.animation.elementMoveFast.bezierCurve + }} + property Component numberAnimation: Component { NumberAnimation { + duration: root.animation.elementMoveFast.duration + easing.type: root.animation.elementMoveFast.type + easing.bezierCurve: root.animation.elementMoveFast.bezierCurve + }} + } + + property QtObject clickBounce: QtObject { + property int duration: 200 + property int type: Easing.BezierSpline + property list bezierCurve: animationCurves.expressiveFastSpatial + property int velocity: 850 + property Component numberAnimation: Component { NumberAnimation { + duration: root.animation.clickBounce.duration + easing.type: root.animation.clickBounce.type + easing.bezierCurve: root.animation.clickBounce.bezierCurve + }} + } + property QtObject scroll: QtObject { + property int duration: 400 + property int type: Easing.BezierSpline + property list bezierCurve: animationCurves.standardDecel + } + property QtObject menuDecel: QtObject { + property int duration: 350 + property int type: Easing.OutExpo + } + } + + sizes: QtObject { + property real barHeight: 40 + property real notificationPopupWidth: 410 + property real searchWidthCollapsed: 260 + property real searchWidth: 450 + property real hyprlandGapsOut: 5 + property real elevationMargin: 10 + property real fabShadowRadius: 5 + property real fabHoveredShadowRadius: 7 + } +} diff --git a/config/quickshell/modules/common/ConfigOptions.qml b/config/quickshell/modules/common/ConfigOptions.qml new file mode 100644 index 00000000..61e6ab8e --- /dev/null +++ b/config/quickshell/modules/common/ConfigOptions.qml @@ -0,0 +1,42 @@ +import QtQuick +import Quickshell +pragma Singleton +pragma ComponentBehavior: Bound + +Singleton { + + property QtObject appearance: QtObject { + property int fakeScreenRounding: 1 // 0: None | 1: Always | 2: When not fullscreen + } + + property QtObject overview: QtObject { + property real scale: 0.15 // Relative to screen size + property real numOfRows: 2 + property real numOfCols: 5 + property bool showXwaylandIndicator: true + property real windowPadding: 6 + property real position: 1 // 0: top | 1: middle | 2: bottom + } + + property QtObject resources: QtObject { + property int updateInterval: 3000 + } + + property QtObject hacks: QtObject { + property int arbitraryRaceConditionDelay: 20 // milliseconds + } + + property QtObject search: QtObject { + property bool searchEnabled: false + property int nonAppResultDelay: 30 // This prevents lagging when typing + property QtObject prefix: QtObject { + property string action: "/" + property string clipboard: ";" + property string emojis: ":" + } + } + + property QtObject bar: QtObject { + property bool bottom: false // Instead of top + } +} diff --git a/config/quickshell/modules/common/Directories.qml b/config/quickshell/modules/common/Directories.qml new file mode 100644 index 00000000..9ddf43bd --- /dev/null +++ b/config/quickshell/modules/common/Directories.qml @@ -0,0 +1,19 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import "root:/modules/common/functions/file_utils.js" as FileUtils +import Qt.labs.platform +import QtQuick +import Quickshell +import Quickshell.Hyprland + +Singleton { + // XDG Dirs, with "file://" + readonly property string config: StandardPaths.standardLocations(StandardPaths.ConfigLocation)[0] + readonly property string state: StandardPaths.standardLocations(StandardPaths.StateLocation)[0] + + // Other dirs used by the shell, without "file://" + property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/quickshell`) + property string shellConfigPath: `${Directories.shellConfig}/config.json` + property string generatedMaterialThemePath: `${Directories.shellConfig}/qml_color.json` +} diff --git a/config/quickshell/modules/common/functions/color_utils.js b/config/quickshell/modules/common/functions/color_utils.js new file mode 100644 index 00000000..c0ccfda9 --- /dev/null +++ b/config/quickshell/modules/common/functions/color_utils.js @@ -0,0 +1,85 @@ +// This module provides high level utility functions for color manipulation. + +/** + * Returns a color with the hue of color2 and the saturation, value, and alpha of color1. + * + * @param {string} color1 - The base color (any Qt.color-compatible string). + * @param {string} color2 - The color to take hue from. + * @returns {Qt.rgba} The resulting color. + */ +function colorWithHueOf(color1, color2) { + var c1 = Qt.color(color1); + var c2 = Qt.color(color2); + + // Qt.color hsvHue/hsvSaturation/hsvValue/alpha return 0-1 + var hue = c2.hsvHue; + var sat = c1.hsvSaturation; + var val = c1.hsvValue; + var alpha = c1.a; + + return Qt.hsva(hue, sat, val, alpha); +} + +/** + * Returns a color with the saturation of color2 and the hue/value/alpha of color1. + * + * @param {string} color1 - The base color (any Qt.color-compatible string). + * @param {string} color2 - The color to take saturation from. + * @returns {Qt.rgba} The resulting color. + */ +function colorWithSaturationOf(color1, color2) { + var c1 = Qt.color(color1); + var c2 = Qt.color(color2); + + var hue = c1.hsvHue; + var sat = c2.hsvSaturation; + var val = c1.hsvValue; + var alpha = c1.a; + + return Qt.hsva(hue, sat, val, alpha); +} + +/** + * Adapts color1 to the accent (hue and saturation) of color2 using HSL, keeping lightness and alpha from color1. + * + * @param {string} color1 - The base color (any Qt.color-compatible string). + * @param {string} color2 - The accent color. + * @returns {Qt.rgba} The resulting color. + */ +function adaptToAccent(color1, color2) { + var c1 = Qt.color(color1); + var c2 = Qt.color(color2); + + var hue = c2.hslHue; + var sat = c2.hslSaturation; + var light = c1.hslLightness; + var alpha = c1.a; + + return Qt.hsla(hue, sat, light, alpha); +} + +/** + * Mixes two colors by a given percentage. + * + * @param {string} color1 - The first color (any Qt.color-compatible string). + * @param {string} color2 - The second color. + * @param {number} percentage - The mix ratio (0-1). 1 = all color1, 0 = all color2. + * @returns {Qt.rgba} The resulting mixed color. + */ +function mix(color1, color2, percentage) { + var c1 = Qt.color(color1); + var c2 = Qt.color(color2); + return Qt.rgba(percentage * c1.r + (1 - percentage) * c2.r, percentage * c1.g + (1 - percentage) * c2.g, percentage * c1.b + (1 - percentage) * c2.b, percentage * c1.a + (1 - percentage) * c2.a); +} + +/** + * Transparentizes a color by a given percentage. + * + * @param {string} color - The color (any Qt.color-compatible string). + * @param {number} percentage - The amount to transparentize (0-1). + * @returns {Qt.rgba} The resulting color. + */ +function transparentize(color, percentage = 1) { + var c = Qt.color(color); + return Qt.rgba(c.r, c.g, c.b, c.a * (1 - percentage)); +} diff --git a/config/quickshell/modules/common/functions/file_utils.js b/config/quickshell/modules/common/functions/file_utils.js new file mode 100644 index 00000000..758950de --- /dev/null +++ b/config/quickshell/modules/common/functions/file_utils.js @@ -0,0 +1,9 @@ +/** + * Trims the File protocol off the input string + * @param {string} str + * @returns {string} + */ +function trimFileProtocol(str) { + return str.startsWith("file://") ? str.slice(7) : str; +} + diff --git a/config/quickshell/modules/common/functions/fuzzysort.js b/config/quickshell/modules/common/functions/fuzzysort.js new file mode 100644 index 00000000..1c1d9b9d --- /dev/null +++ b/config/quickshell/modules/common/functions/fuzzysort.js @@ -0,0 +1,682 @@ +.pragma library + +// https://github.com/farzher/fuzzysort +// License: MIT | Copyright (c) 2018 Stephen Kamenar +// A copy of the license is available in the `licenses` folder of this repository + +var single = (search, target) => { + if(!search || !target) return NULL + + var preparedSearch = getPreparedSearch(search) + if(!isPrepared(target)) target = getPrepared(target) + + var searchBitflags = preparedSearch.bitflags + if((searchBitflags & target._bitflags) !== searchBitflags) return NULL + + return algorithm(preparedSearch, target) +} + +var go = (search, targets, options) => { + if(!search) return options?.all ? all(targets, options) : noResults + + var preparedSearch = getPreparedSearch(search) + var searchBitflags = preparedSearch.bitflags + var containsSpace = preparedSearch.containsSpace + + var threshold = denormalizeScore( options?.threshold || 0 ) + var limit = options?.limit || INFINITY + + var resultsLen = 0; var limitedCount = 0 + var targetsLen = targets.length + + function push_result(result) { + if(resultsLen < limit) { q.add(result); ++resultsLen } + else { + ++limitedCount + if(result._score > q.peek()._score) q.replaceTop(result) + } + } + + // This code is copy/pasted 3 times for performance reasons [options.key, options.keys, no keys] + + // options.key + if(options?.key) { + var key = options.key + for(var i = 0; i < targetsLen; ++i) { var obj = targets[i] + var target = getValue(obj, key) + if(!target) continue + if(!isPrepared(target)) target = getPrepared(target) + + if((searchBitflags & target._bitflags) !== searchBitflags) continue + var result = algorithm(preparedSearch, target) + if(result === NULL) continue + if(result._score < threshold) continue + + result.obj = obj + push_result(result) + } + + // options.keys + } else if(options?.keys) { + var keys = options.keys + var keysLen = keys.length + + outer: for(var i = 0; i < targetsLen; ++i) { var obj = targets[i] + + { // early out based on bitflags + var keysBitflags = 0 + for (var keyI = 0; keyI < keysLen; ++keyI) { + var key = keys[keyI] + var target = getValue(obj, key) + if(!target) { tmpTargets[keyI] = noTarget; continue } + if(!isPrepared(target)) target = getPrepared(target) + tmpTargets[keyI] = target + + keysBitflags |= target._bitflags + } + + if((searchBitflags & keysBitflags) !== searchBitflags) continue + } + + if(containsSpace) for(let i=0; i -1000) { + if(keysSpacesBestScores[i] > NEGATIVE_INFINITY) { + var tmp = (keysSpacesBestScores[i] + allowPartialMatchScores[i]) / 4/*bonus score for having multiple matches*/ + if(tmp > keysSpacesBestScores[i]) keysSpacesBestScores[i] = tmp + } + } + if(allowPartialMatchScores[i] > keysSpacesBestScores[i]) keysSpacesBestScores[i] = allowPartialMatchScores[i] + } + } + + if(containsSpace) { + for(let i=0; i -1000) { + if(score > NEGATIVE_INFINITY) { + var tmp = (score + result._score) / 4/*bonus score for having multiple matches*/ + if(tmp > score) score = tmp + } + } + if(result._score > score) score = result._score + } + } + + objResults.obj = obj + objResults._score = score + if(options?.scoreFn) { + score = options.scoreFn(objResults) + if(!score) continue + score = denormalizeScore(score) + objResults._score = score + } + + if(score < threshold) continue + push_result(objResults) + } + + // no keys + } else { + for(var i = 0; i < targetsLen; ++i) { var target = targets[i] + if(!target) continue + if(!isPrepared(target)) target = getPrepared(target) + + if((searchBitflags & target._bitflags) !== searchBitflags) continue + var result = algorithm(preparedSearch, target) + if(result === NULL) continue + if(result._score < threshold) continue + + push_result(result) + } + } + + if(resultsLen === 0) return noResults + var results = new Array(resultsLen) + for(var i = resultsLen - 1; i >= 0; --i) results[i] = q.poll() + results.total = resultsLen + limitedCount + return results +} + + +// this is written as 1 function instead of 2 for minification. perf seems fine ... +// except when minified. the perf is very slow +var highlight = (result, open='', close='') => { + var callback = typeof open === 'function' ? open : undefined + + var target = result.target + var targetLen = target.length + var indexes = result.indexes + var highlighted = '' + var matchI = 0 + var indexesI = 0 + var opened = false + var parts = [] + + for(var i = 0; i < targetLen; ++i) { var char = target[i] + if(indexes[indexesI] === i) { + ++indexesI + if(!opened) { opened = true + if(callback) { + parts.push(highlighted); highlighted = '' + } else { + highlighted += open + } + } + + if(indexesI === indexes.length) { + if(callback) { + highlighted += char + parts.push(callback(highlighted, matchI++)); highlighted = '' + parts.push(target.substr(i+1)) + } else { + highlighted += char + close + target.substr(i+1) + } + break + } + } else { + if(opened) { opened = false + if(callback) { + parts.push(callback(highlighted, matchI++)); highlighted = '' + } else { + highlighted += close + } + } + } + highlighted += char + } + + return callback ? parts : highlighted +} + + +var prepare = (target) => { + if(typeof target === 'number') target = ''+target + else if(typeof target !== 'string') target = '' + var info = prepareLowerInfo(target) + return new_result(target, {_targetLower:info._lower, _targetLowerCodes:info.lowerCodes, _bitflags:info.bitflags}) +} + +var cleanup = () => { preparedCache.clear(); preparedSearchCache.clear() } + + +// Below this point is only internal code +// Below this point is only internal code +// Below this point is only internal code +// Below this point is only internal code + + +class Result { + get ['indexes']() { return this._indexes.slice(0, this._indexes.len).sort((a,b)=>a-b) } + set ['indexes'](indexes) { return this._indexes = indexes } + ['highlight'](open, close) { return highlight(this, open, close) } + get ['score']() { return normalizeScore(this._score) } + set ['score'](score) { this._score = denormalizeScore(score) } +} + +class KeysResult extends Array { + get ['score']() { return normalizeScore(this._score) } + set ['score'](score) { this._score = denormalizeScore(score) } +} + +var new_result = (target, options) => { + const result = new Result() + result['target'] = target + result['obj'] = options.obj ?? NULL + result._score = options._score ?? NEGATIVE_INFINITY + result._indexes = options._indexes ?? [] + result._targetLower = options._targetLower ?? '' + result._targetLowerCodes = options._targetLowerCodes ?? NULL + result._nextBeginningIndexes = options._nextBeginningIndexes ?? NULL + result._bitflags = options._bitflags ?? 0 + return result +} + + +var normalizeScore = score => { + if(score === NEGATIVE_INFINITY) return 0 + if(score > 1) return score + return Math.E ** ( ((-score + 1)**.04307 - 1) * -2) +} +var denormalizeScore = normalizedScore => { + if(normalizedScore === 0) return NEGATIVE_INFINITY + if(normalizedScore > 1) return normalizedScore + return 1 - Math.pow((Math.log(normalizedScore) / -2 + 1), 1 / 0.04307) +} + + +var prepareSearch = (search) => { + if(typeof search === 'number') search = ''+search + else if(typeof search !== 'string') search = '' + search = search.trim() + var info = prepareLowerInfo(search) + + var spaceSearches = [] + if(info.containsSpace) { + var searches = search.split(/\s+/) + searches = [...new Set(searches)] // distinct + for(var i=0; i { + if(target.length > 999) return prepare(target) // don't cache huge targets + var targetPrepared = preparedCache.get(target) + if(targetPrepared !== undefined) return targetPrepared + targetPrepared = prepare(target) + preparedCache.set(target, targetPrepared) + return targetPrepared +} +var getPreparedSearch = (search) => { + if(search.length > 999) return prepareSearch(search) // don't cache huge searches + var searchPrepared = preparedSearchCache.get(search) + if(searchPrepared !== undefined) return searchPrepared + searchPrepared = prepareSearch(search) + preparedSearchCache.set(search, searchPrepared) + return searchPrepared +} + + +var all = (targets, options) => { + var results = []; results.total = targets.length // this total can be wrong if some targets are skipped + + var limit = options?.limit || INFINITY + + if(options?.key) { + for(var i=0;i= limit) return results + } + } else if(options?.keys) { + for(var i=0;i= 0; --keyI) { + var target = getValue(obj, options.keys[keyI]) + if(!target) { objResults[keyI] = noTarget; continue } + if(!isPrepared(target)) target = getPrepared(target) + target._score = NEGATIVE_INFINITY + target._indexes.len = 0 + objResults[keyI] = target + } + objResults.obj = obj + objResults._score = NEGATIVE_INFINITY + results.push(objResults); if(results.length >= limit) return results + } + } else { + for(var i=0;i= limit) return results + } + } + + return results +} + + +var algorithm = (preparedSearch, prepared, allowSpaces=false, allowPartialMatch=false) => { + if(allowSpaces===false && preparedSearch.containsSpace) return algorithmSpaces(preparedSearch, prepared, allowPartialMatch) + + var searchLower = preparedSearch._lower + var searchLowerCodes = preparedSearch.lowerCodes + var searchLowerCode = searchLowerCodes[0] + var targetLowerCodes = prepared._targetLowerCodes + var searchLen = searchLowerCodes.length + var targetLen = targetLowerCodes.length + var searchI = 0 // where we at + var targetI = 0 // where you at + var matchesSimpleLen = 0 + + // very basic fuzzy match; to remove non-matching targets ASAP! + // walk through target. find sequential matches. + // if all chars aren't found then exit + for(;;) { + var isMatch = searchLowerCode === targetLowerCodes[targetI] + if(isMatch) { + matchesSimple[matchesSimpleLen++] = targetI + ++searchI; if(searchI === searchLen) break + searchLowerCode = searchLowerCodes[searchI] + } + ++targetI; if(targetI >= targetLen) return NULL // Failed to find searchI + } + + var searchI = 0 + var successStrict = false + var matchesStrictLen = 0 + + var nextBeginningIndexes = prepared._nextBeginningIndexes + if(nextBeginningIndexes === NULL) nextBeginningIndexes = prepared._nextBeginningIndexes = prepareNextBeginningIndexes(prepared.target) + targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1] + + // Our target string successfully matched all characters in sequence! + // Let's try a more advanced and strict test to improve the score + // only count it as a match if it's consecutive or a beginning character! + var backtrackCount = 0 + if(targetI !== targetLen) for(;;) { + if(targetI >= targetLen) { + // We failed to find a good spot for this search char, go back to the previous search char and force it forward + if(searchI <= 0) break // We failed to push chars forward for a better match + + ++backtrackCount; if(backtrackCount > 200) break // exponential backtracking is taking too long, just give up and return a bad match + + --searchI + var lastMatch = matchesStrict[--matchesStrictLen] + targetI = nextBeginningIndexes[lastMatch] + + } else { + var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI] + if(isMatch) { + matchesStrict[matchesStrictLen++] = targetI + ++searchI; if(searchI === searchLen) { successStrict = true; break } + ++targetI + } else { + targetI = nextBeginningIndexes[targetI] + } + } + } + + // check if it's a substring match + var substringIndex = searchLen <= 1 ? -1 : prepared._targetLower.indexOf(searchLower, matchesSimple[0]) // perf: this is slow + var isSubstring = !!~substringIndex + var isSubstringBeginning = !isSubstring ? false : substringIndex===0 || prepared._nextBeginningIndexes[substringIndex-1] === substringIndex + + // if it's a substring match but not at a beginning index, let's try to find a substring starting at a beginning index for a better score + if(isSubstring && !isSubstringBeginning) { + for(var i=0; i { + var score = 0 + + var extraMatchGroupCount = 0 + for(var i = 1; i < searchLen; ++i) { + if(matches[i] - matches[i-1] !== 1) {score -= matches[i]; ++extraMatchGroupCount} + } + var unmatchedDistance = matches[searchLen-1] - matches[0] - (searchLen-1) + + score -= (12+unmatchedDistance) * extraMatchGroupCount // penality for more groups + + if(matches[0] !== 0) score -= matches[0]*matches[0]*.2 // penality for not starting near the beginning + + if(!successStrict) { + score *= 1000 + } else { + // successStrict on a target with too many beginning indexes loses points for being a bad target + var uniqueBeginningIndexes = 1 + for(var i = nextBeginningIndexes[0]; i < targetLen; i=nextBeginningIndexes[i]) ++uniqueBeginningIndexes + + if(uniqueBeginningIndexes > 24) score *= (uniqueBeginningIndexes-24)*10 // quite arbitrary numbers here ... + } + + score -= (targetLen - searchLen)/2 // penality for longer targets + + if(isSubstring) score /= 1+searchLen*searchLen*1 // bonus for being a full substring + if(isSubstringBeginning) score /= 1+searchLen*searchLen*1 // bonus for substring starting on a beginningIndex + + score -= (targetLen - searchLen)/2 // penality for longer targets + + return score + } + + if(!successStrict) { + if(isSubstring) for(var i=0; i { + var seen_indexes = new Set() + var score = 0 + var result = NULL + + var first_seen_index_last_search = 0 + var searches = preparedSearch.spaceSearches + var searchesLen = searches.length + var changeslen = 0 + + // Return _nextBeginningIndexes back to its normal state + var resetNextBeginningIndexes = () => { + for(let i=changeslen-1; i>=0; i--) target._nextBeginningIndexes[nextBeginningIndexesChanges[i*2 + 0]] = nextBeginningIndexesChanges[i*2 + 1] + } + + var hasAtLeast1Match = false + for(var i=0; i=0; i--) { + if(toReplace !== target._nextBeginningIndexes[i]) break + target._nextBeginningIndexes[i] = newBeginningIndex + nextBeginningIndexesChanges[changeslen*2 + 0] = i + nextBeginningIndexesChanges[changeslen*2 + 1] = toReplace + changeslen++ + } + } + } + + score += result._score / searchesLen + allowPartialMatchScores[i] = result._score / searchesLen + + // dock points based on order otherwise "c man" returns Manifest.cpp instead of CheatManager.h + if(result._indexes[0] < first_seen_index_last_search) { + score -= (first_seen_index_last_search - result._indexes[0]) * 2 + } + first_seen_index_last_search = result._indexes[0] + + for(var j=0; j score) { + if(allowPartialMatch) { + for(var i=0; i str.replace(/\p{Script=Latin}+/gu, match => match.normalize('NFD')).replace(/[\u0300-\u036f]/g, '') + +var prepareLowerInfo = (str) => { + str = remove_accents(str) + var strLen = str.length + var lower = str.toLowerCase() + var lowerCodes = [] // new Array(strLen) sparse array is too slow + var bitflags = 0 + var containsSpace = false // space isn't stored in bitflags because of how searching with a space works + + for(var i = 0; i < strLen; ++i) { + var lowerCode = lowerCodes[i] = lower.charCodeAt(i) + + if(lowerCode === 32) { + containsSpace = true + continue // it's important that we don't set any bitflags for space + } + + var bit = lowerCode>=97&&lowerCode<=122 ? lowerCode-97 // alphabet + : lowerCode>=48&&lowerCode<=57 ? 26 // numbers + // 3 bits available + : lowerCode<=127 ? 30 // other ascii + : 31 // other utf8 + bitflags |= 1< { + var targetLen = target.length + var beginningIndexes = []; var beginningIndexesLen = 0 + var wasUpper = false + var wasAlphanum = false + for(var i = 0; i < targetLen; ++i) { + var targetCode = target.charCodeAt(i) + var isUpper = targetCode>=65&&targetCode<=90 + var isAlphanum = isUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57 + var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum + wasUpper = isUpper + wasAlphanum = isAlphanum + if(isBeginning) beginningIndexes[beginningIndexesLen++] = i + } + return beginningIndexes +} +var prepareNextBeginningIndexes = (target) => { + target = remove_accents(target) + var targetLen = target.length + var beginningIndexes = prepareBeginningIndexes(target) + var nextBeginningIndexes = [] // new Array(targetLen) sparse array is too slow + var lastIsBeginning = beginningIndexes[0] + var lastIsBeginningI = 0 + for(var i = 0; i < targetLen; ++i) { + if(lastIsBeginning > i) { + nextBeginningIndexes[i] = lastIsBeginning + } else { + lastIsBeginning = beginningIndexes[++lastIsBeginningI] + nextBeginningIndexes[i] = lastIsBeginning===undefined ? targetLen : lastIsBeginning + } + } + return nextBeginningIndexes +} + +var preparedCache = new Map() +var preparedSearchCache = new Map() + +// the theory behind these being globals is to reduce garbage collection by not making new arrays +var matchesSimple = []; var matchesStrict = [] +var nextBeginningIndexesChanges = [] // allows straw berry to match strawberry well, by modifying the end of a substring to be considered a beginning index for the rest of the search +var keysSpacesBestScores = []; var allowPartialMatchScores = [] +var tmpTargets = []; var tmpResults = [] + +// prop = 'key' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop] +// prop = 'key1.key2' 10ms +// prop = ['key1', 'key2'] 27ms +// prop = obj => obj.tags.join() ??ms +var getValue = (obj, prop) => { + var tmp = obj[prop]; if(tmp !== undefined) return tmp + if(typeof prop === 'function') return prop(obj) // this should run first. but that makes string props slower + var segs = prop + if(!Array.isArray(prop)) segs = prop.split('.') + var len = segs.length + var i = -1 + while (obj && (++i < len)) obj = obj[segs[i]] + return obj +} + +var isPrepared = (x) => { return typeof x === 'object' && typeof x._bitflags === 'number' } +var INFINITY = Infinity; var NEGATIVE_INFINITY = -INFINITY +var noResults = []; noResults.total = 0 +var NULL = null + +var noTarget = prepare('') + +// Hacked version of https://github.com/lemire/FastPriorityQueue.js +var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r=>{for(var a=0,v=e[a],c=1;c>1]=e[a],c=1+(a<<1)}for(var f=a-1>>1;a>0&&v._score>1)e[a]=e[f];e[a]=v};return a.add=(r=>{var a=o;e[o++]=r;for(var v=a-1>>1;a>0&&r._score>1)e[a]=e[v];e[a]=r}),a.poll=(r=>{if(0!==o){var a=e[0];return e[0]=e[--o],v(),a}}),a.peek=(r=>{if(0!==o)return e[0]}),a.replaceTop=(r=>{e[0]=r,v()}),a} +var q = fastpriorityqueue() // reuse this diff --git a/config/quickshell/modules/common/functions/levendist.js b/config/quickshell/modules/common/functions/levendist.js new file mode 100644 index 00000000..90180d21 --- /dev/null +++ b/config/quickshell/modules/common/functions/levendist.js @@ -0,0 +1,141 @@ +// Original code from https://github.com/koeqaife/hyprland-material-you +// Original code license: GPLv3 +// Translated to Js from Cython with an LLM and reviewed + +function min3(a, b, c) { + return a < b && a < c ? a : b < c ? b : c; +} + +function max3(a, b, c) { + return a > b && a > c ? a : b > c ? b : c; +} + +function min2(a, b) { + return a < b ? a : b; +} + +function max2(a, b) { + return a > b ? a : b; +} + +function levenshteinDistance(s1, s2) { + let len1 = s1.length; + let len2 = s2.length; + + if (len1 === 0) return len2; + if (len2 === 0) return len1; + + if (len2 > len1) { + [s1, s2] = [s2, s1]; + [len1, len2] = [len2, len1]; + } + + let prev = new Array(len2 + 1); + let curr = new Array(len2 + 1); + + for (let j = 0; j <= len2; j++) { + prev[j] = j; + } + + for (let i = 1; i <= len1; i++) { + curr[0] = i; + for (let j = 1; j <= len2; j++) { + let cost = s1[i - 1] === s2[j - 1] ? 0 : 1; + curr[j] = min3(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost); + } + [prev, curr] = [curr, prev]; + } + + return prev[len2]; +} + +function partialRatio(shortS, longS) { + let lenS = shortS.length; + let lenL = longS.length; + let best = 0.0; + + if (lenS === 0) return 1.0; + + for (let i = 0; i <= lenL - lenS; i++) { + let sub = longS.slice(i, i + lenS); + let dist = levenshteinDistance(shortS, sub); + let score = 1.0 - (dist / lenS); + if (score > best) best = score; + } + + return best; +} + +function computeScore(s1, s2) { + if (s1 === s2) return 1.0; + + let dist = levenshteinDistance(s1, s2); + let maxLen = max2(s1.length, s2.length); + if (maxLen === 0) return 1.0; + + let full = 1.0 - (dist / maxLen); + let part = s1.length < s2.length ? partialRatio(s1, s2) : partialRatio(s2, s1); + + let score = 0.85 * full + 0.15 * part; + + if (s1 && s2 && s1[0] !== s2[0]) { + score -= 0.05; + } + + let lenDiff = Math.abs(s1.length - s2.length); + if (lenDiff >= 3) { + score -= 0.05 * lenDiff / maxLen; + } + + let commonPrefixLen = 0; + let minLen = min2(s1.length, s2.length); + for (let i = 0; i < minLen; i++) { + if (s1[i] === s2[i]) { + commonPrefixLen++; + } else { + break; + } + } + score += 0.02 * commonPrefixLen; + + if (s1.includes(s2) || s2.includes(s1)) { + score += 0.06; + } + + return Math.max(0.0, Math.min(1.0, score)); +} + +function computeTextMatchScore(s1, s2) { + if (s1 === s2) return 1.0; + + let dist = levenshteinDistance(s1, s2); + let maxLen = max2(s1.length, s2.length); + if (maxLen === 0) return 1.0; + + let full = 1.0 - (dist / maxLen); + let part = s1.length < s2.length ? partialRatio(s1, s2) : partialRatio(s2, s1); + + let score = 0.4 * full + 0.6 * part; + + let lenDiff = Math.abs(s1.length - s2.length); + if (lenDiff >= 10) { + score -= 0.02 * lenDiff / maxLen; + } + + let commonPrefixLen = 0; + let minLen = min2(s1.length, s2.length); + for (let i = 0; i < minLen; i++) { + if (s1[i] === s2[i]) { + commonPrefixLen++; + } else { + break; + } + } + score += 0.01 * commonPrefixLen; + + if (s1.includes(s2) || s2.includes(s1)) { + score += 0.2; + } + + return Math.max(0.0, Math.min(1.0, score)); +} diff --git a/config/quickshell/modules/common/functions/object_utils.js b/config/quickshell/modules/common/functions/object_utils.js new file mode 100644 index 00000000..96c632fd --- /dev/null +++ b/config/quickshell/modules/common/functions/object_utils.js @@ -0,0 +1,45 @@ +function toPlainObject(qtObj) { + if (qtObj === null || typeof qtObj !== "object") return qtObj; + + // Handle arrays + if (Array.isArray(qtObj)) { + return qtObj.map(toPlainObject); + } + + const result = ({}); + for (let key in qtObj) { + if ( + typeof qtObj[key] !== "function" && + !key.startsWith("objectName") && + !key.startsWith("children") && + !key.startsWith("object") && + !key.startsWith("parent") && + !key.startsWith("metaObject") && + !key.startsWith("destroyed") && + !key.startsWith("reloadableId") + ) { + result[key] = toPlainObject(qtObj[key]); + } + } + return result; +} + +function applyToQtObject(qtObj, jsonObj) { + if (!qtObj || typeof jsonObj !== "object" || jsonObj === null) return; + + for (let key in jsonObj) { + if (!qtObj.hasOwnProperty(key)) continue; + + // Check if the property is a QtObject (not a value) + const value = qtObj[key]; + const jsonValue = jsonObj[key]; + + // If it's an object and not an array, recurse + if (value && typeof value === "object" && !Array.isArray(value)) { + applyToQtObject(value, jsonValue); + } else { + // Otherwise, assign the value + qtObj[key] = jsonValue; + } + } +} diff --git a/config/quickshell/modules/common/functions/string_utils.js b/config/quickshell/modules/common/functions/string_utils.js new file mode 100644 index 00000000..c22671eb --- /dev/null +++ b/config/quickshell/modules/common/functions/string_utils.js @@ -0,0 +1,188 @@ +/** + * Formats a string according to the args that are passed in + * @param { string } str + * @param {...any} args + * @returns + */ +function format(str, ...args) { + return str.replace(/{(\d+)}/g, (match, index) => + typeof args[index] !== 'undefined' ? args[index] : match + ); +} + +/** + * Returns the domain of the passed in url or null + * @param { string } url + * @returns { string| null } + */ +function getDomain(url) { + const match = url.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/); + return match ? match[1] : null; +} + +/** + * Returns the base url of the passed in url or null + * @param { string } url + * @returns { string | null } + */ +function getBaseUrl(url) { + const match = url.match(/^(https?:\/\/[^\/]+)(\/.*)?$/); + return match ? match[1] : null; +} + +/** + * Escapes single quotes in shell commands + * @param { string } str + * @returns { string } + */ +function shellSingleQuoteEscape(str) { + // escape single quotes + return String(str) + // .replace(/\\/g, '\\\\') + .replace(/'/g, "'\\''"); +} + +/** + * Splits markdown blocks into three different types: text, think, and code. + * @param { string } markdown + */ +function splitMarkdownBlocks(markdown) { + const regex = /```(\w+)?\n([\s\S]*?)```|([\s\S]*?)<\/think>/g; + /** + * @type {{type: "text" | "think" | "code"; content: string; lang: string | undefined; completed: boolean | undefined}[]} + */ + let result = []; + let lastIndex = 0; + let match; + while ((match = regex.exec(markdown)) !== null) { + if (match.index > lastIndex) { + const text = markdown.slice(lastIndex, match.index); + if (text.trim()) { + result.push({ type: "text", content: text }); + } + } + if (match[0].startsWith('```')) { + if (match[2] && match[2].trim()) { + result.push({ type: "code", lang: match[1] || "", content: match[2], completed: true }); + } + } else if (match[0].startsWith('')) { + if (match[3] && match[3].trim()) { + result.push({ type: "think", content: match[3], completed: true }); + } + } + lastIndex = regex.lastIndex; + } + // Handle any remaining text after the last match + if (lastIndex < markdown.length) { + const text = markdown.slice(lastIndex); + // Check for unfinished block + const thinkStart = text.indexOf(''); + const codeStart = text.indexOf('```'); + if ( + thinkStart !== -1 && + (codeStart === -1 || thinkStart < codeStart) + ) { + const beforeThink = text.slice(0, thinkStart); + if (beforeThink.trim()) { + result.push({ type: "text", content: beforeThink }); + } + const thinkContent = text.slice(thinkStart + 7); + if (thinkContent.trim()) { + result.push({ type: "think", content: thinkContent, completed: false }); + } + } else if (codeStart !== -1) { + const beforeCode = text.slice(0, codeStart); + if (beforeCode.trim()) { + result.push({ type: "text", content: beforeCode }); + } + // Try to detect language after ``` + const codeLangMatch = text.slice(codeStart + 3).match(/^(\w+)?\n/); + let lang = ""; + let codeContentStart = codeStart + 3; + if (codeLangMatch) { + lang = codeLangMatch[1] || ""; + codeContentStart += codeLangMatch[0].length; + } else if (text[codeStart + 3] === '\n') { + codeContentStart += 1; + } + const codeContent = text.slice(codeContentStart); + if (codeContent.trim()) { + result.push({ type: "code", lang, content: codeContent, completed: false }); + } + } else if (text.trim()) { + result.push({ type: "text", content: text }); + } + } + // console.log(JSON.stringify(result, null, 2)); + return result; +} + +/** + * Returns the original string with backslashes escaped + * @param { string } str + * @returns { string } + */ +function escapeBackslashes(str) { + return str.replace(/\\/g, '\\\\'); +} + +/** + * Wraps words to supplied maximum length + * @param { string | null } str + * @param { number } maxLen + * @returns { string } + */ +function wordWrap(str, maxLen) { + if (!str) return ""; + let words = str.split(" "); + let lines = []; + let current = ""; + for (let i = 0; i < words.length; ++i) { + if ((current + (current.length > 0 ? " " : "") + words[i]).length > maxLen) { + if (current.length > 0) lines.push(current); + current = words[i]; + } else { + current += (current.length > 0 ? " " : "") + words[i]; + } + } + if (current.length > 0) lines.push(current); + return lines.join("\n"); +} + +function cleanMusicTitle(title) { + if (!title) return ""; + // Brackets + title = title.replace(/^ *\([^)]*\) */g, " "); // Round brackets + title = title.replace(/^ *\[[^\]]*\] */g, " "); // Square brackets + title = title.replace(/^ *\{[^\}]*\} */g, " "); // Curly brackets + // Japenis brackets + title = title.replace(/^ *【[^】]*】/, "") // Touhou + title = title.replace(/^ *《[^》]*》/, "") // ?? + title = title.replace(/^ *「[^」]*」/, "") // OP/ED + title = title.replace(/^ *『[^』]*』/, "") // OP/ED + + return title; +} + +function friendlyTimeForSeconds(seconds) { + if (isNaN(seconds) || seconds < 0) return "0:00"; + seconds = Math.floor(seconds); + const h = Math.floor(seconds / 3600); + const m = Math.floor((seconds % 3600) / 60); + const s = seconds % 60; + if (h > 0) { + return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; + } else { + return `${m}:${s.toString().padStart(2, '0')}`; + } +} + +function escapeHtml(str) { + if (typeof str !== 'string') return str; + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} diff --git a/config/quickshell/modules/common/widgets/CliphistImage.qml b/config/quickshell/modules/common/widgets/CliphistImage.qml new file mode 100644 index 00000000..9de34450 --- /dev/null +++ b/config/quickshell/modules/common/widgets/CliphistImage.qml @@ -0,0 +1,101 @@ +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/services" +import "root:/modules/common/functions/string_utils.js" as StringUtils +import "root:/modules/common/functions/file_utils.js" as FileUtils +import Qt5Compat.GraphicalEffects +import Qt.labs.platform +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell.Io +import Quickshell.Widgets +import Quickshell.Hyprland + +Rectangle { + id: root + property string entry + property real maxWidth + property real maxHeight + + property string imageDecodePath: Directories.cliphistDecode + property string imageDecodeFileName: `${entryNumber}` + property string imageDecodeFilePath: `${imageDecodePath}/${imageDecodeFileName}` + property string source + + property int entryNumber: { + if (!root.entry) return 0 + const match = root.entry.match(/^(\d+)\t/) + return match ? parseInt(match[1]) : 0 + } + property int imageWidth: { + if (!root.entry) return 0 + const match = root.entry.match(/(\d+)x(\d+)/) + return match ? parseInt(match[1]) : 0 + } + property int imageHeight: { + if (!root.entry) return 0 + const match = root.entry.match(/(\d+)x(\d+)/) + return match ? parseInt(match[2]) : 0 + } + property real scale: { + return Math.min( + root.maxWidth / imageWidth, + root.maxHeight / imageHeight, + 1 + ) + } + + color: Appearance.colors.colLayer1 + radius: Appearance.rounding.small + implicitHeight: imageHeight * scale + implicitWidth: imageWidth * scale + + Component.onCompleted: { + decodeImageProcess.running = true + } + + Process { + id: decodeImageProcess + command: ["bash", "-c", + `[ -f ${imageDecodeFilePath} ] || echo '${StringUtils.shellSingleQuoteEscape(root.entry)}' | cliphist decode > '${imageDecodeFilePath}'` + ] + onExited: (exitCode, exitStatus) => { + if (exitCode === 0) { + root.source = imageDecodeFilePath + } else { + console.error("[CliphistImage] Failed to decode image for entry:", root.entry) + root.source = "" + } + } + } + + Component.onDestruction: { + Hyprland.dispatch(`exec bash -c "[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'"`) + } + + Image { + id: image + anchors.fill: parent + + source: Qt.resolvedUrl(root.source) + fillMode: Image.PreserveAspectFit + antialiasing: true + asynchronous: true + + width: root.imageWidth * root.scale + height: root.imageHeight * root.scale + sourceSize.width: width + sourceSize.height: height + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: image.width + height: image.height + radius: root.radius + } + } + } +} + diff --git a/config/quickshell/modules/common/widgets/DialogButton.qml b/config/quickshell/modules/common/widgets/DialogButton.qml new file mode 100644 index 00000000..9e19a507 --- /dev/null +++ b/config/quickshell/modules/common/widgets/DialogButton.qml @@ -0,0 +1,38 @@ +import "root:/modules/common" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Io + +/** + * Material 3 dialog button. See https://m3.material.io/components/dialogs/overview + */ +RippleButton { + id: button + + property string buttonText + implicitHeight: 30 + implicitWidth: buttonTextWidget.implicitWidth + 15 * 2 + buttonRadius: Appearance?.rounding.full ?? 9999 + + property color colEnabled: Appearance?.colors.colPrimary + property color colDisabled: Appearance?.m3colors.m3outline + + contentItem: StyledText { + id: buttonTextWidget + anchors.fill: parent + anchors.leftMargin: 15 + anchors.rightMargin: 15 + text: buttonText + horizontalAlignment: Text.AlignHCenter + font.pixelSize: Appearance?.font.pixelSize.small ?? 12 + color: button.enabled ? button.colEnabled : button.colDisabled + + Behavior on color { + animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + } + } + +} diff --git a/config/quickshell/modules/common/widgets/MaterialSymbol.qml b/config/quickshell/modules/common/widgets/MaterialSymbol.qml new file mode 100644 index 00000000..dbbfff00 --- /dev/null +++ b/config/quickshell/modules/common/widgets/MaterialSymbol.qml @@ -0,0 +1,30 @@ +import "root:/modules/common/" +import QtQuick +import QtQuick.Layouts + +Text { + id: root + property real iconSize: Appearance?.font.pixelSize.small ?? 16 + property real fill: 0 + renderType: Text.NativeRendering + font.hintingPreference: Font.PreferFullHinting + verticalAlignment: Text.AlignVCenter + font.family: Appearance?.font.family.iconMaterial ?? "Material Symbols Rounded" + font.pixelSize: iconSize + color: Appearance.m3colors.m3onBackground + + Behavior on fill { + NumberAnimation { + duration: Appearance?.animation.elementMoveFast.duration ?? 200 + easing.type: Appearance?.animation.elementMoveFast.type ?? Easing.BezierSpline + easing.bezierCurve: Appearance?.animation.elementMoveFast.bezierCurve ?? [0.34, 0.80, 0.34, 1.00, 1, 1] + } + } + + font.variableAxes: { + "FILL": fill, + // "wght": font.weight, + // "GRAD": 0, + "opsz": iconSize, + } +} diff --git a/config/quickshell/modules/common/widgets/PointingHandInteraction.qml b/config/quickshell/modules/common/widgets/PointingHandInteraction.qml new file mode 100644 index 00000000..cf8b065f --- /dev/null +++ b/config/quickshell/modules/common/widgets/PointingHandInteraction.qml @@ -0,0 +1,7 @@ +import QtQuick + +MouseArea { + anchors.fill: parent + onPressed: (mouse) => mouse.accepted = false + cursorShape: Qt.PointingHandCursor +} \ No newline at end of file diff --git a/config/quickshell/modules/common/widgets/RippleButton.qml b/config/quickshell/modules/common/widgets/RippleButton.qml new file mode 100644 index 00000000..cd7762b9 --- /dev/null +++ b/config/quickshell/modules/common/widgets/RippleButton.qml @@ -0,0 +1,185 @@ +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import Qt5Compat.GraphicalEffects +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell.Io +import Quickshell.Widgets + +/** + * A button with ripple effect similar to in Material Design. + */ +Button { + id: root + property bool toggled + property string buttonText + property real buttonRadius: Appearance?.rounding?.small ?? 4 + property real buttonRadiusPressed: buttonRadius + property real buttonEffectiveRadius: root.down ? root.buttonRadiusPressed : root.buttonRadius + property int rippleDuration: 1200 + property bool rippleEnabled: true + property var downAction // When left clicking (down) + property var releaseAction // When left clicking (release) + property var altAction // When right clicking + property var middleClickAction // When middle clicking + + property color colBackground: ColorUtils.transparentize(Appearance?.colors.colLayer1Hover, 1) || "transparent" + property color colBackgroundHover: Appearance?.colors.colLayer1Hover ?? "#E5DFED" + property color colBackgroundToggled: Appearance?.colors.colPrimary ?? "#65558F" + property color colBackgroundToggledHover: Appearance?.colors.colPrimaryHover ?? "#77699C" + property color colRipple: Appearance?.colors.colLayer1Active ?? "#D6CEE2" + property color colRippleToggled: Appearance?.colors.colPrimaryActive ?? "#D6CEE2" + + property color buttonColor: root.enabled ? (root.toggled ? + (root.hovered ? colBackgroundToggledHover : + colBackgroundToggled) : + (root.hovered ? colBackgroundHover : + colBackground)) : colBackground + property color rippleColor: root.toggled ? colRippleToggled : colRipple + + function startRipple(x, y) { + const stateY = buttonBackground.y; + rippleAnim.x = x; + rippleAnim.y = y - stateY; + + const dist = (ox,oy) => ox*ox + oy*oy + const stateEndY = stateY + buttonBackground.height + rippleAnim.radius = Math.sqrt(Math.max(dist(0, stateY), dist(0, stateEndY), dist(width, stateY), dist(width, stateEndY))) + + rippleFadeAnim.complete(); + rippleAnim.restart(); + } + + component RippleAnim: NumberAnimation { + duration: rippleDuration + easing.type: Appearance?.animation.elementMoveEnter.type + easing.bezierCurve: Appearance?.animationCurves.standardDecel + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + onPressed: (event) => { + if(event.button === Qt.RightButton) { + if (root.altAction) root.altAction(); + return; + } + if(event.button === Qt.MiddleButton) { + if (root.middleClickAction) root.middleClickAction(); + return; + } + root.down = true + if (root.downAction) root.downAction(); + if (!root.rippleEnabled) return; + const {x,y} = event + startRipple(x, y) + } + onReleased: (event) => { + root.down = false + if (event.button != Qt.LeftButton) return; + if (root.releaseAction) root.releaseAction(); + root.click() // Because the MouseArea already consumed the event + if (!root.rippleEnabled) return; + rippleFadeAnim.restart(); + } + onCanceled: (event) => { + root.down = false + if (!root.rippleEnabled) return; + rippleFadeAnim.restart(); + } + } + + RippleAnim { + id: rippleFadeAnim + target: ripple + property: "opacity" + to: 0 + } + + SequentialAnimation { + id: rippleAnim + + property real x + property real y + property real radius + + PropertyAction { + target: ripple + property: "x" + value: rippleAnim.x + } + PropertyAction { + target: ripple + property: "y" + value: rippleAnim.y + } + PropertyAction { + target: ripple + property: "opacity" + value: 1 + } + ParallelAnimation { + RippleAnim { + target: ripple + properties: "implicitWidth,implicitHeight" + from: 0 + to: rippleAnim.radius * 2 + } + } + } + + background: Rectangle { + id: buttonBackground + radius: root.buttonEffectiveRadius + implicitHeight: 50 + + color: root.buttonColor + Behavior on color { + animation: Appearance?.animation.elementMoveFast.colorAnimation.createObject(this) + } + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: buttonBackground.width + height: buttonBackground.height + radius: root.buttonEffectiveRadius + } + } + + Item { + id: ripple + width: ripple.implicitWidth + height: ripple.implicitHeight + opacity: 0 + + property real implicitWidth: 0 + property real implicitHeight: 0 + + Behavior on opacity { + animation: Appearance?.animation.elementMoveFast.colorAnimation.createObject(this) + } + + RadialGradient { + anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0.0; color: root.rippleColor } + GradientStop { position: 0.3; color: root.rippleColor } + GradientStop { position: 0.5; color: Qt.rgba(root.rippleColor.r, root.rippleColor.g, root.rippleColor.b, 0) } + } + } + + transform: Translate { + x: -ripple.width / 2 + y: -ripple.height / 2 + } + } + } + + contentItem: StyledText { + text: root.buttonText + } +} diff --git a/config/quickshell/modules/common/widgets/RoundCorner.qml b/config/quickshell/modules/common/widgets/RoundCorner.qml new file mode 100644 index 00000000..c9a2827a --- /dev/null +++ b/config/quickshell/modules/common/widgets/RoundCorner.qml @@ -0,0 +1,64 @@ +import QtQuick 2.9 + +Item { + id: root + + property int size: 25 + property color color: "#000000" + + onColorChanged: { + canvas.requestPaint(); + } + + property QtObject cornerEnum: QtObject { + property int topLeft: 0 + property int topRight: 1 + property int bottomLeft: 2 + property int bottomRight: 3 + } + + property int corner: cornerEnum.topLeft // Default to TopLeft + + width: size + height: size + + Canvas { + id: canvas + + anchors.fill: parent + antialiasing: true + + onPaint: { + var ctx = getContext("2d"); + var r = root.size; + + ctx.beginPath(); + switch (root.corner) { + case cornerEnum.topLeft: + ctx.arc(r, r, r, Math.PI, 3 * Math.PI / 2); + ctx.lineTo(0, 0); + break; + case cornerEnum.topRight: + ctx.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI); + ctx.lineTo(r, 0); + break; + case cornerEnum.bottomLeft: + ctx.arc(r, 0, r, Math.PI / 2, Math.PI); + ctx.lineTo(0, r); + break; + case cornerEnum.bottomRight: + ctx.arc(0, 0, r, 0, Math.PI / 2); + ctx.lineTo(r, r); + break; + } + ctx.closePath(); + ctx.fillStyle = root.color; + ctx.fill(); + } + } + + Behavior on size { + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) + } + +} diff --git a/config/quickshell/modules/common/widgets/StyledRectangularShadow.qml b/config/quickshell/modules/common/widgets/StyledRectangularShadow.qml new file mode 100644 index 00000000..6e1f2e16 --- /dev/null +++ b/config/quickshell/modules/common/widgets/StyledRectangularShadow.qml @@ -0,0 +1,13 @@ +import QtQuick +import QtQuick.Effects +import "root:/modules/common" + +RectangularShadow { + required property var target + anchors.fill: target + radius: target.radius + blur: 1.2 * Appearance.sizes.elevationMargin + spread: 1 + color: Appearance.colors.colShadow + cached: true +} diff --git a/config/quickshell/modules/common/widgets/StyledText.qml b/config/quickshell/modules/common/widgets/StyledText.qml new file mode 100644 index 00000000..6eef5785 --- /dev/null +++ b/config/quickshell/modules/common/widgets/StyledText.qml @@ -0,0 +1,14 @@ +import "root:/modules/common" +import QtQuick +import QtQuick.Layouts + +Text { + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + font { + hintingPreference: Font.PreferFullHinting + family: Appearance?.font.family.main ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.small ?? 15 + } + color: Appearance?.m3colors.m3onBackground ?? "black" +} diff --git a/config/quickshell/modules/common/widgets/StyledTextArea.qml b/config/quickshell/modules/common/widgets/StyledTextArea.qml new file mode 100644 index 00000000..1ea9a349 --- /dev/null +++ b/config/quickshell/modules/common/widgets/StyledTextArea.qml @@ -0,0 +1,15 @@ +import "root:/modules/common" +import QtQuick +import QtQuick.Controls + +TextArea { + renderType: Text.NativeRendering + selectedTextColor: Appearance.m3colors.m3onSecondaryContainer + selectionColor: Appearance.m3colors.m3secondaryContainer + placeholderTextColor: Appearance.m3colors.m3outline + font { + family: Appearance?.font.family.main ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.small ?? 15 + hintingPreference: Font.PreferFullHinting + } +} diff --git a/config/quickshell/modules/common/widgets/StyledToolTip.qml b/config/quickshell/modules/common/widgets/StyledToolTip.qml new file mode 100644 index 00000000..2ca16df1 --- /dev/null +++ b/config/quickshell/modules/common/widgets/StyledToolTip.qml @@ -0,0 +1,60 @@ +import "root:/modules/common" +import "root:/modules/common/widgets" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ToolTip { + id: root + property string content + property bool extraVisibleCondition: true + property bool alternativeVisibleCondition: false + property bool internalVisibleCondition: { + const ans = (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition + return ans + } + verticalPadding: 5 + horizontalPadding: 10 + opacity: internalVisibleCondition ? 1 : 0 + visible: opacity > 0 + + Behavior on opacity { + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) + } + + background: null + + contentItem: Item { + id: contentItemBackground + implicitWidth: tooltipTextObject.width + 2 * root.horizontalPadding + implicitHeight: tooltipTextObject.height + 2 * root.verticalPadding + + Rectangle { + id: backgroundRectangle + anchors.bottom: contentItemBackground.bottom + anchors.horizontalCenter: contentItemBackground.horizontalCenter + color: Appearance?.m3colors.colTooltip ?? "#3C4043" + radius: Appearance?.rounding.verysmall ?? 7 + width: internalVisibleCondition ? (tooltipTextObject.width + 2 * padding) : 0 + height: internalVisibleCondition ? (tooltipTextObject.height + 2 * padding) : 0 + clip: true + + Behavior on width { + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) + } + Behavior on height { + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) + } + + StyledText { + id: tooltipTextObject + anchors.centerIn: parent + text: content + font.pixelSize: Appearance?.font.pixelSize.smaller ?? 14 + font.hintingPreference: Font.PreferNoHinting // Prevent shaky text + color: Appearance?.m3colors.colOnTooltip ?? "#FFFFFF" + wrapMode: Text.Wrap + } + } + } +} \ No newline at end of file diff --git a/config/quickshell/modules/overview/Overview.qml b/config/quickshell/modules/overview/Overview.qml new file mode 100644 index 00000000..ef5a49c3 --- /dev/null +++ b/config/quickshell/modules/overview/Overview.qml @@ -0,0 +1,279 @@ +import "root:/" +import "root:/services" +import "root:/modules/common" +import "root:/modules/common/widgets" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import Quickshell.Hyprland + +Scope { + id: overviewScope + property bool dontAutoCancelSearch: false + property bool searchEnabled: ConfigOptions.search.searchEnabled + + Variants { + id: overviewVariants + model: Quickshell.screens + PanelWindow { + id: root + required property var modelData + property string searchingText: "" + readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen) + property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor.id) + screen: modelData + visible: GlobalStates.overviewOpen + + WlrLayershell.namespace: "quickshell:overview" + WlrLayershell.layer: WlrLayer.Overlay + color: "transparent" + + mask: Region { + item: GlobalStates.overviewOpen ? columnLayout : null + } + HyprlandWindow.visibleMask: Region { + item: GlobalStates.overviewOpen ? columnLayout : null + } + + anchors { + top: true + left: true + right: true + bottom: true + } + + HyprlandFocusGrab { + id: grab + windows: [ root ] + property bool canBeActive: root.monitorIsFocused + active: false + onCleared: () => { + if (!active) GlobalStates.overviewOpen = false + } + } + + Connections { + target: GlobalStates + function onOverviewOpenChanged() { + if (!GlobalStates.overviewOpen) { + if (overviewScope.searchEnabled && searchWidget) { + searchWidget.disableExpandAnimation() + } + overviewScope.dontAutoCancelSearch = false; + } else { + if (!overviewScope.dontAutoCancelSearch && overviewScope.searchEnabled && searchWidget) { + searchWidget.cancelSearch() + } + delayedGrabTimer.start() + } + } + } + + Timer { + id: delayedGrabTimer + interval: ConfigOptions.hacks.arbitraryRaceConditionDelay + repeat: false + onTriggered: { + if (!grab.canBeActive) return + grab.active = GlobalStates.overviewOpen + } + } + + implicitWidth: columnLayout.implicitWidth + implicitHeight: columnLayout.implicitHeight + + function setSearchingText(text) { + if (overviewScope.searchEnabled && searchWidget) { + searchWidget.setSearchingText(text); + } + } + + ColumnLayout { + id: columnLayout + visible: GlobalStates.overviewOpen + anchors { + horizontalCenter: parent.horizontalCenter + top: ConfigOptions.overview.position === 0 ? parent.top : undefined + verticalCenter: ConfigOptions.overview.position === 1 ? parent.verticalCenter : undefined + bottom: ConfigOptions.overview.position === 2 ? parent.bottom : undefined + } + + Keys.onPressed: (event) => { + if (event.key === Qt.Key_Escape) { + GlobalStates.overviewOpen = false; + } + } + + Item { + height: 1 + width: 1 + } + + // Conditionally render SearchWidget - only exists when searchEnabled is true + SearchWidget { + id: searchWidget + Layout.alignment: Qt.AlignHCenter + visible: overviewScope.searchEnabled + height: overviewScope.searchEnabled ? implicitHeight : 0 + Layout.preferredHeight: overviewScope.searchEnabled ? implicitHeight : 0 + onSearchingTextChanged: (text) => { + root.searchingText = searchingText + } + } + + Item { + Layout.preferredHeight: overviewScope.searchEnabled ? 0 : 20 + Layout.fillWidth: true + visible: !overviewScope.searchEnabled + } + + Loader { + id: overviewLoader + active: GlobalStates.overviewOpen + sourceComponent: OverviewWidget { + panelWindow: root + // Show OverviewWidget when search is disabled OR when search text is empty + visible: !overviewScope.searchEnabled || (root.searchingText == "") + } + } + } + } + } + + IpcHandler { + target: "overview" + + function toggle() { + GlobalStates.overviewOpen = !GlobalStates.overviewOpen + } + function close() { + GlobalStates.overviewOpen = false + } + function open() { + GlobalStates.overviewOpen = true + } + function toggleReleaseInterrupt() { + GlobalStates.superReleaseMightTrigger = false + } + // Add function to control search + function toggleSearch() { + overviewScope.searchEnabled = !overviewScope.searchEnabled + } + function enableSearch() { + overviewScope.searchEnabled = true + } + function disableSearch() { + overviewScope.searchEnabled = false + } + } + + GlobalShortcut { + name: "overviewToggle" + description: qsTr("Toggles overview on press") + + onPressed: { + GlobalStates.overviewOpen = !GlobalStates.overviewOpen + } + } + + GlobalShortcut { + name: "overviewClose" + description: qsTr("Closes overview") + + onPressed: { + GlobalStates.overviewOpen = false + } + } + + GlobalShortcut { + name: "overviewToggleRelease" + description: qsTr("Toggles overview on release") + + onPressed: { + GlobalStates.superReleaseMightTrigger = true + } + + onReleased: { + if (!GlobalStates.superReleaseMightTrigger) { + GlobalStates.superReleaseMightTrigger = true + return + } + GlobalStates.overviewOpen = !GlobalStates.overviewOpen + } + } + + GlobalShortcut { + name: "overviewToggleReleaseInterrupt" + description: qsTr("Interrupts possibility of overview being toggled on release. ") + + qsTr("This is necessary because GlobalShortcut.onReleased in quickshell triggers whether or not you press something else while holding the key. ") + + qsTr("To make sure this works consistently, use binditn = MODKEYS, catchall in an automatically triggered submap that includes everything.") + + onPressed: { + GlobalStates.superReleaseMightTrigger = false + } + } + + // Only enable clipboard/emoji shortcuts when search is enabled + GlobalShortcut { + name: "overviewClipboardToggle" + description: qsTr("Toggle clipboard query on overview widget") + + onPressed: { + if (!overviewScope.searchEnabled) return; // Skip if search disabled + + if (GlobalStates.overviewOpen && overviewScope.dontAutoCancelSearch) { + GlobalStates.overviewOpen = false; + return; + } + for (let i = 0; i < overviewVariants.instances.length; i++) { + let panelWindow = overviewVariants.instances[i]; + if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) { + overviewScope.dontAutoCancelSearch = true; + panelWindow.setSearchingText( + ConfigOptions.search.prefix.clipboard + ); + GlobalStates.overviewOpen = true; + return + } + } + } + } + + GlobalShortcut { + name: "overviewEmojiToggle" + description: qsTr("Toggle emoji query on overview widget") + + onPressed: { + if (!overviewScope.searchEnabled) return; // Skip if search disabled + + if (GlobalStates.overviewOpen && overviewScope.dontAutoCancelSearch) { + GlobalStates.overviewOpen = false; + return; + } + for (let i = 0; i < overviewVariants.instances.length; i++) { + let panelWindow = overviewVariants.instances[i]; + if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) { + overviewScope.dontAutoCancelSearch = true; + panelWindow.setSearchingText( + ConfigOptions.search.prefix.emojis + ); + GlobalStates.overviewOpen = true; + return + } + } + } + } + + // Optional: Add shortcut to toggle search functionality + GlobalShortcut { + name: "overviewToggleSearch" + description: qsTr("Toggle search functionality in overview") + + onPressed: { + overviewScope.searchEnabled = !overviewScope.searchEnabled + } + } +} \ No newline at end of file diff --git a/config/quickshell/modules/overview/OverviewWidget.qml b/config/quickshell/modules/overview/OverviewWidget.qml new file mode 100644 index 00000000..73dbbc26 --- /dev/null +++ b/config/quickshell/modules/overview/OverviewWidget.qml @@ -0,0 +1,341 @@ +import "root:/" +import "root:/services/" +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import QtQuick +import QtQuick.Effects +import QtQuick.Layouts +import Quickshell +import Quickshell.Io +import Quickshell.Widgets +import Quickshell.Wayland +import Quickshell.Hyprland + +Item { + id: root + required property var panelWindow + readonly property HyprlandMonitor monitor: Hyprland.monitorFor(panelWindow.screen) + readonly property var toplevels: ToplevelManager.toplevels + readonly property int workspacesShown: ConfigOptions.overview.numOfRows * ConfigOptions.overview.numOfCols + readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / workspacesShown) + property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor.id) + property var windows: HyprlandData.windowList + property var windowByAddress: HyprlandData.windowByAddress + property var windowAddresses: HyprlandData.addresses + property var monitorData: HyprlandData.monitors.find(m => m.id === root.monitor.id) + property real scale: ConfigOptions.overview.scale + property color activeBorderColor: Appearance.m3colors.m3secondary + + property real workspaceImplicitWidth: Math.max(100, (monitorData?.transform % 2 === 1) ? + ((monitor.height - monitorData?.reserved[0] - monitorData?.reserved[2]) * root.scale / monitor.scale) : + ((monitor.width - monitorData?.reserved[0] - monitorData?.reserved[2]) * root.scale / monitor.scale)) + property real workspaceImplicitHeight: Math.max(60, (monitorData?.transform % 2 === 1) ? + ((monitor.width - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale) : + ((monitor.height - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale)) + + property real workspaceNumberMargin: 80 + property real workspaceNumberSize: Math.min(workspaceImplicitHeight, workspaceImplicitWidth) * monitor.scale + property int workspaceZ: 0 + property int windowZ: 1 + property int windowDraggingZ: 99999 + property real workspaceSpacing: 5 + + property int draggingFromWorkspace: -1 + property int draggingTargetWorkspace: -1 + + implicitWidth: overviewBackground.implicitWidth + Appearance.sizes.elevationMargin * 2 + implicitHeight: overviewBackground.implicitHeight + Appearance.sizes.elevationMargin * 2 + + property Component windowComponent: OverviewWindow {} + property list windowWidgets: [] + + // Shared wallpaper image - loaded once and reused + Image { + id: sharedWallpaper + source: Appearance.background_image || "" + visible: false // Hidden as it's only used as a source + cache: true + asynchronous: true + smooth: true + opacity: Appearance.workpaceTransparency // Adds slight transparency (0.0 = fully transparent, 1.0 = fully opaque) + } + + StyledRectangularShadow { + target: overviewBackground + } + Rectangle { // Background + id: overviewBackground + property real padding: 10 + anchors.fill: parent + anchors.margins: Appearance.sizes.elevationMargin + border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.2) + border.width : 2 + + implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2 + implicitHeight: workspaceColumnLayout.implicitHeight + padding * 2 + radius: Appearance.rounding.screenRounding * root.scale + padding + color: Appearance.colors.colLayer0 + + + ColumnLayout { // Workspaces + id: workspaceColumnLayout + + z: root.workspaceZ + anchors.centerIn: parent + spacing: workspaceSpacing + Repeater { + model: ConfigOptions.overview.numOfRows + delegate: RowLayout { + id: row + property int rowIndex: index + spacing: workspaceSpacing + + Repeater { // Workspace repeater + model: ConfigOptions.overview.numOfCols + Rectangle { // Workspace + id: workspace + property int colIndex: index + property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * ConfigOptions.overview.numOfCols + colIndex + 1 + property color defaultWorkspaceColor: Appearance.colors.colLayer1 + property color hoveredWorkspaceColor: ColorUtils.mix(defaultWorkspaceColor, Appearance.colors.colLayer1Hover, 0.1) + property color hoveredBorderColor: Appearance.colors.colLayer2Hover + property bool hoveredWhileDragging: false + readonly property int padding: ConfigOptions.overview.windowPadding + + Layout.preferredWidth: root.workspaceImplicitWidth + Layout.preferredHeight: root.workspaceImplicitHeight + Layout.minimumWidth: 100 + Layout.minimumHeight: 60 + + width: root.workspaceImplicitWidth + height: root.workspaceImplicitHeight + color: "transparent" + radius: Appearance.rounding.screenRounding * root.scale + clip: true + opacity: Appearance.workpaceTransparency // Adds slight transparency (0.0 = fully transparent, 1.0 = fully opaque) + + + // Efficient wallpaper using ShaderEffectSource + Rectangle { + id: wallpaperContainer + anchors.fill: parent + anchors.margins: 2 // Leave space for border + radius: workspace.radius - 2 + color: workspace.defaultWorkspaceColor // Fallback color + clip: true + + ShaderEffectSource { + id: wallpaperSource + anchors.fill: parent + sourceItem: sharedWallpaper + visible: sharedWallpaper.status === Image.Ready + smooth: true + + // Scale to fill while preserving aspect ratio + transform: Scale { + property real aspectRatio: sharedWallpaper.implicitWidth / Math.max(1, sharedWallpaper.implicitHeight) + property real containerRatio: wallpaperContainer.width / Math.max(1, wallpaperContainer.height) + + xScale: aspectRatio > containerRatio ? + wallpaperContainer.height * aspectRatio / wallpaperContainer.width : 1 + yScale: aspectRatio > containerRatio ? + 1 : wallpaperContainer.width / (wallpaperContainer.height * aspectRatio) + + origin.x: wallpaperContainer.width / 2 + origin.y: wallpaperContainer.height / 2 + } + } + + // Fallback when image fails to load or isn't ready + Rectangle { + anchors.fill: parent + color: workspace.defaultWorkspaceColor + visible: sharedWallpaper.status !== Image.Ready + } + + // Optional: Add overlay for better text readability and hover effects + Rectangle { + anchors.fill: parent + color: hoveredWhileDragging ? hoveredWorkspaceColor : "black" + opacity: hoveredWhileDragging ? 0.3 : 0.1 + } + } + + // Border overlay - on top of wallpaper + Rectangle { + anchors.fill: parent + color: "transparent" + radius: parent.radius + border.width: 1 + border.color: hoveredWhileDragging ? hoveredBorderColor : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.6) + z: 10 // Ensure it's on top + } + + StyledText { + // Position in top-left corner with padding + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: 12 // Padding from top edge + anchors.leftMargin: 12 // Padding from left edge + + text: workspaceValue + font.pixelSize: root.workspaceNumberSize * root.scale + font.weight: Font.DemiBold + color: ColorUtils.transparentize(Appearance.colors.colOnLayer1, 0.8) + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignTop + z: 15 // Above border + } + + MouseArea { + id: workspaceArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton + z: 20 // Above all visual elements + onClicked: { + if (root.draggingTargetWorkspace === -1) { + GlobalStates.overviewOpen = false + Hyprland.dispatch(`workspace ${workspaceValue}`) + } + } + } + + DropArea { + anchors.fill: parent + z: 20 // Same level as MouseArea + onEntered: { + root.draggingTargetWorkspace = workspaceValue + if (root.draggingFromWorkspace == root.draggingTargetWorkspace) return; + hoveredWhileDragging = true + } + onExited: { + hoveredWhileDragging = false + if (root.draggingTargetWorkspace == workspaceValue) root.draggingTargetWorkspace = -1 + } + } + + } + } + } + } + } + + Item { // Windows & focused workspace indicator + id: windowSpace + anchors.centerIn: parent + implicitWidth: workspaceColumnLayout.implicitWidth + implicitHeight: workspaceColumnLayout.implicitHeight + + Repeater { // Window repeater + model: ScriptModel { + values: windowAddresses.filter((address) => { + var win = windowByAddress[address] + return (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown) + }) + } + delegate: OverviewWindow { + id: window + windowData: windowByAddress[modelData] + monitorData: root.monitorData + scale: root.scale + availableWorkspaceWidth: root.workspaceImplicitWidth + availableWorkspaceHeight: root.workspaceImplicitHeight + + property bool atInitPosition: (initX == x && initY == y) + restrictToWorkspace: Drag.active || atInitPosition + + property int workspaceColIndex: (windowData?.workspace.id - 1) % ConfigOptions.overview.numOfCols + property int workspaceRowIndex: Math.floor((windowData?.workspace.id - 1) % root.workspacesShown / ConfigOptions.overview.numOfCols) + xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex + yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * workspaceRowIndex + + Timer { + id: updateWindowPosition + interval: ConfigOptions.hacks.arbitraryRaceConditionDelay + repeat: false + running: false + onTriggered: { + window.x = Math.max((windowData?.at[0] - monitorData?.reserved[0]) * root.scale, 0) + xOffset + window.y = Math.max((windowData?.at[1] - monitorData?.reserved[1]) * root.scale, 0) + yOffset + } + } + + z: atInitPosition ? root.windowZ : root.windowDraggingZ + Drag.hotSpot.x: targetWindowWidth / 2 + Drag.hotSpot.y: targetWindowHeight / 2 + MouseArea { + id: dragArea + anchors.fill: parent + hoverEnabled: true + onEntered: hovered = true + onExited: hovered = false + acceptedButtons: Qt.LeftButton | Qt.MiddleButton + drag.target: parent + onPressed: { + root.draggingFromWorkspace = windowData?.workspace.id + window.pressed = true + window.Drag.active = true + window.Drag.source = window + } + onReleased: { + const targetWorkspace = root.draggingTargetWorkspace + window.pressed = false + window.Drag.active = false + root.draggingFromWorkspace = -1 + if (targetWorkspace !== -1 && targetWorkspace !== windowData?.workspace.id) { + Hyprland.dispatch(`movetoworkspacesilent ${targetWorkspace}, address:${window.windowData?.address}`) + updateWindowPosition.restart() + } + else { + window.x = window.initX + window.y = window.initY + } + } + onClicked: (event) => { + if (!windowData) return; + + if (event.button === Qt.LeftButton) { + GlobalStates.overviewOpen = false + Hyprland.dispatch(`focuswindow address:${windowData.address}`) + event.accepted = true + } else if (event.button === Qt.MiddleButton) { + Hyprland.dispatch(`closewindow address:${windowData.address}`) + event.accepted = true + } + } + + StyledToolTip { + extraVisibleCondition: false + alternativeVisibleCondition: dragArea.containsMouse && !window.Drag.active + content: `${windowData.title}\n[${windowData.class}] ${windowData.xwayland ? "[XWayland] " : ""}\n` + } + } + } + } + + Rectangle { // Focused workspace indicator + id: focusedWorkspaceIndicator + property int activeWorkspaceInGroup: monitor.activeWorkspace?.id - (root.workspaceGroup * root.workspacesShown) + property int activeWorkspaceRowIndex: Math.floor((activeWorkspaceInGroup - 1) / ConfigOptions.overview.numOfCols) + property int activeWorkspaceColIndex: (activeWorkspaceInGroup - 1) % ConfigOptions.overview.numOfCols + x: (root.workspaceImplicitWidth + workspaceSpacing) * activeWorkspaceColIndex + y: (root.workspaceImplicitHeight + workspaceSpacing) * activeWorkspaceRowIndex + z: root.windowZ + width: Math.max(100, root.workspaceImplicitWidth) + height: Math.max(60, root.workspaceImplicitHeight) + color: "transparent" + radius: Appearance.rounding.screenRounding * root.scale + border.width: 2 + border.color: root.activeBorderColor + visible: width > 0 && height > 0 && activeWorkspaceInGroup > 0 + Behavior on x { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + Behavior on y { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + } + } + } +} \ No newline at end of file diff --git a/config/quickshell/modules/overview/OverviewWindow.qml b/config/quickshell/modules/overview/OverviewWindow.qml new file mode 100644 index 00000000..273eff7e --- /dev/null +++ b/config/quickshell/modules/overview/OverviewWindow.qml @@ -0,0 +1,94 @@ +import "root:/services/" +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import Qt5Compat.GraphicalEffects +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Widgets +import Quickshell.Io +import Quickshell.Hyprland + +Rectangle { // Window + id: root + property var windowData + property var monitorData + property var scale + property var availableWorkspaceWidth + property var availableWorkspaceHeight + property bool restrictToWorkspace: true + property real initX: Math.max((windowData?.at[0] - monitorData?.reserved[0]) * root.scale, 0) + xOffset + property real initY: Math.max((windowData?.at[1] - monitorData?.reserved[1]) * root.scale, 0) + yOffset + property real xOffset: 0 + property real yOffset: 0 + + property var targetWindowWidth: windowData?.size[0] * scale + property var targetWindowHeight: windowData?.size[1] * scale + property bool hovered: false + property bool pressed: false + + property var iconToWindowRatio: 0.35 + property var xwaylandIndicatorToIconRatio: 0.35 + property var iconToWindowRatioCompact: 0.6 + property var iconPath: Quickshell.iconPath(AppSearch.guessIcon(windowData?.class), "image-missing") + property bool compactMode: Appearance.font.pixelSize.smaller * 4 > targetWindowHeight || Appearance.font.pixelSize.smaller * 4 > targetWindowWidth + + property bool indicateXWayland: (ConfigOptions.overview.showXwaylandIndicator && windowData?.xwayland) ?? false + + x: initX + y: initY + width: Math.min(windowData?.size[0] * root.scale, (restrictToWorkspace ? windowData?.size[0] : availableWorkspaceWidth - x + xOffset)) + height: Math.min(windowData?.size[1] * root.scale, (restrictToWorkspace ? windowData?.size[1] : availableWorkspaceHeight - y + yOffset)) + + radius: Appearance.rounding.windowRounding * root.scale + color: pressed ? Appearance.colors.colLayer2Active : hovered ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2 + // border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.9) + border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.4) + border.pixelAligned : false + border.width : 2 + + Behavior on x { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + Behavior on y { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + Behavior on width { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + Behavior on height { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + + ColumnLayout { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + spacing: Appearance.font.pixelSize.smaller * 0.5 + + IconImage { + id: windowIcon + Layout.alignment: Qt.AlignHCenter + source: root.iconPath + implicitSize: Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) + + Behavior on implicitSize { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + } + + StyledText { + Layout.leftMargin: 10 + Layout.rightMargin: 10 + visible: !compactMode + Layout.fillWidth: true + Layout.fillHeight: true + horizontalAlignment: Text.AlignHCenter + font.pixelSize: Appearance.font.pixelSize.smaller + font.italic: indicateXWayland ? true : false + elide: Text.ElideRight + text: windowData?.title ?? "" + } + } +} \ No newline at end of file diff --git a/config/quickshell/modules/overview/SearchItem.qml b/config/quickshell/modules/overview/SearchItem.qml new file mode 100644 index 00000000..1363b88d --- /dev/null +++ b/config/quickshell/modules/overview/SearchItem.qml @@ -0,0 +1,220 @@ +// pragma NativeMethodBehavior: AcceptThisObject +import "root:/" +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import "root:/modules/common/functions/string_utils.js" as StringUtils +import "root:/modules/common/functions/fuzzysort.js" as Fuzzy +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Io +import Quickshell.Widgets +import Quickshell.Hyprland + +RippleButton { + id: root + property var entry + property string query + property bool entryShown: entry?.shown ?? true + property string itemType: entry?.type + property string itemName: entry?.name + property string itemIcon: entry?.icon ?? "" + property var itemExecute: entry?.execute + property string fontType: entry?.fontType ?? "main" + property string itemClickActionName: entry?.clickActionName + property string bigText: entry?.bigText ?? "" + property string materialSymbol: entry?.materialSymbol ?? "" + property string cliphistRawString: entry?.cliphistRawString ?? "" + + property string highlightPrefix: `` + property string highlightSuffix: `` + function highlightContent(content, query) { + if (!query || query.length === 0 || content == query || fontType === "monospace") + return StringUtils.escapeHtml(content); + + let contentLower = content.toLowerCase(); + let queryLower = query.toLowerCase(); + + let result = ""; + let lastIndex = 0; + let qIndex = 0; + + for (let i = 0; i < content.length && qIndex < query.length; i++) { + if (contentLower[i] === queryLower[qIndex]) { + // Add non-highlighted part (escaped) + if (i > lastIndex) + result += StringUtils.escapeHtml(content.slice(lastIndex, i)); + // Add highlighted character (escaped) + result += root.highlightPrefix + StringUtils.escapeHtml(content[i]) + root.highlightSuffix; + lastIndex = i + 1; + qIndex++; + } + } + // Add the rest of the string (escaped) + if (lastIndex < content.length) + result += StringUtils.escapeHtml(content.slice(lastIndex)); + + return result; + } + property string displayContent: highlightContent(root.itemName, root.query) + + property list urls: { + if (!root.itemName) return []; + // Regular expression to match URLs + const urlRegex = /https?:\/\/[^\s<>"{}|\\^`[\]]+/gi; + const matches = root.itemName?.match(urlRegex) + ?.filter(url => !url.includes("…")) // Elided = invalid + return matches ? matches : []; + } + + visible: root.entryShown + property int horizontalMargin: 10 + property int buttonHorizontalPadding: 10 + property int buttonVerticalPadding: 5 + property bool keyboardDown: false + + implicitHeight: rowLayout.implicitHeight + root.buttonVerticalPadding * 2 + implicitWidth: rowLayout.implicitWidth + root.buttonHorizontalPadding * 2 + buttonRadius: Appearance.rounding.normal + colBackground: (root.down || root.keyboardDown) ? Appearance.colors.colLayer1Active : + ((root.hovered || root.focus) ? Appearance.colors.colLayer1Hover : + ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHigh, 1)) + colBackgroundHover: Appearance.colors.colLayer1Hover + colRipple: Appearance.colors.colLayer1Active + + background { + anchors.fill: root + anchors.leftMargin: root.horizontalMargin + anchors.rightMargin: root.horizontalMargin + } + + PointingHandInteraction {} + onClicked: { + root.itemExecute() + Hyprland.dispatch("global quickshell:overviewClose") + } + Keys.onPressed: (event) => { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { + root.keyboardDown = true + root.clicked() + event.accepted = true; + } + } + Keys.onReleased: (event) => { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { + root.keyboardDown = false + event.accepted = true; + } + } + + RowLayout { + id: rowLayout + spacing: iconLoader.sourceComponent === null ? 0 : 10 + anchors.fill: parent + anchors.leftMargin: root.horizontalMargin + root.buttonHorizontalPadding + anchors.rightMargin: root.horizontalMargin + root.buttonHorizontalPadding + + // Icon + Loader { + id: iconLoader + active: true + sourceComponent: root.materialSymbol !== "" ? materialSymbolComponent : + root.bigText ? bigTextComponent : + root.itemIcon !== "" ? iconImageComponent : + null + } + + Component { + id: iconImageComponent + IconImage { + source: Quickshell.iconPath(root.itemIcon, "image-missing") + width: 35 + height: 35 + } + } + + Component { + id: materialSymbolComponent + MaterialSymbol { + text: root.materialSymbol + iconSize: 30 + color: Appearance.m3colors.m3onSurface + } + } + + Component { + id: bigTextComponent + StyledText { + text: root.bigText + font.pixelSize: Appearance.font.pixelSize.larger + color: Appearance.m3colors.m3onSurface + } + } + + // Main text + ColumnLayout { + id: contentColumn + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + spacing: 0 + StyledText { + font.pixelSize: Appearance.font.pixelSize.smaller + color: Appearance.colors.colSubtext + visible: root.itemType && root.itemType != qsTr("App") + text: root.itemType + } + RowLayout { + Loader { // Checkmark for copied clipboard entry + visible: itemName == Quickshell.clipboardText && root.cliphistRawString + active: itemName == Quickshell.clipboardText && root.cliphistRawString + sourceComponent: Rectangle { + implicitWidth: activeText.implicitHeight + implicitHeight: activeText.implicitHeight + radius: Appearance.rounding.full + color: Appearance.colors.colPrimary + MaterialSymbol { + id: activeText + anchors.centerIn: parent + text: "check" + font.pixelSize: Appearance.font.pixelSize.normal + color: Appearance.m3colors.m3onPrimary + } + } + } + StyledText { // Item name/content + Layout.fillWidth: true + id: nameText + textFormat: Text.StyledText // RichText also works, but StyledText ensures elide work + font.pixelSize: Appearance.font.pixelSize.small + font.family: Appearance.font.family[root.fontType] + color: Appearance.m3colors.m3onSurface + horizontalAlignment: Text.AlignLeft + elide: Text.ElideRight + text: `${root.displayContent}` + } + } + Loader { // Clipboard image preview + active: root.cliphistRawString && /^\d+\t\[\[.*binary data.*\d+x\d+.*\]\]$/.test(root.cliphistRawString) + sourceComponent: CliphistImage { + Layout.fillWidth: true + entry: root.cliphistRawString + maxWidth: contentColumn.width + maxHeight: 140 + } + } + } + + // Action text + StyledText { + Layout.fillWidth: false + visible: (root.hovered || root.focus) + id: clickAction + font.pixelSize: Appearance.font.pixelSize.normal + color: Appearance.colors.colSubtext + horizontalAlignment: Text.AlignRight + text: root.itemClickActionName + } + } +} diff --git a/config/quickshell/modules/overview/SearchWidget.qml b/config/quickshell/modules/overview/SearchWidget.qml new file mode 100644 index 00000000..fed710ec --- /dev/null +++ b/config/quickshell/modules/overview/SearchWidget.qml @@ -0,0 +1,425 @@ +import "root:/" +import "root:/services/" +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/modules/common/functions/string_utils.js" as StringUtils +import Qt5Compat.GraphicalEffects +import Qt.labs.platform +import QtQuick +import QtQuick.Controls +import QtQuick.Effects +import QtQuick.Layouts +import Quickshell +import Quickshell.Io +import Quickshell.Hyprland + +Item { // Wrapper + id: root + readonly property string xdgConfigHome: Directories.config + property string searchingText: "" + property bool showResults: searchingText != "" + property real searchBarHeight: searchBar.height + Appearance.sizes.elevationMargin * 2 + implicitWidth: searchWidgetContent.implicitWidth + Appearance.sizes.elevationMargin * 2 + implicitHeight: searchWidgetContent.implicitHeight + Appearance.sizes.elevationMargin * 2 + + property string mathResult: "" + + function disableExpandAnimation() { + searchWidthBehavior.enabled = false; + } + + function cancelSearch() { + searchInput.selectAll() + root.searchingText = "" + searchWidthBehavior.enabled = true; + } + + function setSearchingText(text) { + searchInput.text = text; + root.searchingText = text; + } + + property var searchActions: [ + { + action: "img", + execute: () => { + executor.executeCommand(Directories.wallpaperSwitchScriptPath) + } + }, + { + action: "dark", + execute: () => { + executor.executeCommand(`${Directories.wallpaperSwitchScriptPath} --mode dark --noswitch`) + } + }, + { + action: "light", + execute: () => { + executor.executeCommand(`${Directories.wallpaperSwitchScriptPath} --mode light --noswitch`) + } + }, + { + action: "accentcolor", + execute: (args) => { + executor.executeCommand( + `${Directories.wallpaperSwitchScriptPath} --noswitch --color ${args != '' ? ("'"+args+"'") : ""}` + ) + } + }, + { + action: "todo", + execute: (args) => { + Todo.addTask(args) + } + }, + ] + + function focusFirstItemIfNeeded() { + if (searchInput.focus) appResults.currentIndex = 0; // Focus the first item + } + + Timer { + id: nonAppResultsTimer + interval: ConfigOptions.search.nonAppResultDelay + onTriggered: { + mathProcess.calculateExpression(root.searchingText); + } + } + + Process { + id: mathProcess + property list baseCommand: ["qalc", "-t"] + function calculateExpression(expression) { + // mathProcess.running = false + mathProcess.command = baseCommand.concat(expression) + mathProcess.running = true + } + stdout: SplitParser { + onRead: data => { + root.mathResult = data + root.focusFirstItemIfNeeded() + } + } + } + + Process { + id: executor + property list baseCommand: ["bash", "-c"] + function executeCommand(command) { + executor.command = baseCommand.concat( + `${command} || ${ConfigOptions.apps.terminal} fish -C 'echo "${qsTr("Searching for package with that command")}..." && pacman -F ${command}'` + ) + executor.startDetached() + } + } + + Keys.onPressed: (event) => { + // Prevent Esc and Backspace from registering + if (event.key === Qt.Key_Escape) return; + + // Handle Backspace: focus and delete character if not focused + if (event.key === Qt.Key_Backspace) { + if (!searchInput.activeFocus) { + searchInput.forceActiveFocus(); + if (event.modifiers & Qt.ControlModifier) { + // Delete word before cursor + let text = searchInput.text; + let pos = searchInput.cursorPosition; + if (pos > 0) { + // Find the start of the previous word + let left = text.slice(0, pos); + let match = left.match(/(\s*\S+)\s*$/); + let deleteLen = match ? match[0].length : 1; + searchInput.text = text.slice(0, pos - deleteLen) + text.slice(pos); + searchInput.cursorPosition = pos - deleteLen; + } + } else { + // Delete character before cursor if any + if (searchInput.cursorPosition > 0) { + searchInput.text = searchInput.text.slice(0, searchInput.cursorPosition - 1) + + searchInput.text.slice(searchInput.cursorPosition); + searchInput.cursorPosition -= 1; + } + } + // Always move cursor to end after programmatic edit + searchInput.cursorPosition = searchInput.text.length; + event.accepted = true; + } + // If already focused, let TextField handle it + return; + } + + // Only handle visible printable characters (ignore control chars, arrows, etc.) + if ( + event.text && + event.text.length === 1 && + event.key !== Qt.Key_Enter && + event.key !== Qt.Key_Return && + event.text.charCodeAt(0) >= 0x20 // ignore control chars like Backspace, Tab, etc. + ) { + if (!searchInput.activeFocus) { + searchInput.forceActiveFocus(); + // Insert the character at the cursor position + searchInput.text = searchInput.text.slice(0, searchInput.cursorPosition) + + event.text + + searchInput.text.slice(searchInput.cursorPosition); + searchInput.cursorPosition += 1; + event.accepted = true; + } + } + } + + StyledRectangularShadow { + target: searchWidgetContent + } + Rectangle { // Background + id: searchWidgetContent + anchors.centerIn: parent + implicitWidth: columnLayout.implicitWidth + implicitHeight: columnLayout.implicitHeight + radius: Appearance.rounding.large + color: Appearance.colors.colLayer0 + + ColumnLayout { + id: columnLayout + anchors.centerIn: parent + spacing: 0 + + // clip: true + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: searchWidgetContent.width + height: searchWidgetContent.width + radius: searchWidgetContent.radius + } + } + + RowLayout { + id: searchBar + spacing: 5 + MaterialSymbol { + id: searchIcon + Layout.leftMargin: 15 + iconSize: Appearance.font.pixelSize.huge + color: Appearance.m3colors.m3onSurface + text: root.searchingText.startsWith(ConfigOptions.search.prefix.clipboard) ? 'content_paste_search' : '' + } + TextField { // Search box + id: searchInput + + focus: GlobalStates.overviewOpen + Layout.rightMargin: 15 + padding: 15 + renderType: Text.NativeRendering + font { + family: Appearance?.font.family.main ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.small ?? 15 + hintingPreference: Font.PreferFullHinting + } + color: activeFocus ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3onSurfaceVariant + selectedTextColor: Appearance.m3colors.m3onSecondaryContainer + selectionColor: Appearance.m3colors.m3secondaryContainer + placeholderText: qsTr("Search, calculate or run") + placeholderTextColor: Appearance.m3colors.m3outline + implicitWidth: root.searchingText == "" ? Appearance.sizes.searchWidthCollapsed : Appearance.sizes.searchWidth + + Behavior on implicitWidth { + id: searchWidthBehavior + enabled: false + NumberAnimation { + duration: 300 + easing.type: Appearance.animation.elementMove.type + easing.bezierCurve: Appearance.animation.elementMove.bezierCurve + } + } + + onTextChanged: root.searchingText = text + + onAccepted: { + if (appResults.count > 0) { + // Get the first visible delegate and trigger its click + let firstItem = appResults.itemAtIndex(0); + if (firstItem && firstItem.clicked) { + firstItem.clicked(); + } + } + } + + background: null + + cursorDelegate: Rectangle { + width: 1 + color: searchInput.activeFocus ? Appearance.colors.colPrimary : "transparent" + radius: 1 + } + } + } + + Rectangle { // Separator + visible: root.showResults + Layout.fillWidth: true + height: 1 + color: Appearance.m3colors.m3outlineVariant + } + + ListView { // App results + id: appResults + visible: root.showResults + Layout.fillWidth: true + implicitHeight: Math.min(600, appResults.contentHeight + topMargin + bottomMargin) + clip: true + topMargin: 10 + bottomMargin: 10 + spacing: 2 + KeyNavigation.up: searchBar + highlightMoveDuration : 100 + + onFocusChanged: { + if(focus) appResults.currentIndex = 1; + } + + Connections { + target: root + function onSearchingTextChanged() { + if (appResults.count > 0) + appResults.currentIndex = 0; + } + } + + model: ScriptModel { + id: model + values: { // Search results are handled here + ////////////////// Skip? ////////////////// + if(root.searchingText == "") return []; + + ///////////// Special cases /////////////// + if (root.searchingText.startsWith(ConfigOptions.search.prefix.clipboard)) { // Clipboard + const searchString = root.searchingText.slice(ConfigOptions.search.prefix.clipboard.length); + return Cliphist.fuzzyQuery(searchString).map(entry => { + return { + cliphistRawString: entry, + name: entry.replace(/^\s*\S+\s+/, ""), + clickActionName: "", + type: `#${entry.match(/^\s*(\S+)/)?.[1] || ""}`, + execute: () => { + Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`); + } + }; + }).filter(Boolean); + } + if (root.searchingText.startsWith(ConfigOptions.search.prefix.emojis)) { // Clipboard + const searchString = root.searchingText.slice(ConfigOptions.search.prefix.emojis.length); + return Emojis.fuzzyQuery(searchString).map(entry => { + return { + cliphistRawString: entry, + bigText: entry.match(/^\s*(\S+)/)?.[1] || "", + name: entry.replace(/^\s*\S+\s+/, ""), + clickActionName: "", + type: "Emoji", + execute: () => { + Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(entry.match(/^\s*(\S+)/)?.[1])}'`); + } + }; + }).filter(Boolean); + } + + + ////////////////// Init /////////////////// + nonAppResultsTimer.restart(); + const mathResultObject = { + name: root.mathResult, + clickActionName: qsTr("Copy"), + type: qsTr("Math result"), + fontType: "monospace", + materialSymbol: 'calculate', + execute: () => { + Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(root.mathResult)}'`) + } + } + const commandResultObject = { + name: searchingText.replace("file://", ""), + clickActionName: qsTr("Run"), + type: qsTr("Run command"), + fontType: "monospace", + materialSymbol: 'terminal', + execute: () => { + executor.executeCommand(searchingText.startsWith('sudo') ? `${ConfigOptions.apps.terminal} fish -C '${root.searchingText.replace("file://", "")}'` : root.searchingText.replace("file://", "")); + } + } + const launcherActionObjects = root.searchActions + .map(action => { + const actionString = `${ConfigOptions.search.prefix.action}${action.action}`; + if (actionString.startsWith(root.searchingText) || root.searchingText.startsWith(actionString)) { + return { + name: root.searchingText.startsWith(actionString) ? root.searchingText : actionString, + clickActionName: qsTr("Run"), + type: qsTr("Action"), + materialSymbol: 'settings_suggest', + execute: () => { + action.execute(root.searchingText.split(" ").slice(1).join(" ")) + }, + }; + } + return null; + }) + .filter(Boolean); + + let result = []; + + //////////////// Apps ////////////////// + result = result.concat( + AppSearch.fuzzyQuery(root.searchingText) + .map((entry) => { + entry.clickActionName = qsTr("Launch"); + entry.type = qsTr("App"); + return entry; + }) + ); + + ////////// Launcher actions //////////// + result = result.concat(launcherActionObjects); + + /////////// Math result & command ////////// + const startsWithNumber = /^\d/.test(root.searchingText); + if (startsWithNumber) { + result.push(mathResultObject); + result.push(commandResultObject); + } else { + result.push(commandResultObject); + result.push(mathResultObject); + } + + ///////////////// Web search //////////////// + result.push({ + name: root.searchingText, + clickActionName: qsTr("Search"), + type: qsTr("Search the web"), + materialSymbol: 'travel_explore', + execute: () => { + let url = ConfigOptions.search.engineBaseUrl + root.searchingText + for (let site of ConfigOptions.search.excludedSites) { + url += ` -site:${site}`; + } + Qt.openUrlExternally(url); + } + }); + + return result; + } + } + + delegate: SearchItem { // The selectable item for each search result + required property var modelData + anchors.left: parent?.left + anchors.right: parent?.right + entry: modelData + query: root.searchingText.startsWith(ConfigOptions.search.prefix.clipboard) ? + root.searchingText.slice(ConfigOptions.search.prefix.clipboard.length) : + root.searchingText; + } + } + + } + } +} \ No newline at end of file diff --git a/config/quickshell/services/AppSearch.qml b/config/quickshell/services/AppSearch.qml new file mode 100644 index 00000000..876df183 --- /dev/null +++ b/config/quickshell/services/AppSearch.qml @@ -0,0 +1,116 @@ +pragma Singleton + +import "root:/modules/common" +import "root:/modules/common/functions/fuzzysort.js" as Fuzzy +import "root:/modules/common/functions/levendist.js" as Levendist +import Quickshell +import Quickshell.Io + +/** + * - Eases fuzzy searching for applications by name + * - Guesses icon name for window class name + */ +Singleton { + id: root + property bool sloppySearch: ConfigOptions?.search.sloppy ?? false + property real scoreThreshold: 0.2 + property var substitutions: ({ + "code-url-handler": "visual-studio-code", + "Code": "visual-studio-code", + "gnome-tweaks": "org.gnome.tweaks", + "pavucontrol-qt": "pavucontrol", + "wps": "wps-office2019-kprometheus", + "wpsoffice": "wps-office2019-kprometheus", + "footclient": "foot", + "zen": "zen-browser", + }) + property var regexSubstitutions: [ + { + "regex": /^steam_app_(\\d+)$/, + "replace": "steam_icon_$1" + }, + { + "regex": /Minecraft.*/, + "replace": "minecraft" + }, + { + "regex": /.*polkit.*/, + "replace": "system-lock-screen" + }, + { + "regex": /gcr.prompter/, + "replace": "system-lock-screen" + } + ] + + readonly property list list: Array.from(DesktopEntries.applications.values) + .sort((a, b) => a.name.localeCompare(b.name)) + + readonly property var preppedNames: list.map(a => ({ + name: Fuzzy.prepare(`${a.name} `), + entry: a + })) + + function fuzzyQuery(search: string): var { // Idk why list doesn't work + if (root.sloppySearch) { + const results = list.map(obj => ({ + entry: obj, + score: Levendist.computeScore(obj.name.toLowerCase(), search.toLowerCase()) + })).filter(item => item.score > root.scoreThreshold) + .sort((a, b) => b.score - a.score) + return results + .map(item => item.entry) + } + + return Fuzzy.go(search, preppedNames, { + all: true, + key: "name" + }).map(r => { + return r.obj.entry + }); + } + + function iconExists(iconName) { + return (Quickshell.iconPath(iconName, true).length > 0) + && !iconName.includes("image-missing"); + } + + function guessIcon(str) { + if (!str || str.length == 0) return "image-missing"; + + // Normal substitutions + if (substitutions[str]) + return substitutions[str]; + + // Regex substitutions + for (let i = 0; i < regexSubstitutions.length; i++) { + const substitution = regexSubstitutions[i]; + const replacedName = str.replace( + substitution.regex, + substitution.replace, + ); + if (replacedName != str) return replacedName; + } + + // If it gets detected normally, no need to guess + if (iconExists(str)) return str; + + let guessStr = str; + // Guess: Take only app name of reverse domain name notation + guessStr = str.split('.').slice(-1)[0].toLowerCase(); + if (iconExists(guessStr)) return guessStr; + // Guess: normalize to kebab case + guessStr = str.toLowerCase().replace(/\s+/g, "-"); + if (iconExists(guessStr)) return guessStr; + // Guess: First fuzze desktop entry match + const searchResults = root.fuzzyQuery(str); + if (searchResults.length > 0) { + const firstEntry = searchResults[0]; + guessStr = firstEntry.icon + if (iconExists(guessStr)) return guessStr; + } + + // Give up + return str; + } +} diff --git a/config/quickshell/services/ConfigLoader.qml b/config/quickshell/services/ConfigLoader.qml new file mode 100644 index 00000000..051162d1 --- /dev/null +++ b/config/quickshell/services/ConfigLoader.qml @@ -0,0 +1,116 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import "root:/modules/common" +import "root:/modules/common/functions/file_utils.js" as FileUtils +import "root:/modules/common/functions/string_utils.js" as StringUtils +import "root:/modules/common/functions/object_utils.js" as ObjectUtils +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Hyprland +import Qt.labs.platform + +/** + * Loads and manages the shell configuration file. + * The config file is by default at XDG_CONFIG_HOME/quickshell/config.json. + * Automatically reloaded when the file changes, but does not provide a way to save changes. + */ +Singleton { + id: root + property string filePath: Directories.shellConfigPath + property bool firstLoad: true + + function loadConfig() { + configFileView.reload() + } + + function applyConfig(fileContent) { + try { + const json = JSON.parse(fileContent); + + ObjectUtils.applyToQtObject(ConfigOptions, json); + if (root.firstLoad) { + root.firstLoad = false; + } else { + Hyprland.dispatch(`exec notify-send "${qsTr("Shell configuration reloaded")}" "${root.filePath}"`) + } + } catch (e) { + console.error("[ConfigLoader] Error reading file:", e); + Hyprland.dispatch(`exec notify-send "${qsTr("Shell configuration failed to load")}" "${root.filePath}"`) + return; + + } + } + + function setLiveConfigValue(nestedKey, value) { + let keys = nestedKey.split("."); + let obj = ConfigOptions; + let parents = [obj]; + + // Traverse and collect parent objects + for (let i = 0; i < keys.length - 1; ++i) { + if (!obj[keys[i]] || typeof obj[keys[i]] !== "object") { + obj[keys[i]] = {}; + } + obj = obj[keys[i]]; + parents.push(obj); + } + + // Convert value to correct type using JSON.parse when safe + let convertedValue = value; + if (typeof value === "string") { + let trimmed = value.trim(); + if (trimmed === "true" || trimmed === "false" || !isNaN(Number(trimmed))) { + try { + convertedValue = JSON.parse(trimmed); + } catch (e) { + convertedValue = value; + } + } + } + + console.log(parents.join(".")); + console.log(`[ConfigLoader] Setting live config value: ${nestedKey} = ${convertedValue}`); + obj[keys[keys.length - 1]] = convertedValue; + } + + function saveConfig() { + const plainConfig = ObjectUtils.toPlainObject(ConfigOptions) + Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(JSON.stringify(plainConfig, null, 2))}' > '${root.filePath}'`) + } + + Timer { + id: delayedFileRead + interval: ConfigOptions.hacks.arbitraryRaceConditionDelay + repeat: false + running: false + onTriggered: { + root.applyConfig(configFileView.text()) + } + } + + FileView { + id: configFileView + path: Qt.resolvedUrl(root.filePath) + watchChanges: true + onFileChanged: { + console.log("[ConfigLoader] File changed, reloading...") + this.reload() + delayedFileRead.start() + } + onLoadedChanged: { + const fileContent = configFileView.text() + root.applyConfig(fileContent) + } + onLoadFailed: (error) => { + if(error == FileViewError.FileNotFound) { + console.log("[ConfigLoader] File not found, creating new file.") + root.saveConfig() + Hyprland.dispatch(`exec notify-send "${qsTr("Shell configuration created")}" "${root.filePath}"`) + } else { + Hyprland.dispatch(`exec notify-send "${qsTr("Shell configuration failed to load")}" "${root.filePath}"`) + } + } + } +} diff --git a/config/quickshell/services/HyprlandData.qml b/config/quickshell/services/HyprlandData.qml new file mode 100644 index 00000000..2b88ad9c --- /dev/null +++ b/config/quickshell/services/HyprlandData.qml @@ -0,0 +1,69 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import Quickshell.Hyprland + +/** + * Provides access to some Hyprland data not available in Quickshell.Hyprland. + */ +Singleton { + id: root + property var windowList: [] + property var addresses: [] + property var windowByAddress: ({}) + property var monitors: [] + + function updateWindowList() { + getClients.running = true + getMonitors.running = true + } + + Component.onCompleted: { + updateWindowList() + } + + Connections { + target: Hyprland + + function onRawEvent(event) { + // Filter out redundant old v1 events for the same thing + if(event.name in [ + "activewindow", "focusedmon", "monitoradded", + "createworkspace", "destroyworkspace", "moveworkspace", + "activespecial", "movewindow", "windowtitle" + ]) return ; + updateWindowList() + } + } + + Process { + id: getClients + command: ["bash", "-c", "hyprctl clients -j | jq -c"] + stdout: SplitParser { + onRead: (data) => { + root.windowList = JSON.parse(data) + let tempWinByAddress = {} + for (var i = 0; i < root.windowList.length; ++i) { + var win = root.windowList[i] + tempWinByAddress[win.address] = win + } + root.windowByAddress = tempWinByAddress + root.addresses = root.windowList.map((win) => win.address) + } + } + } + Process { + id: getMonitors + command: ["bash", "-c", "hyprctl monitors -j | jq -c"] + stdout: SplitParser { + onRead: (data) => { + root.monitors = JSON.parse(data) + } + } + } +} + diff --git a/config/quickshell/services/HyprlandKeybinds.qml b/config/quickshell/services/HyprlandKeybinds.qml new file mode 100644 index 00000000..189ba76d --- /dev/null +++ b/config/quickshell/services/HyprlandKeybinds.qml @@ -0,0 +1,73 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import "root:/modules/common" +import "root:/modules/common/functions/file_utils.js" as FileUtils +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import Quickshell.Hyprland + +/** + * A service that provides access to Hyprland keybinds. + * Uses the `get_keybinds.py` script to parse comments in config files in a certain format and convert to JSON. + */ +Singleton { + id: root + property string keybindParserPath: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/scripts/hyprland/get_keybinds.py`) + property string defaultKeybindConfigPath: FileUtils.trimFileProtocol(`${Directories.config}/hypr/hyprland/keybinds.conf`) + property string userKeybindConfigPath: FileUtils.trimFileProtocol(`${Directories.config}/hypr/custom/keybinds.conf`) + property var defaultKeybinds: {"children": []} + property var userKeybinds: {"children": []} + property var keybinds: ({ + children: [ + ...(defaultKeybinds.children ?? []), + ...(userKeybinds.children ?? []), + ] + }) + + Connections { + target: Hyprland + + function onRawEvent(event) { + if (event.name == "configreloaded") { + getDefaultKeybinds.running = true + getUserKeybinds.running = true + } + } + } + + Process { + id: getDefaultKeybinds + running: true + command: [root.keybindParserPath, "--path", root.defaultKeybindConfigPath,] + + stdout: SplitParser { + onRead: data => { + try { + root.defaultKeybinds = JSON.parse(data) + } catch (e) { + console.error("[CheatsheetKeybinds] Error parsing keybinds:", e) + } + } + } + } + + Process { + id: getUserKeybinds + running: true + command: [root.keybindParserPath, "--path", root.userKeybindConfigPath] + + stdout: SplitParser { + onRead: data => { + try { + root.userKeybinds = JSON.parse(data) + } catch (e) { + console.error("[CheatsheetKeybinds] Error parsing keybinds:", e) + } + } + } + } +} + diff --git a/config/quickshell/services/MaterialThemeLoader.qml b/config/quickshell/services/MaterialThemeLoader.qml new file mode 100644 index 00000000..cd4eb686 --- /dev/null +++ b/config/quickshell/services/MaterialThemeLoader.qml @@ -0,0 +1,58 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import "root:/modules/common" +import QtQuick +import Quickshell +import Quickshell.Io + +/** + * Automatically reloads generated material colors. + * It is necessary to run reapplyTheme() on startup because Singletons are lazily loaded. + */ +Singleton { + id: root + property string filePath: Directories.generatedMaterialThemePath + + function reapplyTheme() { + themeFileView.reload() + } + + function applyColors(fileContent) { + const json = JSON.parse(fileContent) + for (const key in json) { + if (json.hasOwnProperty(key)) { + // Convert snake_case to CamelCase + const camelCaseKey = key.replace(/_([a-z])/g, (g) => g[1].toUpperCase()) + const m3Key = `m3${camelCaseKey}` + Appearance.m3colors[m3Key] = json[key] + } + } + + Appearance.m3colors.darkmode = (Appearance.m3colors.m3background.hslLightness < 0.5) + } + + Timer { + id: delayedFileRead + interval: ConfigOptions?.hacks?.arbitraryRaceConditionDelay ?? 100 + repeat: false + running: false + onTriggered: { + root.applyColors(themeFileView.text()) + } + } + + FileView { + id: themeFileView + path: Qt.resolvedUrl(root.filePath) + watchChanges: true + onFileChanged: { + this.reload() + delayedFileRead.start() + } + onLoadedChanged: { + const fileContent = themeFileView.text() + root.applyColors(fileContent) + } + } +} diff --git a/config/quickshell/shell.qml b/config/quickshell/shell.qml new file mode 100644 index 00000000..36842c2b --- /dev/null +++ b/config/quickshell/shell.qml @@ -0,0 +1,27 @@ +//@ pragma UseQApplication +//@ pragma Env QS_NO_RELOAD_POPUP=1 +//@ pragma Env QT_QUICK_CONTROLS_STYLE=Basic + +import "./modules/common/" +import "./modules/overview/" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window +import Quickshell +import "./services/" + +ShellRoot { + // Enable/disable modules here. False = not loaded at all, so rest assured + // no unnecessary stuff will take up memory if you decide to only use, say, the overview. + property bool enableOverview: true + + // Force initialization of some singletons + Component.onCompleted: { + MaterialThemeLoader.reapplyTheme() + ConfigLoader.loadConfig() + } + + Loader { active: enableOverview; sourceComponent: Overview {} } + +} \ No newline at end of file diff --git a/config/wallust/templates/qml_color.json b/config/wallust/templates/qml_color.json new file mode 100644 index 00000000..70283080 --- /dev/null +++ b/config/wallust/templates/qml_color.json @@ -0,0 +1,21 @@ +{ + "background": "#1e1e2e", + "onBackground": "#bac2de", + "surfaceContainerLow": "{{color4}}", + "surfaceContainer": "{{color6}}", + "surfaceContainerHigh": "{{color3}}", + "surfaceContainerHighest": "{{color2}}", + "onSurface": "#EAE0E7", + "onSurfaceVariant": "#CFC3CD", + "outline": "{{color7}}", + "scrim": "#000000", + "shadow": "#000000", + "primary": "{{color7}}", + "primaryContainer": "{{color7}}", + "secondary": "#D5C0D7", + "secondaryContainer": "{{color5}}", + "onPrimary": "#FFFFFF", + "onPrimaryContainer": "#21005D", + "onSecondaryContainer": "#F2DCF3", + "outlineVariant": "{{color5}}" +} \ No newline at end of file diff --git a/config/wallust/wallust.toml b/config/wallust/wallust.toml index a7f66721..d1f40ab2 100644 --- a/config/wallust/wallust.toml +++ b/config/wallust/wallust.toml @@ -49,6 +49,9 @@ waybar.target = '~/.config/waybar/wallust/colors-waybar.css' kitty.template = 'colors-kitty.conf' kitty.target = '~/.config/kitty/kitty-themes/01-Wallust.conf' +quickshell.template = 'qml_color.json' +quickshell.target = '~/.config/quickshell/qml_color.json' + #swaync.template = 'colors-swaync.css' #swaync.target = '~/.config/swaync/wallust/colors-wallust.css' -- cgit v1.2.3 From ae78ca7ad6ff17b64125787b31c913d0ab873890 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Mon, 9 Jun 2025 11:34:52 +0530 Subject: quickshell startup --- config/hypr/UserConfigs/Startup_Apps.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index 702f9a90..91ff9cd0 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -30,6 +30,7 @@ exec-once = swaync #exec-once = blueman-applet #exec-once = rog-control-center exec-once = waybar +exec-once = qs #clipboard manager exec-once = wl-paste --type text --watch cliphist store -- cgit v1.2.3 From 3bda8183fccb41b67ccf9f02591249f805c94c88 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Mon, 9 Jun 2025 11:52:04 +0530 Subject: Removed hardcoded path --- config/quickshell/modules/common/Appearance.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/quickshell/modules/common/Appearance.qml b/config/quickshell/modules/common/Appearance.qml index 45a4894d..29eca00c 100644 --- a/config/quickshell/modules/common/Appearance.qml +++ b/config/quickshell/modules/common/Appearance.qml @@ -20,7 +20,7 @@ Singleton { property real workpaceTransparency: 0.8 // property real transparency: 0.15 // property real contentTransparency: 0.5 - property string background_image: "file:///home/itachi/.config/rofi/.current_wallpaper" + property string background_image: Directories.config + "/rofi/.current_wallpaper" m3colors: QtObject { property bool darkmode: true -- cgit v1.2.3 From d46077fe5ac56afbd63dc1222e649f10435b05e2 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Mon, 9 Jun 2025 12:02:14 +0530 Subject: Enabled search --- config/quickshell/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/quickshell/config.json b/config/quickshell/config.json index f98f9f69..33fca8e9 100644 --- a/config/quickshell/config.json +++ b/config/quickshell/config.json @@ -24,7 +24,7 @@ "arbitraryRaceConditionDelay": 20 }, "search": { - "searchEnabled": false, + "searchEnabled": true, "nonAppResultDelay": 30, "prefix": { "action": "/", -- cgit v1.2.3 From 1462996cc5256e6337eafc226423de5559214c7f Mon Sep 17 00:00:00 2001 From: Kiran George Date: Mon, 16 Jun 2025 08:15:18 +0530 Subject: Expose font size and family in config --- config/quickshell/config.json | 24 ++++++++++++- config/quickshell/modules/common/ConfigOptions.qml | 1 + .../quickshell/modules/overview/OverviewWidget.qml | 4 ++- config/quickshell/services/ConfigLoader.qml | 39 +++++++++++++++++++--- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/config/quickshell/config.json b/config/quickshell/config.json index 33fca8e9..f6c9e843 100644 --- a/config/quickshell/config.json +++ b/config/quickshell/config.json @@ -15,7 +15,8 @@ "numOfCols": 5, "showXwaylandIndicator": true, "windowPadding": 6, - "position": 1 + "position": 1, + "workspaceNumberSize": 220 }, "resources": { "updateInterval": 3000 @@ -34,5 +35,26 @@ }, "bar": { "bottom": false + }, + "font": { + "family": { + "main": "Open Sans", + "title": "JetBrains Mono NF", + "iconMaterial": "FiraConde Nerd Font", + "iconNerd": "SpaceMono NF", + "monospace": "JetBrains Mono NF", + "reading": "Readex Pro" + }, + "pixelSize": { + "smallest": 10, + "smaller": 13, + "small": 15, + "normal": 16, + "large": 17, + "larger": 19, + "huge": 22, + "hugeass": 23, + "title": 28 + } } } \ No newline at end of file diff --git a/config/quickshell/modules/common/ConfigOptions.qml b/config/quickshell/modules/common/ConfigOptions.qml index 61e6ab8e..25f0de05 100644 --- a/config/quickshell/modules/common/ConfigOptions.qml +++ b/config/quickshell/modules/common/ConfigOptions.qml @@ -16,6 +16,7 @@ Singleton { property bool showXwaylandIndicator: true property real windowPadding: 6 property real position: 1 // 0: top | 1: middle | 2: bottom + property real workspaceNumberSize: 120 // Set 0, dynamic calculation based on monitor size } property QtObject resources: QtObject { diff --git a/config/quickshell/modules/overview/OverviewWidget.qml b/config/quickshell/modules/overview/OverviewWidget.qml index 73dbbc26..63633602 100644 --- a/config/quickshell/modules/overview/OverviewWidget.qml +++ b/config/quickshell/modules/overview/OverviewWidget.qml @@ -35,7 +35,9 @@ Item { ((monitor.height - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale)) property real workspaceNumberMargin: 80 - property real workspaceNumberSize: Math.min(workspaceImplicitHeight, workspaceImplicitWidth) * monitor.scale + property real workspaceNumberSize: (ConfigOptions.overview.workspaceNumberSize > 0) + ? ConfigOptions.overview.workspaceNumberSize + : Math.min(workspaceImplicitHeight, workspaceImplicitWidth) * monitor.scale property int workspaceZ: 0 property int windowZ: 1 property int windowDraggingZ: 99999 diff --git a/config/quickshell/services/ConfigLoader.qml b/config/quickshell/services/ConfigLoader.qml index 051162d1..5f16bf55 100644 --- a/config/quickshell/services/ConfigLoader.qml +++ b/config/quickshell/services/ConfigLoader.qml @@ -29,7 +29,32 @@ Singleton { try { const json = JSON.parse(fileContent); - ObjectUtils.applyToQtObject(ConfigOptions, json); + // Extract font configuration if it exists + let fontConfig = null; + let configForOptions = {}; + + // Copy all properties except font to configForOptions + for (let key in json) { + if (key !== "font") { + configForOptions[key] = json[key]; + } else { + fontConfig = json[key]; + } + } + + // Apply the non-font configuration to ConfigOptions + ObjectUtils.applyToQtObject(ConfigOptions, configForOptions); + + // Apply font configuration to Appearance if it exists + if (fontConfig && typeof Appearance !== 'undefined') { + if (fontConfig.family && Appearance.font && Appearance.font.family) { + ObjectUtils.applyToQtObject(Appearance.font.family, fontConfig.family); + } + if (fontConfig.pixelSize && Appearance.font && Appearance.font.pixelSize) { + ObjectUtils.applyToQtObject(Appearance.font.pixelSize, fontConfig.pixelSize); + } + } + if (root.firstLoad) { root.firstLoad = false; } else { @@ -39,13 +64,19 @@ Singleton { console.error("[ConfigLoader] Error reading file:", e); Hyprland.dispatch(`exec notify-send "${qsTr("Shell configuration failed to load")}" "${root.filePath}"`) return; - } } function setLiveConfigValue(nestedKey, value) { let keys = nestedKey.split("."); - let obj = ConfigOptions; + let targetObject = ConfigOptions; + + // Check if this is a font-related configuration + if (keys[0] === "font" && typeof Appearance !== 'undefined') { + targetObject = Appearance; + } + + let obj = targetObject; let parents = [obj]; // Traverse and collect parent objects @@ -113,4 +144,4 @@ Singleton { } } } -} +} \ No newline at end of file -- cgit v1.2.3 From 0cda8f13953d0f4cc6126d4810c04452cc3375b8 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sat, 21 Jun 2025 17:26:23 +0530 Subject: Refactored for better colour and font expose and cleaned up unused code --- config/quickshell/.claude/settings.local.json | 9 ++ config/quickshell/GlobalStates.qml | 2 - config/quickshell/config.json | 25 ++-- config/quickshell/modules/common/Appearance.qml | 75 +++++------- config/quickshell/modules/common/Directories.qml | 3 +- .../modules/common/functions/string_utils.js | 135 --------------------- .../modules/common/widgets/DialogButton.qml | 4 +- .../modules/common/widgets/MaterialSymbol.qml | 9 +- .../modules/common/widgets/StyledText.qml | 7 +- .../modules/common/widgets/StyledTextArea.qml | 10 +- .../modules/common/widgets/StyledToolTip.qml | 2 +- .../quickshell/modules/overview/OverviewWidget.qml | 6 +- .../quickshell/modules/overview/OverviewWindow.qml | 8 +- config/quickshell/modules/overview/SearchItem.qml | 24 ++-- .../quickshell/modules/overview/SearchWidget.qml | 18 +-- config/quickshell/qml_color.json | 17 +++ config/quickshell/services/ConfigLoader.qml | 5 +- config/quickshell/services/MaterialThemeLoader.qml | 2 +- config/quickshell/shell.qml | 1 - config/wallust/templates/qml_color.json | 34 +++--- 20 files changed, 128 insertions(+), 268 deletions(-) create mode 100644 config/quickshell/.claude/settings.local.json create mode 100644 config/quickshell/qml_color.json diff --git a/config/quickshell/.claude/settings.local.json b/config/quickshell/.claude/settings.local.json new file mode 100644 index 00000000..d474da6e --- /dev/null +++ b/config/quickshell/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(find:*)", + "Bash(grep:*)" + ], + "deny": [] + } +} \ No newline at end of file diff --git a/config/quickshell/GlobalStates.qml b/config/quickshell/GlobalStates.qml index 7875645c..84b53c03 100644 --- a/config/quickshell/GlobalStates.qml +++ b/config/quickshell/GlobalStates.qml @@ -1,8 +1,6 @@ import "root:/modules/common/" import QtQuick import Quickshell -import Quickshell.Hyprland -import Quickshell.Io pragma Singleton pragma ComponentBehavior: Bound diff --git a/config/quickshell/config.json b/config/quickshell/config.json index f6c9e843..cd9c2c4d 100644 --- a/config/quickshell/config.json +++ b/config/quickshell/config.json @@ -16,7 +16,7 @@ "showXwaylandIndicator": true, "windowPadding": 6, "position": 1, - "workspaceNumberSize": 220 + "workspaceNumberSize": 0 }, "resources": { "updateInterval": 3000 @@ -38,23 +38,16 @@ }, "font": { "family": { - "main": "Open Sans", - "title": "JetBrains Mono NF", - "iconMaterial": "FiraConde Nerd Font", - "iconNerd": "SpaceMono NF", - "monospace": "JetBrains Mono NF", - "reading": "Readex Pro" + "uiFont": "Open Sans", + "iconFont": "FiraConde Nerd Font", + "codeFont": "JetBrains Mono NF" }, "pixelSize": { - "smallest": 10, - "smaller": 13, - "small": 15, - "normal": 16, - "large": 17, - "larger": 19, - "huge": 22, - "hugeass": 23, - "title": 28 + "textSmall": 13, + "textBase": 15, + "textMedium": 16, + "textLarge": 19, + "iconLarge": 22 } } } \ No newline at end of file diff --git a/config/quickshell/modules/common/Appearance.qml b/config/quickshell/modules/common/Appearance.qml index 29eca00c..675f1d1e 100644 --- a/config/quickshell/modules/common/Appearance.qml +++ b/config/quickshell/modules/common/Appearance.qml @@ -18,53 +18,47 @@ Singleton { property real transparency: 0.5 property real contentTransparency: 0.1 property real workpaceTransparency: 0.8 - // property real transparency: 0.15 - // property real contentTransparency: 0.5 property string background_image: Directories.config + "/rofi/.current_wallpaper" m3colors: QtObject { property bool darkmode: true property bool transparent: true - property color m3background: "#161217" - property color m3onBackground: "#EAE0E7" - property color m3surfaceContainerLow: "#1F1A1F" - property color m3surfaceContainer: "#231E23" - property color m3surfaceContainerHigh: "#2D282E" - property color m3surfaceContainerHighest: "#383339" - property color m3onSurface: "#EAE0E7" - property color m3onSurfaceVariant: "#CFC3CD" - property color m3outline: "#cba6f7" - property color m3scrim: "#000000" - property color m3shadow: "#000000" - property color m3primary: "#E5B6F2" - property color m3primaryContainer: "#5D386A" - property color m3secondary: "#D5C0D7" - property color m3secondaryContainer: "#534457" - property color m3onPrimary: "#452152" - property color m3onPrimaryContainer: "#F9D8FF" - property color m3onSecondaryContainer: "#F2DCF3" - property color m3outlineVariant: "#4C444D" + property color m3windowBackground: "#161217" + property color m3primaryText: "#EAE0E7" + property color m3layerBackground1: "#1F1A1F" + property color m3layerBackground2: "#231E23" + property color m3layerBackground3: "#2D282E" + property color m3surfaceText: "#EAE0E7" + property color m3secondaryText: "#CFC3CD" + property color m3borderPrimary: "#cba6f7" + property color m3shadowColor: "#000000" + property color m3accentPrimary: "#E5B6F2" + property color m3accentSecondary: "#D5C0D7" + property color m3selectionBackground: "#534457" + property color m3accentPrimaryText: "#452152" + property color m3selectionText: "#F2DCF3" + property color m3borderSecondary: "#4C444D" property color colTooltip: "#1e1e2e" property color colOnTooltip: "#F8F9FA" } colors: QtObject { - property color colSubtext: m3colors.m3outline - property color colLayer0: ColorUtils.transparentize(m3colors.m3background, root.transparency) - property color colLayer1: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainerLow, m3colors.m3background, 0.7), root.contentTransparency); - property color colOnLayer1: m3colors.m3onSurfaceVariant; - property color colLayer2: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3surfaceContainer, m3colors.m3surfaceContainerHigh, 0.55), root.contentTransparency) - property color colOnLayer2: m3colors.m3onSurface; + property color colSubtext: m3colors.m3borderPrimary + property color colLayer0: ColorUtils.transparentize(m3colors.m3windowBackground, root.transparency) + property color colLayer1: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3layerBackground1, m3colors.m3windowBackground, 0.7), root.contentTransparency); + property color colOnLayer1: m3colors.m3secondaryText; + property color colLayer2: ColorUtils.transparentize(ColorUtils.mix(m3colors.m3layerBackground2, m3colors.m3layerBackground3, 0.55), root.contentTransparency) + property color colOnLayer2: m3colors.m3surfaceText; property color colLayer1Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer1, colOnLayer1, 0.92), root.contentTransparency) property color colLayer1Active: ColorUtils.transparentize(ColorUtils.mix(colLayer1, colOnLayer1, 0.85), root.contentTransparency); property color colLayer2Hover: ColorUtils.transparentize(ColorUtils.mix(colLayer2, colOnLayer2, 0.90), root.contentTransparency) property color colLayer2Active: ColorUtils.transparentize(ColorUtils.mix(colLayer2, colOnLayer2, 0.80), root.contentTransparency); - property color colPrimary: m3colors.m3primary + property color colPrimary: m3colors.m3accentPrimary property color colPrimaryHover: ColorUtils.mix(colors.colPrimary, colLayer1Hover, 0.87) property color colPrimaryActive: ColorUtils.mix(colors.colPrimary, colLayer1Active, 0.7) - property color colShadow: ColorUtils.transparentize(m3colors.m3shadow, 0.7) + property color colShadow: ColorUtils.transparentize(m3colors.m3shadowColor, 0.7) } rounding: QtObject { @@ -82,23 +76,16 @@ Singleton { font: QtObject { property QtObject family: QtObject { - property string main: "Open Sans" - property string title: "JetBrains Mono NF" - property string iconMaterial: "FiraConde Nerd Font" - property string iconNerd: "SpaceMono NF" - property string monospace: "JetBrains Mono NF" - property string reading: "Readex Pro" + property string uiFont: "Open Sans" + property string iconFont: "FiraConde Nerd Font" + property string codeFont: "JetBrains Mono NF" } property QtObject pixelSize: QtObject { - property int smallest: 10 - property int smaller: 13 - property int small: 15 - property int normal: 16 - property int large: 17 - property int larger: 19 - property int huge: 22 - property int hugeass: 23 - property int title: 28 + property int textSmall: 13 + property int textBase: 15 + property int textMedium: 16 + property int textLarge: 19 + property int iconLarge: 22 } } diff --git a/config/quickshell/modules/common/Directories.qml b/config/quickshell/modules/common/Directories.qml index 9ddf43bd..694c73df 100644 --- a/config/quickshell/modules/common/Directories.qml +++ b/config/quickshell/modules/common/Directories.qml @@ -11,9 +11,10 @@ Singleton { // XDG Dirs, with "file://" readonly property string config: StandardPaths.standardLocations(StandardPaths.ConfigLocation)[0] readonly property string state: StandardPaths.standardLocations(StandardPaths.StateLocation)[0] + readonly property string gen_cache: StandardPaths.standardLocations(StandardPaths.GenericCacheLocation)[0] // Other dirs used by the shell, without "file://" property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/quickshell`) property string shellConfigPath: `${Directories.shellConfig}/config.json` - property string generatedMaterialThemePath: `${Directories.shellConfig}/qml_color.json` + property string generatedMaterialThemePath: `${Directories.gen_cache}/hellwal/qml_color.json` } diff --git a/config/quickshell/modules/common/functions/string_utils.js b/config/quickshell/modules/common/functions/string_utils.js index c22671eb..c31edf49 100644 --- a/config/quickshell/modules/common/functions/string_utils.js +++ b/config/quickshell/modules/common/functions/string_utils.js @@ -42,141 +42,6 @@ function shellSingleQuoteEscape(str) { .replace(/'/g, "'\\''"); } -/** - * Splits markdown blocks into three different types: text, think, and code. - * @param { string } markdown - */ -function splitMarkdownBlocks(markdown) { - const regex = /```(\w+)?\n([\s\S]*?)```|([\s\S]*?)<\/think>/g; - /** - * @type {{type: "text" | "think" | "code"; content: string; lang: string | undefined; completed: boolean | undefined}[]} - */ - let result = []; - let lastIndex = 0; - let match; - while ((match = regex.exec(markdown)) !== null) { - if (match.index > lastIndex) { - const text = markdown.slice(lastIndex, match.index); - if (text.trim()) { - result.push({ type: "text", content: text }); - } - } - if (match[0].startsWith('```')) { - if (match[2] && match[2].trim()) { - result.push({ type: "code", lang: match[1] || "", content: match[2], completed: true }); - } - } else if (match[0].startsWith('')) { - if (match[3] && match[3].trim()) { - result.push({ type: "think", content: match[3], completed: true }); - } - } - lastIndex = regex.lastIndex; - } - // Handle any remaining text after the last match - if (lastIndex < markdown.length) { - const text = markdown.slice(lastIndex); - // Check for unfinished block - const thinkStart = text.indexOf(''); - const codeStart = text.indexOf('```'); - if ( - thinkStart !== -1 && - (codeStart === -1 || thinkStart < codeStart) - ) { - const beforeThink = text.slice(0, thinkStart); - if (beforeThink.trim()) { - result.push({ type: "text", content: beforeThink }); - } - const thinkContent = text.slice(thinkStart + 7); - if (thinkContent.trim()) { - result.push({ type: "think", content: thinkContent, completed: false }); - } - } else if (codeStart !== -1) { - const beforeCode = text.slice(0, codeStart); - if (beforeCode.trim()) { - result.push({ type: "text", content: beforeCode }); - } - // Try to detect language after ``` - const codeLangMatch = text.slice(codeStart + 3).match(/^(\w+)?\n/); - let lang = ""; - let codeContentStart = codeStart + 3; - if (codeLangMatch) { - lang = codeLangMatch[1] || ""; - codeContentStart += codeLangMatch[0].length; - } else if (text[codeStart + 3] === '\n') { - codeContentStart += 1; - } - const codeContent = text.slice(codeContentStart); - if (codeContent.trim()) { - result.push({ type: "code", lang, content: codeContent, completed: false }); - } - } else if (text.trim()) { - result.push({ type: "text", content: text }); - } - } - // console.log(JSON.stringify(result, null, 2)); - return result; -} - -/** - * Returns the original string with backslashes escaped - * @param { string } str - * @returns { string } - */ -function escapeBackslashes(str) { - return str.replace(/\\/g, '\\\\'); -} - -/** - * Wraps words to supplied maximum length - * @param { string | null } str - * @param { number } maxLen - * @returns { string } - */ -function wordWrap(str, maxLen) { - if (!str) return ""; - let words = str.split(" "); - let lines = []; - let current = ""; - for (let i = 0; i < words.length; ++i) { - if ((current + (current.length > 0 ? " " : "") + words[i]).length > maxLen) { - if (current.length > 0) lines.push(current); - current = words[i]; - } else { - current += (current.length > 0 ? " " : "") + words[i]; - } - } - if (current.length > 0) lines.push(current); - return lines.join("\n"); -} - -function cleanMusicTitle(title) { - if (!title) return ""; - // Brackets - title = title.replace(/^ *\([^)]*\) */g, " "); // Round brackets - title = title.replace(/^ *\[[^\]]*\] */g, " "); // Square brackets - title = title.replace(/^ *\{[^\}]*\} */g, " "); // Curly brackets - // Japenis brackets - title = title.replace(/^ *【[^】]*】/, "") // Touhou - title = title.replace(/^ *《[^》]*》/, "") // ?? - title = title.replace(/^ *「[^」]*」/, "") // OP/ED - title = title.replace(/^ *『[^』]*』/, "") // OP/ED - - return title; -} - -function friendlyTimeForSeconds(seconds) { - if (isNaN(seconds) || seconds < 0) return "0:00"; - seconds = Math.floor(seconds); - const h = Math.floor(seconds / 3600); - const m = Math.floor((seconds % 3600) / 60); - const s = seconds % 60; - if (h > 0) { - return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; - } else { - return `${m}:${s.toString().padStart(2, '0')}`; - } -} - function escapeHtml(str) { if (typeof str !== 'string') return str; return str diff --git a/config/quickshell/modules/common/widgets/DialogButton.qml b/config/quickshell/modules/common/widgets/DialogButton.qml index 9e19a507..b799336a 100644 --- a/config/quickshell/modules/common/widgets/DialogButton.qml +++ b/config/quickshell/modules/common/widgets/DialogButton.qml @@ -18,7 +18,7 @@ RippleButton { buttonRadius: Appearance?.rounding.full ?? 9999 property color colEnabled: Appearance?.colors.colPrimary - property color colDisabled: Appearance?.m3colors.m3outline + property color colDisabled: Appearance?.m3colors.m3borderPrimary contentItem: StyledText { id: buttonTextWidget @@ -27,7 +27,7 @@ RippleButton { anchors.rightMargin: 15 text: buttonText horizontalAlignment: Text.AlignHCenter - font.pixelSize: Appearance?.font.pixelSize.small ?? 12 + font.pixelSize: Appearance?.font.pixelSize.textBase ?? 12 color: button.enabled ? button.colEnabled : button.colDisabled Behavior on color { diff --git a/config/quickshell/modules/common/widgets/MaterialSymbol.qml b/config/quickshell/modules/common/widgets/MaterialSymbol.qml index dbbfff00..214f838e 100644 --- a/config/quickshell/modules/common/widgets/MaterialSymbol.qml +++ b/config/quickshell/modules/common/widgets/MaterialSymbol.qml @@ -1,17 +1,16 @@ import "root:/modules/common/" import QtQuick -import QtQuick.Layouts Text { id: root - property real iconSize: Appearance?.font.pixelSize.small ?? 16 + property real iconSize: Appearance?.font.pixelSize.textBase ?? 16 property real fill: 0 renderType: Text.NativeRendering font.hintingPreference: Font.PreferFullHinting verticalAlignment: Text.AlignVCenter - font.family: Appearance?.font.family.iconMaterial ?? "Material Symbols Rounded" + font.family: Appearance?.font.family.iconFont ?? "Material Symbols Rounded" font.pixelSize: iconSize - color: Appearance.m3colors.m3onBackground + color: Appearance.m3colors.m3primaryText Behavior on fill { NumberAnimation { @@ -23,8 +22,6 @@ Text { font.variableAxes: { "FILL": fill, - // "wght": font.weight, - // "GRAD": 0, "opsz": iconSize, } } diff --git a/config/quickshell/modules/common/widgets/StyledText.qml b/config/quickshell/modules/common/widgets/StyledText.qml index 6eef5785..988c136d 100644 --- a/config/quickshell/modules/common/widgets/StyledText.qml +++ b/config/quickshell/modules/common/widgets/StyledText.qml @@ -1,14 +1,13 @@ import "root:/modules/common" import QtQuick -import QtQuick.Layouts Text { renderType: Text.NativeRendering verticalAlignment: Text.AlignVCenter font { hintingPreference: Font.PreferFullHinting - family: Appearance?.font.family.main ?? "sans-serif" - pixelSize: Appearance?.font.pixelSize.small ?? 15 + family: Appearance?.font.family.uiFont ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.textBase ?? 15 } - color: Appearance?.m3colors.m3onBackground ?? "black" + color: Appearance?.m3colors.m3primaryText ?? "black" } diff --git a/config/quickshell/modules/common/widgets/StyledTextArea.qml b/config/quickshell/modules/common/widgets/StyledTextArea.qml index 1ea9a349..af3cf34d 100644 --- a/config/quickshell/modules/common/widgets/StyledTextArea.qml +++ b/config/quickshell/modules/common/widgets/StyledTextArea.qml @@ -4,12 +4,12 @@ import QtQuick.Controls TextArea { renderType: Text.NativeRendering - selectedTextColor: Appearance.m3colors.m3onSecondaryContainer - selectionColor: Appearance.m3colors.m3secondaryContainer - placeholderTextColor: Appearance.m3colors.m3outline + selectedTextColor: Appearance.m3colors.m3selectionText + selectionColor: Appearance.m3colors.m3selectionBackground + placeholderTextColor: Appearance.m3colors.m3borderPrimary font { - family: Appearance?.font.family.main ?? "sans-serif" - pixelSize: Appearance?.font.pixelSize.small ?? 15 + family: Appearance?.font.family.uiFont ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.textBase ?? 15 hintingPreference: Font.PreferFullHinting } } diff --git a/config/quickshell/modules/common/widgets/StyledToolTip.qml b/config/quickshell/modules/common/widgets/StyledToolTip.qml index 2ca16df1..aaaad813 100644 --- a/config/quickshell/modules/common/widgets/StyledToolTip.qml +++ b/config/quickshell/modules/common/widgets/StyledToolTip.qml @@ -50,7 +50,7 @@ ToolTip { id: tooltipTextObject anchors.centerIn: parent text: content - font.pixelSize: Appearance?.font.pixelSize.smaller ?? 14 + font.pixelSize: Appearance?.font.pixelSize.textSmall ?? 14 font.hintingPreference: Font.PreferNoHinting // Prevent shaky text color: Appearance?.m3colors.colOnTooltip ?? "#FFFFFF" wrapMode: Text.Wrap diff --git a/config/quickshell/modules/overview/OverviewWidget.qml b/config/quickshell/modules/overview/OverviewWidget.qml index 63633602..2ea8d58a 100644 --- a/config/quickshell/modules/overview/OverviewWidget.qml +++ b/config/quickshell/modules/overview/OverviewWidget.qml @@ -25,7 +25,7 @@ Item { property var windowAddresses: HyprlandData.addresses property var monitorData: HyprlandData.monitors.find(m => m.id === root.monitor.id) property real scale: ConfigOptions.overview.scale - property color activeBorderColor: Appearance.m3colors.m3secondary + property color activeBorderColor: Appearance.m3colors.m3accentSecondary property real workspaceImplicitWidth: Math.max(100, (monitorData?.transform % 2 === 1) ? ((monitor.height - monitorData?.reserved[0] - monitorData?.reserved[2]) * root.scale / monitor.scale) : @@ -71,7 +71,7 @@ Item { property real padding: 10 anchors.fill: parent anchors.margins: Appearance.sizes.elevationMargin - border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.2) + border.color : ColorUtils.transparentize(Appearance.m3colors.m3borderPrimary, 0.2) border.width : 2 implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2 @@ -170,7 +170,7 @@ Item { color: "transparent" radius: parent.radius border.width: 1 - border.color: hoveredWhileDragging ? hoveredBorderColor : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.6) + border.color: hoveredWhileDragging ? hoveredBorderColor : ColorUtils.transparentize(Appearance.m3colors.m3borderPrimary, 0.6) z: 10 // Ensure it's on top } diff --git a/config/quickshell/modules/overview/OverviewWindow.qml b/config/quickshell/modules/overview/OverviewWindow.qml index 273eff7e..449a98c4 100644 --- a/config/quickshell/modules/overview/OverviewWindow.qml +++ b/config/quickshell/modules/overview/OverviewWindow.qml @@ -32,7 +32,7 @@ Rectangle { // Window property var xwaylandIndicatorToIconRatio: 0.35 property var iconToWindowRatioCompact: 0.6 property var iconPath: Quickshell.iconPath(AppSearch.guessIcon(windowData?.class), "image-missing") - property bool compactMode: Appearance.font.pixelSize.smaller * 4 > targetWindowHeight || Appearance.font.pixelSize.smaller * 4 > targetWindowWidth + property bool compactMode: Appearance.font.pixelSize.textSmall * 4 > targetWindowHeight || Appearance.font.pixelSize.textSmall * 4 > targetWindowWidth property bool indicateXWayland: (ConfigOptions.overview.showXwaylandIndicator && windowData?.xwayland) ?? false @@ -44,7 +44,7 @@ Rectangle { // Window radius: Appearance.rounding.windowRounding * root.scale color: pressed ? Appearance.colors.colLayer2Active : hovered ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2 // border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.9) - border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.4) + border.color : ColorUtils.transparentize(Appearance.m3colors.m3borderPrimary, 0.4) border.pixelAligned : false border.width : 2 @@ -65,7 +65,7 @@ Rectangle { // Window anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.right: parent.right - spacing: Appearance.font.pixelSize.smaller * 0.5 + spacing: Appearance.font.pixelSize.textSmall * 0.5 IconImage { id: windowIcon @@ -85,7 +85,7 @@ Rectangle { // Window Layout.fillWidth: true Layout.fillHeight: true horizontalAlignment: Text.AlignHCenter - font.pixelSize: Appearance.font.pixelSize.smaller + font.pixelSize: Appearance.font.pixelSize.textSmall font.italic: indicateXWayland ? true : false elide: Text.ElideRight text: windowData?.title ?? "" diff --git a/config/quickshell/modules/overview/SearchItem.qml b/config/quickshell/modules/overview/SearchItem.qml index 1363b88d..1357d03c 100644 --- a/config/quickshell/modules/overview/SearchItem.qml +++ b/config/quickshell/modules/overview/SearchItem.qml @@ -22,7 +22,7 @@ RippleButton { property string itemName: entry?.name property string itemIcon: entry?.icon ?? "" property var itemExecute: entry?.execute - property string fontType: entry?.fontType ?? "main" + property string fontType: entry?.fontType ?? "uiFont" property string itemClickActionName: entry?.clickActionName property string bigText: entry?.bigText ?? "" property string materialSymbol: entry?.materialSymbol ?? "" @@ -31,7 +31,7 @@ RippleButton { property string highlightPrefix: `` property string highlightSuffix: `` function highlightContent(content, query) { - if (!query || query.length === 0 || content == query || fontType === "monospace") + if (!query || query.length === 0 || content == query || fontType === "codeFont") return StringUtils.escapeHtml(content); let contentLower = content.toLowerCase(); @@ -80,7 +80,7 @@ RippleButton { buttonRadius: Appearance.rounding.normal colBackground: (root.down || root.keyboardDown) ? Appearance.colors.colLayer1Active : ((root.hovered || root.focus) ? Appearance.colors.colLayer1Hover : - ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHigh, 1)) + ColorUtils.transparentize(Appearance.m3colors.m3layerBackground3, 1)) colBackgroundHover: Appearance.colors.colLayer1Hover colRipple: Appearance.colors.colLayer1Active @@ -140,7 +140,7 @@ RippleButton { MaterialSymbol { text: root.materialSymbol iconSize: 30 - color: Appearance.m3colors.m3onSurface + color: Appearance.m3colors.m3surfaceText } } @@ -148,8 +148,8 @@ RippleButton { id: bigTextComponent StyledText { text: root.bigText - font.pixelSize: Appearance.font.pixelSize.larger - color: Appearance.m3colors.m3onSurface + font.pixelSize: Appearance.font.pixelSize.textLarge + color: Appearance.m3colors.m3surfaceText } } @@ -160,7 +160,7 @@ RippleButton { Layout.alignment: Qt.AlignVCenter spacing: 0 StyledText { - font.pixelSize: Appearance.font.pixelSize.smaller + font.pixelSize: Appearance.font.pixelSize.textSmall color: Appearance.colors.colSubtext visible: root.itemType && root.itemType != qsTr("App") text: root.itemType @@ -178,8 +178,8 @@ RippleButton { id: activeText anchors.centerIn: parent text: "check" - font.pixelSize: Appearance.font.pixelSize.normal - color: Appearance.m3colors.m3onPrimary + font.pixelSize: Appearance.font.pixelSize.textMedium + color: Appearance.m3colors.m3accentPrimaryText } } } @@ -187,9 +187,9 @@ RippleButton { Layout.fillWidth: true id: nameText textFormat: Text.StyledText // RichText also works, but StyledText ensures elide work - font.pixelSize: Appearance.font.pixelSize.small + font.pixelSize: Appearance.font.pixelSize.textBase font.family: Appearance.font.family[root.fontType] - color: Appearance.m3colors.m3onSurface + color: Appearance.m3colors.m3surfaceText horizontalAlignment: Text.AlignLeft elide: Text.ElideRight text: `${root.displayContent}` @@ -211,7 +211,7 @@ RippleButton { Layout.fillWidth: false visible: (root.hovered || root.focus) id: clickAction - font.pixelSize: Appearance.font.pixelSize.normal + font.pixelSize: Appearance.font.pixelSize.textMedium color: Appearance.colors.colSubtext horizontalAlignment: Text.AlignRight text: root.itemClickActionName diff --git a/config/quickshell/modules/overview/SearchWidget.qml b/config/quickshell/modules/overview/SearchWidget.qml index fed710ec..f84aa558 100644 --- a/config/quickshell/modules/overview/SearchWidget.qml +++ b/config/quickshell/modules/overview/SearchWidget.qml @@ -201,8 +201,8 @@ Item { // Wrapper MaterialSymbol { id: searchIcon Layout.leftMargin: 15 - iconSize: Appearance.font.pixelSize.huge - color: Appearance.m3colors.m3onSurface + iconSize: Appearance.font.pixelSize.iconLarge + color: Appearance.m3colors.m3surfaceText text: root.searchingText.startsWith(ConfigOptions.search.prefix.clipboard) ? 'content_paste_search' : '' } TextField { // Search box @@ -213,15 +213,15 @@ Item { // Wrapper padding: 15 renderType: Text.NativeRendering font { - family: Appearance?.font.family.main ?? "sans-serif" - pixelSize: Appearance?.font.pixelSize.small ?? 15 + family: Appearance?.font.family.uiFont ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.textBase ?? 15 hintingPreference: Font.PreferFullHinting } - color: activeFocus ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3onSurfaceVariant - selectedTextColor: Appearance.m3colors.m3onSecondaryContainer - selectionColor: Appearance.m3colors.m3secondaryContainer + color: activeFocus ? Appearance.m3colors.m3surfaceText : Appearance.m3colors.m3secondaryText + selectedTextColor: Appearance.m3colors.m3selectionText + selectionColor: Appearance.m3colors.m3selectionBackground placeholderText: qsTr("Search, calculate or run") - placeholderTextColor: Appearance.m3colors.m3outline + placeholderTextColor: Appearance.m3colors.m3borderPrimary implicitWidth: root.searchingText == "" ? Appearance.sizes.searchWidthCollapsed : Appearance.sizes.searchWidth Behavior on implicitWidth { @@ -260,7 +260,7 @@ Item { // Wrapper visible: root.showResults Layout.fillWidth: true height: 1 - color: Appearance.m3colors.m3outlineVariant + color: Appearance.m3colors.m3borderSecondary } ListView { // App results diff --git a/config/quickshell/qml_color.json b/config/quickshell/qml_color.json new file mode 100644 index 00000000..888ba3e6 --- /dev/null +++ b/config/quickshell/qml_color.json @@ -0,0 +1,17 @@ +{ + "windowBackground": "#0f0f15", + "primaryText": "#bac2de", + "layerBackground1": "#1F1A1F", + "layerBackground2": "#231E23", + "layerBackground3": "#2D282E", + "surfaceText": "#EAE0E7", + "secondaryText": "#CFC3CD", + "borderPrimary": "#cba6f7", + "shadowColor": "#000000", + "accentPrimary": "#6750A4", + "accentSecondary": "#D5C0D7", + "selectionBackground": "#534457", + "accentPrimaryText": "#FFFFFF", + "selectionText": "#F2DCF3", + "borderSecondary": "#4C444D" +} \ No newline at end of file diff --git a/config/quickshell/services/ConfigLoader.qml b/config/quickshell/services/ConfigLoader.qml index 5f16bf55..d3fb4e26 100644 --- a/config/quickshell/services/ConfigLoader.qml +++ b/config/quickshell/services/ConfigLoader.qml @@ -72,7 +72,7 @@ Singleton { let targetObject = ConfigOptions; // Check if this is a font-related configuration - if (keys[0] === "font" && typeof Appearance !== 'undefined') { + if (keys[0] === "font") { targetObject = Appearance; } @@ -101,13 +101,12 @@ Singleton { } } - console.log(parents.join(".")); console.log(`[ConfigLoader] Setting live config value: ${nestedKey} = ${convertedValue}`); obj[keys[keys.length - 1]] = convertedValue; } function saveConfig() { - const plainConfig = ObjectUtils.toPlainObject(ConfigOptions) + const plainConfig = ObjectUtils.toPlainObject(ConfigOptions); Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(JSON.stringify(plainConfig, null, 2))}' > '${root.filePath}'`) } diff --git a/config/quickshell/services/MaterialThemeLoader.qml b/config/quickshell/services/MaterialThemeLoader.qml index cd4eb686..2d67ad5b 100644 --- a/config/quickshell/services/MaterialThemeLoader.qml +++ b/config/quickshell/services/MaterialThemeLoader.qml @@ -29,7 +29,7 @@ Singleton { } } - Appearance.m3colors.darkmode = (Appearance.m3colors.m3background.hslLightness < 0.5) + Appearance.m3colors.darkmode = (Appearance.m3colors.m3windowBackground.hslLightness < 0.5) } Timer { diff --git a/config/quickshell/shell.qml b/config/quickshell/shell.qml index 36842c2b..b14c8773 100644 --- a/config/quickshell/shell.qml +++ b/config/quickshell/shell.qml @@ -7,7 +7,6 @@ import "./modules/overview/" import QtQuick import QtQuick.Controls import QtQuick.Layouts -import QtQuick.Window import Quickshell import "./services/" diff --git a/config/wallust/templates/qml_color.json b/config/wallust/templates/qml_color.json index 70283080..03565181 100644 --- a/config/wallust/templates/qml_color.json +++ b/config/wallust/templates/qml_color.json @@ -1,21 +1,17 @@ { - "background": "#1e1e2e", - "onBackground": "#bac2de", - "surfaceContainerLow": "{{color4}}", - "surfaceContainer": "{{color6}}", - "surfaceContainerHigh": "{{color3}}", - "surfaceContainerHighest": "{{color2}}", - "onSurface": "#EAE0E7", - "onSurfaceVariant": "#CFC3CD", - "outline": "{{color7}}", - "scrim": "#000000", - "shadow": "#000000", - "primary": "{{color7}}", - "primaryContainer": "{{color7}}", - "secondary": "#D5C0D7", - "secondaryContainer": "{{color5}}", - "onPrimary": "#FFFFFF", - "onPrimaryContainer": "#21005D", - "onSecondaryContainer": "#F2DCF3", - "outlineVariant": "{{color5}}" + "windowBackground": "#0f0f15", + "primaryText": "#bac2de", + "layerBackground1": "{{color7}}", + "layerBackground2": "{{color6}}", + "layerBackground3": "#2D282E", + "surfaceText": "#EAE0E7", + "secondaryText": "#CFC3CD", + "borderPrimary": "{{color7}}", + "shadowColor": "#000000", + "accentPrimary": "{{color7}}", + "accentSecondary": "#{{color7}}", + "selectionBackground": "{{color7}}", + "accentPrimaryText": "#FFFFFF", + "selectionText": "#F2DCF3", + "borderSecondary": "#{{color5}}" } \ No newline at end of file -- cgit v1.2.3 From 7b8e5f9c2f542b70af067d3034524086c8dc800c Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sat, 21 Jun 2025 17:34:03 +0530 Subject: Cleanup --- config/quickshell/.claude/settings.local.json | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 config/quickshell/.claude/settings.local.json diff --git a/config/quickshell/.claude/settings.local.json b/config/quickshell/.claude/settings.local.json deleted file mode 100644 index d474da6e..00000000 --- a/config/quickshell/.claude/settings.local.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(find:*)", - "Bash(grep:*)" - ], - "deny": [] - } -} \ No newline at end of file -- cgit v1.2.3 From 96a6196f835df391d477cca75a5b6725aaf2e464 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sat, 21 Jun 2025 17:35:48 +0530 Subject: Updated workspaceNumberSize from 0->auto to manual->220 --- config/quickshell/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/quickshell/config.json b/config/quickshell/config.json index cd9c2c4d..286985f5 100644 --- a/config/quickshell/config.json +++ b/config/quickshell/config.json @@ -16,7 +16,7 @@ "showXwaylandIndicator": true, "windowPadding": 6, "position": 1, - "workspaceNumberSize": 0 + "workspaceNumberSize": 220 }, "resources": { "updateInterval": 3000 -- cgit v1.2.3 From 897873fccd5d19c460128998b9434238dcf07ba6 Mon Sep 17 00:00:00 2001 From: Kiran George Date: Sun, 22 Jun 2025 08:14:42 +0530 Subject: Corrected qml_color path --- config/quickshell/modules/common/Directories.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/quickshell/modules/common/Directories.qml b/config/quickshell/modules/common/Directories.qml index 694c73df..f4a6bf83 100644 --- a/config/quickshell/modules/common/Directories.qml +++ b/config/quickshell/modules/common/Directories.qml @@ -16,5 +16,5 @@ Singleton { // Other dirs used by the shell, without "file://" property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/quickshell`) property string shellConfigPath: `${Directories.shellConfig}/config.json` - property string generatedMaterialThemePath: `${Directories.gen_cache}/hellwal/qml_color.json` + property string generatedMaterialThemePath: `${Directories.shellConfig}/qml_color.json` } -- cgit v1.2.3 From b37cf284a9d1ebd6583ba8489195c755c65935d8 Mon Sep 17 00:00:00 2001 From: JaKooLit Date: Tue, 15 Jul 2025 19:33:34 +0900 Subject: Introducing QuickShell --- config/hypr/UserConfigs/UserSettings.conf | 2 -- config/hypr/scripts/Refresh.sh | 4 +-- config/hypr/scripts/RefreshNoWaybar.sh | 2 +- copy.sh | 51 ++++++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/config/hypr/UserConfigs/UserSettings.conf b/config/hypr/UserConfigs/UserSettings.conf index 29dbc572..1f8c23c3 100644 --- a/config/hypr/UserConfigs/UserSettings.conf +++ b/config/hypr/UserConfigs/UserSettings.conf @@ -104,8 +104,6 @@ xwayland { } render { - #explicit_sync = 2 - #explicit_sync_kms = 2 direct_scanout = 0 } diff --git a/config/hypr/scripts/Refresh.sh b/config/hypr/scripts/Refresh.sh index 2d7887a5..d04570b1 100755 --- a/config/hypr/scripts/Refresh.sh +++ b/config/hypr/scripts/Refresh.sh @@ -25,8 +25,8 @@ done # added since wallust sometimes not applying killall -SIGUSR2 waybar -# quit ags & relaunch ags -#ags -q && ags & +# quit quickshell & relaunch quickshell +#pkill qs && qs & # some process to kill for pid in $(pidof waybar rofi swaync ags swaybg); do diff --git a/config/hypr/scripts/RefreshNoWaybar.sh b/config/hypr/scripts/RefreshNoWaybar.sh index e5a0835e..cdbb82db 100755 --- a/config/hypr/scripts/RefreshNoWaybar.sh +++ b/config/hypr/scripts/RefreshNoWaybar.sh @@ -26,7 +26,7 @@ for _prs in "${_ps[@]}"; do done # quit ags & relaunch ags -#ags -q && ags & +#pkill qs && qs & # Wallust refresh ${SCRIPTSDIR}/WallustSwww.sh & diff --git a/copy.sh b/copy.sh index 0c556ddd..f752ac92 100755 --- a/copy.sh +++ b/copy.sh @@ -240,11 +240,11 @@ if command -v blueman-applet >/dev/null 2>&1; then sed -i '/^\s*#exec-once = blueman-applet/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf fi -# Check if ags is installed edit ags behaviour on configs -if command -v ags >/dev/null 2>&1; then - sed -i '/^\s*#exec-once = ags/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf - sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh - sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh +# Check if quickshell is installed edit quickshell behaviour on configs +if command -v qs >/dev/null 2>&1; then + sed -i '/^\s*#exec-once = qs/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf + sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh + sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh fi printf "\n%.0s" {1..1} @@ -461,7 +461,7 @@ fi printf "${INFO} - copying dotfiles ${SKY_BLUE}first${RESET} part\n" # Config directories which will ask the user whether to replace or not -DIRS="ags fastfetch kitty rofi swaync" +DIRS="fastfetch kitty rofi swaync" for DIR2 in $DIRS; do DIRPATH="$HOME/.config/$DIR2" @@ -670,6 +670,43 @@ done printf "\n%.0s" {1..1} +# quickshell (ags alternative) +# Check if quickshell is running +if pgrep -x "qs" >/dev/null; then + echo -e "${NOTE} - ${YELLOW}quickshell${RESET} is currently installed and running." + + DIRPATH_QS="$HOME/.config/quickshell" + + if [ ! -d "$DIRPATH_QS" ]; then + echo "${INFO} - quickshell config not found, copying new config." + if [ -d "config/quickshell" ]; then + cp -r "config/quickshell/" "$DIRPATH" 2>&1 | tee -a "$LOG" + fi + else + read -p "${CAT} Do you want to overwrite your existing ${YELLOW}quickshell${RESET} config? [y/N] " answer_qs + case "$answer_qs" in + [Yy]* ) + BACKUP_DIR=$(get_backup_dirname) + mv "$DIRPATH_QS" "$DIRPATH_QS-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" + echo -e "${NOTE} - Backed up quickshell to $DIRPATH_QS-backup-$BACKUP_DIR" + + cp -r "config/quickshell/" "$DIRPATH_QS" 2>&1 | tee -a "$LOG" + if [ $? -eq 0 ]; then + echo "${OK} - ${YELLOW}quickshell${RESET} overwritten successfully." + else + echo "${ERROR} - Failed to copy ${YELLOW}quickshell${RESET} config." + exit 1 + fi + ;; + * ) + echo "${NOTE} - Skipping overwrite of quickshell config." + ;; + esac + fi +fi +printf "\n%.0s" {1..1} + + # Restore automatically Animations and Monitor-Profiles # including monitors.conf and workspaces.conf HYPR_DIR="$HOME/.config/hypr" @@ -1037,4 +1074,4 @@ printf "\n%.0s" {1..1} printf "${INFO} However, it is ${MAGENTA}HIGHLY SUGGESTED${RESET} to logout and re-login or better reboot to avoid any issues" printf "\n%.0s" {1..1} printf "${SKY_BLUE}Thank you${RESET} for using ${MAGENTA}KooL's Hyprland Configuration${RESET}... ${YELLOW}ENJOY!!!${RESET}" -printf "\n%.0s" {1..3} +printf "\n%.0s" {1..3} \ No newline at end of file -- cgit v1.2.3 From eb6c637b8789edcaa4439382bad91c0fb4df8e1b Mon Sep 17 00:00:00 2001 From: JaKooLit Date: Tue, 15 Jul 2025 19:47:15 +0900 Subject: removing ags --- config/ags/config.js | 31 -- config/ags/modules/.configuration/user_options.js | 127 ------- config/ags/modules/.miscutils/icons.js | 13 - config/ags/modules/.miscutils/mathfuncs.js | 4 - config/ags/modules/.miscutils/system.js | 54 --- .../ags/modules/.widgethacks/advancedrevealers.js | 86 ----- config/ags/modules/.widgethacks/popupwindow.js | 32 -- config/ags/modules/.widgetutils/clickthrough.js | 4 - config/ags/modules/.widgetutils/cursorhover.js | 57 --- config/ags/modules/.widgetutils/keybind.js | 25 -- config/ags/modules/overview/actions.js | 28 -- config/ags/modules/overview/main.js | 18 - config/ags/modules/overview/miscfunctions.js | 155 -------- config/ags/modules/overview/overview_hyprland.js | 423 --------------------- config/ags/modules/overview/searchbuttons.js | 163 -------- config/ags/modules/overview/searchitem.js | 65 ---- config/ags/modules/overview/windowcontent.js | 262 ------------- config/ags/user/style.css | 197 ---------- config/ags/user_options.js | 21 - config/ags/variables.js | 21 - 20 files changed, 1786 deletions(-) delete mode 100644 config/ags/config.js delete mode 100644 config/ags/modules/.configuration/user_options.js delete mode 100644 config/ags/modules/.miscutils/icons.js delete mode 100644 config/ags/modules/.miscutils/mathfuncs.js delete mode 100644 config/ags/modules/.miscutils/system.js delete mode 100644 config/ags/modules/.widgethacks/advancedrevealers.js delete mode 100644 config/ags/modules/.widgethacks/popupwindow.js delete mode 100644 config/ags/modules/.widgetutils/clickthrough.js delete mode 100644 config/ags/modules/.widgetutils/cursorhover.js delete mode 100644 config/ags/modules/.widgetutils/keybind.js delete mode 100644 config/ags/modules/overview/actions.js delete mode 100644 config/ags/modules/overview/main.js delete mode 100644 config/ags/modules/overview/miscfunctions.js delete mode 100644 config/ags/modules/overview/overview_hyprland.js delete mode 100644 config/ags/modules/overview/searchbuttons.js delete mode 100644 config/ags/modules/overview/searchitem.js delete mode 100644 config/ags/modules/overview/windowcontent.js delete mode 100644 config/ags/user/style.css delete mode 100644 config/ags/user_options.js delete mode 100644 config/ags/variables.js diff --git a/config/ags/config.js b/config/ags/config.js deleted file mode 100644 index 278bf351..00000000 --- a/config/ags/config.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -import GLib from 'gi://GLib'; -import App from 'resource:///com/github/Aylur/ags/app.js' -import userOptions from './modules/.configuration/user_options.js'; -import Overview from './modules/overview/main.js'; - -const COMPILED_STYLE_DIR = `${GLib.get_user_config_dir()}/ags/user/` - -async function applyStyle() { - - App.resetCss(); - App.applyCss(`${COMPILED_STYLE_DIR}/style.css`); - console.log('[LOG] Styles loaded') -} -applyStyle().catch(print); - -const Windows = () => [ - Overview() -]; -const CLOSE_ANIM_TIME = 210; -App.config({ - css: `${COMPILED_STYLE_DIR}/style.css`, - stackTraceOnError: true, - closeWindowDelay: { - 'sideright': CLOSE_ANIM_TIME, - 'sideleft': CLOSE_ANIM_TIME, - 'osk': CLOSE_ANIM_TIME, - }, - windows: Windows().flat(1), -}); - diff --git a/config/ags/modules/.configuration/user_options.js b/config/ags/modules/.configuration/user_options.js deleted file mode 100644 index 242c0575..00000000 --- a/config/ags/modules/.configuration/user_options.js +++ /dev/null @@ -1,127 +0,0 @@ - -import userOverrides from '../../user_options.js'; - -// Defaults -let configOptions = { - // General stuff - 'ai': { - 'defaultGPTProvider': "openai", - 'defaultTemperature': 0.9, - 'enhancements': true, - 'useHistory': true, - 'writingCursor': " ...", // Warning: Using weird characters can mess up Markdown rendering - }, - 'animations': { - 'choreographyDelay': 35, - 'durationSmall': 110, - 'durationLarge': 180, - }, - 'appearance': { - 'keyboardUseFlag': false, // Use flag emoji instead of abbreviation letters - }, - 'apps': { - 'imageViewer': "loupe", - 'terminal': "foot", // This is only for shell actions - }, - 'battery': { - 'low': 20, - 'critical': 10, - }, - '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': { - 'imageColumns': 2, - 'imageBooruCount': 20, - 'imageAllowNsfw': false, - }, - 'search': { - 'engineBaseUrl': "https://www.google.com/search?q=", - 'excludedSites': [], //add site to exclude from result. eg: "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 - }, - 'weather': { - 'city': "", - }, - 'workspaces': { - 'shown': 10, - }, - // Longer stuff - 'icons': { - substitutions: { - 'codium-url-handler': "vscodium", - 'codium': "vscodium", - '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", - 'eu.betterbird.Betterbird' : "thunderbird", - 'thunderbird-esr': "thunderbird", - 'wps': "wps-office2019-kprometheus", - 'wpsoffice': "wps-office2019-kprometheus", - 'firefox-esr': "firefox", - 'soffice' : "libreoffice", - '': "image-missing", - } - }, - 'keybinds': { - // Format: Mod1+Mod2+key. CaSe SeNsItIvE! - // Modifiers: Shift Ctrl Alt Hyper Meta - // See https://docs.gtk.org/gdk3/index.html#constants for the other keys (they are listed as KEY_key) - '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", - }, - 'pin': "Ctrl+p", - 'cycleTab': "Ctrl+Tab", - 'nextTab': "Ctrl+Page_Down", - 'prevTab': "Ctrl+Page_Up", - }, - }, -} - -// Override defaults with user's options -function overrideConfigRecursive(userOverrides, configOptions = {}) { - for (const [key, value] of Object.entries(userOverrides)) { - if (typeof value === 'object') { - overrideConfigRecursive(value, configOptions[key]); - } else { - configOptions[key] = value; - } - } -} -overrideConfigRecursive(userOverrides, configOptions); - -globalThis['userOptions'] = configOptions; -export default configOptions; \ No newline at end of file diff --git a/config/ags/modules/.miscutils/icons.js b/config/ags/modules/.miscutils/icons.js deleted file mode 100644 index fb1e20da..00000000 --- a/config/ags/modules/.miscutils/icons.js +++ /dev/null @@ -1,13 +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) { - if(userOptions.icons.substitutions[str]) return userOptions.icons.substitutions[str]; - - if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, '-'); // Turn into kebab-case - return str; -} \ No newline at end of file diff --git a/config/ags/modules/.miscutils/mathfuncs.js b/config/ags/modules/.miscutils/mathfuncs.js deleted file mode 100644 index ba1c0b59..00000000 --- a/config/ags/modules/.miscutils/mathfuncs.js +++ /dev/null @@ -1,4 +0,0 @@ - -export function clamp(x, min, max) { - return Math.min(Math.max(x, min), max); -} \ No newline at end of file diff --git a/config/ags/modules/.miscutils/system.js b/config/ags/modules/.miscutils/system.js deleted file mode 100644 index ef7d15c3..00000000 --- a/config/ags/modules/.miscutils/system.js +++ /dev/null @@ -1,54 +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_cache_dir()}/ags/user/colormode.txt`; -const colorMode = Utils.exec('bash -c "sed -n \'1p\' $HOME/.cache/ags/user/colormode.txt"'); -export let darkMode = Variable(!(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light')); -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'; -} diff --git a/config/ags/modules/.widgethacks/advancedrevealers.js b/config/ags/modules/.widgethacks/advancedrevealers.js deleted file mode 100644 index 3f127931..00000000 --- a/config/ags/modules/.widgethacks/advancedrevealers.js +++ /dev/null @@ -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; -} diff --git a/config/ags/modules/.widgethacks/popupwindow.js b/config/ags/modules/.widgethacks/popupwindow.js deleted file mode 100644 index 26dad59c..00000000 --- a/config/ags/modules/.widgethacks/popupwindow.js +++ /dev/null @@ -1,32 +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: 'overlay', - ...props, - - child: Box({ - setup: (self) => { - self.hook(App, (self, currentName, visible) => { - if (currentName === name) { - self.toggleClassName(hideClassName, !visible); - } - }).keybind("Escape", () => App.closeWindow(name)) - if (showClassName !== "" && hideClassName !== "") - self.className = `${showClassName} ${hideClassName}`; - }, - child: child, - }), - }); -} \ No newline at end of file diff --git a/config/ags/modules/.widgetutils/clickthrough.js b/config/ags/modules/.widgetutils/clickthrough.js deleted file mode 100644 index 505f1412..00000000 --- a/config/ags/modules/.widgetutils/clickthrough.js +++ /dev/null @@ -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); \ No newline at end of file diff --git a/config/ags/modules/.widgetutils/cursorhover.js b/config/ags/modules/.widgetutils/cursorhover.js deleted file mode 100644 index 89be913b..00000000 --- a/config/ags/modules/.widgetutils/cursorhover.js +++ /dev/null @@ -1,57 +0,0 @@ -const { Gdk } = imports.gi; - -export function setupCursorHover(button) { // Hand pointing cursor on hover - const display = Gdk.Display.get_default(); - button.connect('enter-notify-event', () => { - const cursor = Gdk.Cursor.new_from_name(display, 'pointer'); - 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 - button.connect('enter-notify-event', () => { - const display = Gdk.Display.get_default(); - const cursor = Gdk.Cursor.new_from_name(display, 'crosshair'); - button.get_window().set_cursor(cursor); - }); - - button.connect('leave-notify-event', () => { - const display = Gdk.Display.get_default(); - const cursor = Gdk.Cursor.new_from_name(display, 'default'); - button.get_window().set_cursor(cursor); - }); -} - -export function setupCursorHoverGrab(button) { // Hand ready to grab on hover - button.connect('enter-notify-event', () => { - const display = Gdk.Display.get_default(); - const cursor = Gdk.Cursor.new_from_name(display, 'grab'); - button.get_window().set_cursor(cursor); - }); - - button.connect('leave-notify-event', () => { - const display = Gdk.Display.get_default(); - const cursor = Gdk.Cursor.new_from_name(display, 'default'); - button.get_window().set_cursor(cursor); - }); -} - -export function setupCursorHoverInfo(button) { // "?" mark cursor on hover - const display = Gdk.Display.get_default(); - button.connect('enter-notify-event', () => { - const cursor = Gdk.Cursor.new_from_name(display, 'help'); - 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); - }); -} - diff --git a/config/ags/modules/.widgetutils/keybind.js b/config/ags/modules/.widgetutils/keybind.js deleted file mode 100644 index eda7877b..00000000 --- a/config/ags/modules/.widgetutils/keybind.js +++ /dev/null @@ -1,25 +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 -} - -export const checkKeybind = (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] in MODS) { - if (!(pressedModMask & MODS[keys[i]])) { - return false; - } - } else if (pressedKey !== Gdk[`KEY_${keys[i]}`]) { - return false; - } - } - return true; -} diff --git a/config/ags/modules/overview/actions.js b/config/ags/modules/overview/actions.js deleted file mode 100644 index 766cf454..00000000 --- a/config/ags/modules/overview/actions.js +++ /dev/null @@ -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)); -} \ No newline at end of file diff --git a/config/ags/modules/overview/main.js b/config/ags/modules/overview/main.js deleted file mode 100644 index 1f5348d9..00000000 --- a/config/ags/modules/overview/main.js +++ /dev/null @@ -1,18 +0,0 @@ -import Widget from 'resource:///com/github/Aylur/ags/widget.js'; -import { SearchAndWindows } from "./windowcontent.js"; -import PopupWindow from '../.widgethacks/popupwindow.js'; - -export default (id = '') => PopupWindow({ - name: `overview${id}`, - exclusivity: 'ignore', - keymode: 'exclusive', - visible: false, - // anchor: ['middle'], - layer: 'overlay', - child: Widget.Box({ - vertical: true, - children: [ - SearchAndWindows(), - ] - }), -}) diff --git a/config/ags/modules/overview/miscfunctions.js b/config/ags/modules/overview/miscfunctions.js deleted file mode 100644 index 187ee6ec..00000000 --- a/config/ags/modules/overview/miscfunctions.js +++ /dev/null @@ -1,155 +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"; -import { darkMode } from '../.miscutils/system.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 - execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh --pick`, `&`]).catch(print); - } - else if (args[0] == '>light') { // Light mode - darkMode.value = false; - execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "1s/.*/light/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`]) - .then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`])) - .catch(print); - } - else if (args[0] == '>dark') { // Dark mode - darkMode.value = true; - execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "1s/.*/dark/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`]) - .then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`])) - .catch(print); - } - else if (args[0] == '>badapple') { // Black and white - execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "3s/.*/monochrome/" ${GLib.get_user_cache_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_cache_dir()}/ags/user && echo "material" > ${GLib.get_user_cache_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_cache_dir()}/ags/user && echo "pywal" > ${GLib.get_user_cache_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; -} diff --git a/config/ags/modules/overview/overview_hyprland.js b/config/ags/modules/overview/overview_hyprland.js deleted file mode 100644 index 034d6c81..00000000 --- a/config/ags/modules/overview/overview_hyprland.js +++ /dev/null @@ -1,423 +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 { SCREEN_HEIGHT, SCREEN_WIDTH } from '../../variables.js'; -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 { substitute } from "../.miscutils/icons.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 POPUP_CLOSE_TIME = 100; // ms - -const overviewTick = Variable(false); - -export default () => { - const clientMap = new Map(); - let workspaceGroup = 0; - 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, title, xwayland }, screenCoords) => { - const revealInfoCondition = (Math.min(w, h) * userOptions.overview.scale > 70); - if (w <= 0 || h <= 0 || (c === '' && title === '') || c.endsWith('-dropterm')) 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 / SCREEN_WIDTH) * SCREEN_WIDTH); - else if (x < 0) { w = x + w; x = 0; } - if (y + h <= 0) x += (Math.floor(y / SCREEN_HEIGHT) * SCREEN_HEIGHT); - else if (y < 0) { h = y + h; y = 0; } - // Truncate if offscreen - if (x + w > SCREEN_WIDTH) w = SCREEN_WIDTH - x; - if (y + h > SCREEN_HEIGHT) h = SCREEN_HEIGHT - y; - - const appIcon = Widget.Icon({ - icon: substitute(c), - 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) => { - App.closeWindow('overview'); - Utils.timeout(POPUP_CLOSE_TIME, () => Hyprland.messageAsync(`dispatch focuswindow address:${address}`)); - }, - 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', - className: 'spacing-v-5', - children: [ - appIcon, - // TODO: Add xwayland tag instead of just having italics - Widget.Revealer({ - transition: 'slide_down', - revealChild: revealInfoCondition, - child: Widget.Label({ - maxWidthChars: 10, // Doesn't matter what number - truncate: 'end', - className: `${xwayland ? 'txt txt-italic' : 'txt'}`, - css: ` - font-size: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale / 14.6}px; - margin: 0px ${Math.min(SCREEN_WIDTH, SCREEN_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.drag_source_set_icon_gicon(icon); - - 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: ` - margin: ${Math.min(SCREEN_WIDTH, SCREEN_HEIGHT) * userOptions.overview.scale * userOptions.overview.wsNumMarginScale}px; - font-size: ${SCREEN_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', - css: ` - min-width: ${SCREEN_WIDTH * userOptions.overview.scale}px; - min-height: ${SCREEN_HEIGHT * userOptions.overview.scale}px; - `, - children: [Widget.EventBox({ - hexpand: true, - vexpand: true, - onPrimaryClick: () => { - App.closeWindow('overview'); - Utils.timeout(POPUP_CLOSE_TIME, () => Hyprland.messageAsync(`dispatch workspace ${index}`)); - }, - 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: { - 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; - if (!App.getWindow(windowName).visible) return; - 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) { - box.attribute.update(box); - box.attribute.workspaceGroup = currentGroup; - } - }) - .hook(App, (box, name, visible) => { // Update on open - if (name == 'overview' && visible) box.attribute.update(box); - }) - }, - }); - - return Widget.Revealer({ - revealChild: true, - 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, - }) - ) - }), - }); -} \ No newline at end of file diff --git a/config/ags/modules/overview/searchbuttons.js b/config/ags/modules/overview/searchbuttons.js deleted file mode 100644 index f5892f31..00000000 --- a/config/ags/modules/overview/searchbuttons.js +++ /dev/null @@ -1,163 +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'; - -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: '󱖦 ', - 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' : ' '}`, - name: `Run command`, - actionName: `Execute ${terminal ? 'in terminal' : ''}`, - content: `${command}`, - onActivate: () => execAndClose(command, terminal), - extraClassName: 'techfont', -}) - -export const CustomCommandButton = ({ text = '' }) => searchItem({ - materialIconName: ' ', - name: 'Action', - actionName: 'Run', - content: `${text}`, - onActivate: () => { - App.closeWindow('overview'); - launchCustomCommand(text); - }, -}); - -export const SearchButton = ({ text = '' }) => searchItem({ - materialIconName: '󰜏 ', - name: 'Search the web', - actionName: 'Go', - content: `${text}`, - onActivate: () => { - App.closeWindow('overview'); - execAsync(['bash', '-c', `xdg-open '${userOptions.search.engineBaseUrl}${text} ${['', ...userOptions.search.excludedSites].join(' -site:')}' &`]).catch(print); - }, -}); \ No newline at end of file diff --git a/config/ags/modules/overview/searchitem.js b/config/ags/modules/overview/searchitem.js deleted file mode 100644 index 2a3303a4..00000000 --- a/config/ags/modules/overview/searchitem.js +++ /dev/null @@ -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; - }) - , - }); -} diff --git a/config/ags/modules/overview/windowcontent.js b/config/ags/modules/overview/windowcontent.js deleted file mode 100644 index 7a19dd3c..00000000 --- a/config/ags/modules/overview/windowcontent.js +++ /dev/null @@ -1,262 +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 -} from './searchbuttons.js'; -import { checkKeybind } from '../.widgetutils/keybind.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.0; -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 ClickToClose = ({ ...props }) => Widget.EventBox({ - ...props, - onPrimaryClick: () => App.closeWindow('overview'), - onSecondaryClick: () => App.closeWindow('overview'), - onMiddleClick: () => App.closeWindow('overview'), - }); - const resultsBox = Widget.Box({ - className: 'overview-search-results', - vertical: true, - vexpand: 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: '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: ' ', - }), - }); - - 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 - const text = self.text; - if (text.length == 0) return; - const isAction = text.startsWith('>'); - const isDir = (['/', '~'].includes(entry.text[0])); - - if (couldBeMath(text)) { // Eval on typing is dangerous, this is a workaround - try { - const fullResult = eval(text.replace(/\^/g, "**")); - // copy - execAsync(['wl-copy', `${fullResult}`]).catch(print); - App.closeWindow('overview'); - return; - } catch (e) { - // console.log(e); - } - } - if (isDir) { - App.closeWindow('overview'); - execAsync(['bash', '-c', `xdg-open "${expandTilde(text)}"`, `&`]).catch(print); - return; - } - if (_appSearchResults.length > 0) { - App.closeWindow('overview'); - _appSearchResults[0].launch(); - return; - } - else if (text[0] == '>') { // Custom commands - App.closeWindow('overview'); - launchCustomCommand(text); - return; - } - // Fallback: Execute command - if (!isAction && exec(`bash -c "command -v ${text.split(' ')[0]}"`) != '') { - if (text.startsWith('sudo')) - execAndClose(text, true); - else - execAndClose(text, false); - } - - else { - App.closeWindow('overview'); - execAsync(['bash', '-c', `xdg-open '${userOptions.search.engineBaseUrl}${text} ${['', ...userOptions.search.excludedSites].join(' -site:')}' &`]).catch(print); - } - }, - 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 (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 (isDir) { - var contents = []; - contents = ls({ path: text, silent: true }); - contents.forEach((item) => { - resultsBox.add(DirectoryButton(item)); - }) - } - if (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 (!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 - resultsBox.add(SearchButton({ text: entry.text })); - resultsBox.show_all(); - }, - }); - return Widget.Box({ - vertical: true, - children: [ - ClickToClose({ // Top margin. Also works as a click-outside-to-close thing - child: Widget.Box({ - className: 'bar-height', - }) - }), - 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); - } - } - }) - , - }); -}; diff --git a/config/ags/user/style.css b/config/ags/user/style.css deleted file mode 100644 index 13410ea4..00000000 --- a/config/ags/user/style.css +++ /dev/null @@ -1,197 +0,0 @@ -*:not(popover) { - all: unset; -} - -@import '../../../.config/waybar/wallust/colors-waybar.css'; - -/* define some colors */ -@define-color border-color @color12; -@define-color border-color-alt @color9; -@define-color text-color rgba(255, 255, 255, 0.7); -@define-color noti-bg rgba(0, 0, 0, 0.4); -@define-color noti-bg-alt #111111; - -widget { - border-radius: 0.818rem; - -gtk-outline-radius: 0.818rem; -} - -.overview-window { - margin-top: 2.727rem; -} - -.overview-search-box { - transition: 300ms cubic-bezier(0, 0.55, 0.45, 1); - border-radius: 1.705rem; - -gtk-outline-radius: 1.705rem; - border-top: 4px solid @border-color; - border-left: 1px solid @border-color-alt; - border-right: 1px solid @border-color-alt; - border-bottom: 4px solid @border-color; - box-shadow: 0px 2px 3px alpha(@color12, 0.45); - margin: 0.476rem; - min-width: 13.636rem; - min-height: 3.409rem; - padding: 0rem 1.364rem; - padding-right: 2.864rem; - background-color: @noti-bg; - color: @text-color; - caret-color: inherit; - font-weight: bolder; -} -.overview-search-box selection { - background-color: @noti-bg; - color: @text-color; -} - -.overview-search-box-extended { - min-width: 25.909rem; - caret-color: #FDD9FD; -} - -.overview-search-prompt { - color: @text-color; -} - -.overview-search-icon { - margin: 0rem 1.023rem; -} - -.overview-search-prompt-box { - margin-left: -18.545rem; - margin-right: 0.544rem; -} - -.overview-search-icon-box { - margin-left: -18.545rem; - margin-right: 0.544rem; -} - -.overview-search-results { - border-radius: 1.705rem; - -gtk-outline-radius: 1.705rem; - border-top: 4px solid @border-color; - border-left: 1px solid @border-color-alt; - border-right: 1px solid @border-color-alt; - border-bottom: 4px solid @border-color; - box-shadow: 0px 2px 3px @color9; - margin: 0.476rem; - min-width: 28.773rem; - padding: 0.682rem; - background-color: @noti-bg; - color: @text-color; - font-weight: bold; -} - -.overview-search-results-icon { - margin: 0rem 0.682rem; - font-size: 2.386rem; - min-width: 2.386rem; - min-height: 2.386rem; -} - -.overview-search-results-txt { - margin-right: 0.682rem; -} - -.overview-search-results-txt-cmd { - margin-right: 0.682rem; - font-family: "JetBrains Mono NF", "JetBrains Mono Nerd Font", "JetBrains Mono NL", "SpaceMono NF", "SpaceMono Nerd Font", monospace; - font-size: 1.227rem; -} - -.overview-search-result-btn { - border-radius: 1.159rem; - -gtk-outline-radius: 1.159rem; - padding: 0.341rem; - min-width: 2.386rem; - min-height: 2.386rem; - caret-color: transparent; -} - -.overview-search-result-btn:hover, -.overview-search-result-btn:focus { - background-color: alpha(@color7, 0.9); - color: alpha(@color0, 0.7); -} - -.overview-search-result-btn:active { - background-color: alpha(@color7, 0.9); - color: @color4; -} - -.overview-tasks { - border-radius: 1.705rem; - -gtk-outline-radius: 1.705rem; - border-top: 4px solid @border-color; - border-left: 1px solid @border-color-alt; - border-right: 1px solid @border-color-alt; - border-bottom: 4px solid @border-color; - box-shadow: 0px 2px 3px @color5; - margin: 0.476rem; - padding: 0.341rem; - /* background-color: rgba(49, 50, 68, 0.8); */ - background-color: @noti-bg; - color: #EBDFED; -} - -.overview-tasks-workspace { - border-radius: 1.159rem; - -gtk-outline-radius: 1.159rem; - margin: 0.341rem; - /* background-color: #26233A; */ - background-image: url('../../rofi/.current_wallpaper'); - background-size: cover; - background-position: center; - border: 0.068rem solid alpha(@color4, 0.5); -} - -.overview-tasks-workspace-number { - font-family: "Open Sans", "Noto Sans", sans-serif; - color: #CFC2D3; -} - -.overview-tasks-window { - border-radius: 1.159rem; - -gtk-outline-radius: 1.159rem; - transition: 300ms cubic-bezier(0.1, 1, 0, 1); - background-color: alpha(@color3, .7); - /* background-color: @color_a3; */ - /* background-color: rgba(46, 40, 50, 0.8); */ - color: #EBDFED; - border: 0.068rem solid @color7; -} - -.overview-tasks-window:hover, -.overview-tasks-window:focus { - background-color: alpha(@color9, 0.8); -} - -.overview-tasks-window:active { - background-color: alpha(@color9, 0.8); -} - -.overview-tasks-window-selected { - background-color: alpha(@color9, 0.8); -} - -.overview-tasks-window-dragging { - opacity: 0.2; -} - -.growingRadial { - transition: 300ms cubic-bezier(0.2, 0, 0, 1); -} - -.fadingRadial { - transition: 50ms cubic-bezier(0.2, 0, 0, 1); -} - -.sidebar-pinned { - margin: 0rem; - border-radius: 0rem; - border-bottom-right-radius: 1.705rem; - border: 0rem solid; -} - -/*# sourceMappingURL=style.css.map */ diff --git a/config/ags/user_options.js b/config/ags/user_options.js deleted file mode 100644 index 9105decb..00000000 --- a/config/ags/user_options.js +++ /dev/null @@ -1,21 +0,0 @@ - -const userConfigOptions = { - // For every option, see ~/.config/ags/modules/.configuration/user_options.js - // (vscode users ctrl+click this: file://./modules/.configuration/user_options.js) - // (vim users: `:vsp` to split window, move cursor to this path, press `gf`. `Ctrl-w` twice to switch between) - // options listed in this file will override the default ones in the above file - // Here's an example - 'overview':{ - 'scale': 0.15, - 'numOfRows': 2 - }, - 'keybinds': { - 'sidebar': { - 'pin': "Ctrl+p", - 'nextTab': "Ctrl+Page_Down", - 'prevTab': "Ctrl+Page_Up", - }, - }, -} - -export default userConfigOptions; diff --git a/config/ags/variables.js b/config/ags/variables.js deleted file mode 100644 index 645a5807..00000000 --- a/config/ags/variables.js +++ /dev/null @@ -1,21 +0,0 @@ -const { Gtk } = imports.gi; -import Variable from 'resource:///com/github/Aylur/ags/variable.js'; -import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; -const { exec, execAsync } = Utils; - -Gtk.IconTheme.get_default().append_search_path(`${App.configDir}/assets/icons`); - -// Screen size -export const SCREEN_WIDTH = Number(exec(`bash -c "hyprctl monitors -j | jq '.[0].width / .[0].scale'"`)); -export const SCREEN_HEIGHT = Number(exec(`bash -c "hyprctl monitors -j | jq '.[0].height / .[0].scale'"`)); - -// Mode switching -export const currentShellMode = Variable('normal', {}) // normal, focus -globalThis['currentMode'] = currentShellMode; -globalThis['cycleMode'] = () => { - if (currentShellMode.value === 'normal') { - currentShellMode.value = 'focus'; - } else { - currentShellMode.value = 'normal'; - } -} -- cgit v1.2.3