From eee7ade89b9b6cf08bc5c88bb8ecff67f1ad5f46 Mon Sep 17 00:00:00 2001 From: "Matthieu Fortin (CPC/CCP)" Date: Wed, 18 Sep 2024 16:00:39 -0400 Subject: [PATCH] hypr config ... --- bash/.bashrc | 2 +- .../.config/fastfetch/config-compact.jsonc | 72 ++ .../.config/fastfetch/config-orignal.jsonc | 27 + fastfetch/.config/fastfetch/config-v2.jsonc | 112 +++ fastfetch/.config/fastfetch/config.jsonc | 128 ++++ fastfetch/.config/fastfetch/nixos.png | Bin 0 -> 79276 bytes hyprland/.config/ags/config.js | 31 + .../modules/.configuration/user_options.js | 125 ++++ .../.config/ags/modules/.miscutils/icons.js | 13 + .../ags/modules/.miscutils/mathfuncs.js | 4 + .../.config/ags/modules/.miscutils/system.js | 54 ++ .../modules/.widgethacks/advancedrevealers.js | 86 +++ .../ags/modules/.widgethacks/popupwindow.js | 32 + .../ags/modules/.widgetutils/clickthrough.js | 4 + .../ags/modules/.widgetutils/cursorhover.js | 57 ++ .../ags/modules/.widgetutils/keybind.js | 25 + .../.config/ags/modules/overview/actions.js | 28 + hyprland/.config/ags/modules/overview/main.js | 18 + .../ags/modules/overview/miscfunctions.js | 155 ++++ .../ags/modules/overview/overview_hyprland.js | 423 +++++++++++ .../ags/modules/overview/searchbuttons.js | 163 ++++ .../ags/modules/overview/searchitem.js | 65 ++ .../ags/modules/overview/windowcontent.js | 262 +++++++ hyprland/.config/ags/user/style.css | 197 +++++ hyprland/.config/ags/user_options.js | 21 + hyprland/.config/ags/variables.js | 21 + hyprland/.config/cava/config | 292 ++++++++ .../.config/cava/shaders/bar_spectrum.frag | 79 ++ .../.config/cava/shaders/normalized_bars.frag | 38 + .../.config/cava/shaders/northern_lights.frag | 34 + .../.config/cava/shaders/pass_through.vert | 14 + .../.config/hypr/UserConfigs/ENVariables.conf | 53 ++ .../.config/hypr/UserScripts/QuickEdit.sh | 53 ++ .../{userScripts => UserScripts}/RofiBeats.sh | 0 .../{userScripts => UserScripts}/RofiCalc.sh | 0 .../WallpaperAutoChange.sh | 0 .../WallpaperEffects.sh | 0 .../WallpaperRandom.sh | 0 .../WallpaperSelect.sh | 0 .../{userScripts => UserScripts}/Weather.py | 0 .../{userScripts => UserScripts}/Weather.sh | 0 .../ZshChangeTheme.sh | 0 hyprland/.config/hypr/hypridle.conf | 2 +- hyprland/.config/hypr/hyprland.conf | 32 +- hyprland/.config/hypr/scripts/LockScreen.sh | 5 +- hyprland/.config/hypr/scripts/Polkit.sh | 2 +- .../hypr/wallust/wallust-hyprland.conf | 36 +- hyprland/.config/kitty/kitty.conf | 25 + hyprland/.config/rofi/.current_wallpaper | 1 + hyprland/.config/rofi/config-calc.rasi | 22 + hyprland/.config/rofi/config-clipboard.rasi | 16 + hyprland/.config/rofi/config-compact.rasi | 45 ++ hyprland/.config/rofi/config-emoji.rasi | 16 + .../.config/rofi/config-rofi-Beats-menu.rasi | 22 + hyprland/.config/rofi/config-rofi-Beats.rasi | 14 + hyprland/.config/rofi/config-search.rasi | 28 + .../.config/rofi/config-wallpaper-effect.rasi | 27 + hyprland/.config/rofi/config-wallpaper.rasi | 50 ++ .../.config/rofi/config-waybar-layout.rasi | 10 + .../.config/rofi/config-waybar-style.rasi | 26 + hyprland/.config/rofi/config-zsh-theme.rasi | 59 ++ hyprland/.config/rofi/config.rasi | 38 + hyprland/.config/rofi/master-config.rasi | 238 ++++++ .../.config/rofi/resolution/1080p/config.rasi | 38 + .../rofi/resolution/1080p/master-config.rasi | 238 ++++++ .../.config/rofi/resolution/1440p/config.rasi | 44 ++ .../rofi/resolution/1440p/master-config.rasi | 238 ++++++ .../.config/rofi/wallust/colors-rofi.rasi | 31 + .../wallust/templates/colors-rofi.rasi | 2 +- hyprland/.config/waybar/Modules.1 | 696 ------------------ hyprland/.config/waybar/Modules.2 | 696 ------------------ hyprland/.config/waybar/Modules.3 | 696 ------------------ .../.config/waybar/wallust/colors-waybar.css | 38 +- kitty/.config/kitty/kitty.conf | 163 +--- 74 files changed, 3984 insertions(+), 2298 deletions(-) create mode 100644 fastfetch/.config/fastfetch/config-compact.jsonc create mode 100644 fastfetch/.config/fastfetch/config-orignal.jsonc create mode 100644 fastfetch/.config/fastfetch/config-v2.jsonc create mode 100644 fastfetch/.config/fastfetch/config.jsonc create mode 100644 fastfetch/.config/fastfetch/nixos.png create mode 100644 hyprland/.config/ags/config.js create mode 100644 hyprland/.config/ags/modules/.configuration/user_options.js create mode 100644 hyprland/.config/ags/modules/.miscutils/icons.js create mode 100644 hyprland/.config/ags/modules/.miscutils/mathfuncs.js create mode 100644 hyprland/.config/ags/modules/.miscutils/system.js create mode 100644 hyprland/.config/ags/modules/.widgethacks/advancedrevealers.js create mode 100644 hyprland/.config/ags/modules/.widgethacks/popupwindow.js create mode 100644 hyprland/.config/ags/modules/.widgetutils/clickthrough.js create mode 100644 hyprland/.config/ags/modules/.widgetutils/cursorhover.js create mode 100644 hyprland/.config/ags/modules/.widgetutils/keybind.js create mode 100644 hyprland/.config/ags/modules/overview/actions.js create mode 100644 hyprland/.config/ags/modules/overview/main.js create mode 100644 hyprland/.config/ags/modules/overview/miscfunctions.js create mode 100644 hyprland/.config/ags/modules/overview/overview_hyprland.js create mode 100644 hyprland/.config/ags/modules/overview/searchbuttons.js create mode 100644 hyprland/.config/ags/modules/overview/searchitem.js create mode 100644 hyprland/.config/ags/modules/overview/windowcontent.js create mode 100644 hyprland/.config/ags/user/style.css create mode 100644 hyprland/.config/ags/user_options.js create mode 100644 hyprland/.config/ags/variables.js create mode 100644 hyprland/.config/cava/config create mode 100644 hyprland/.config/cava/shaders/bar_spectrum.frag create mode 100644 hyprland/.config/cava/shaders/normalized_bars.frag create mode 100644 hyprland/.config/cava/shaders/northern_lights.frag create mode 100644 hyprland/.config/cava/shaders/pass_through.vert create mode 100644 hyprland/.config/hypr/UserConfigs/ENVariables.conf create mode 100755 hyprland/.config/hypr/UserScripts/QuickEdit.sh rename hyprland/.config/hypr/{userScripts => UserScripts}/RofiBeats.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/RofiCalc.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/WallpaperAutoChange.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/WallpaperEffects.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/WallpaperRandom.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/WallpaperSelect.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/Weather.py (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/Weather.sh (100%) rename hyprland/.config/hypr/{userScripts => UserScripts}/ZshChangeTheme.sh (100%) create mode 100644 hyprland/.config/kitty/kitty.conf create mode 120000 hyprland/.config/rofi/.current_wallpaper create mode 100644 hyprland/.config/rofi/config-calc.rasi create mode 100644 hyprland/.config/rofi/config-clipboard.rasi create mode 100644 hyprland/.config/rofi/config-compact.rasi create mode 100644 hyprland/.config/rofi/config-emoji.rasi create mode 100644 hyprland/.config/rofi/config-rofi-Beats-menu.rasi create mode 100644 hyprland/.config/rofi/config-rofi-Beats.rasi create mode 100644 hyprland/.config/rofi/config-search.rasi create mode 100644 hyprland/.config/rofi/config-wallpaper-effect.rasi create mode 100644 hyprland/.config/rofi/config-wallpaper.rasi create mode 100644 hyprland/.config/rofi/config-waybar-layout.rasi create mode 100644 hyprland/.config/rofi/config-waybar-style.rasi create mode 100644 hyprland/.config/rofi/config-zsh-theme.rasi create mode 100755 hyprland/.config/rofi/config.rasi create mode 100644 hyprland/.config/rofi/master-config.rasi create mode 100755 hyprland/.config/rofi/resolution/1080p/config.rasi create mode 100644 hyprland/.config/rofi/resolution/1080p/master-config.rasi create mode 100755 hyprland/.config/rofi/resolution/1440p/config.rasi create mode 100644 hyprland/.config/rofi/resolution/1440p/master-config.rasi create mode 100644 hyprland/.config/rofi/wallust/colors-rofi.rasi delete mode 100644 hyprland/.config/waybar/Modules.1 delete mode 100644 hyprland/.config/waybar/Modules.2 delete mode 100644 hyprland/.config/waybar/Modules.3 diff --git a/bash/.bashrc b/bash/.bashrc index 51db458..bf31eda 100644 --- a/bash/.bashrc +++ b/bash/.bashrc @@ -1,7 +1,7 @@ #!/bin/bash iatest=$(expr index "$-" i) -[ -f /usr/bin/fastfetch ] && fastfetch +[ -f /usr/bin/fastfetch ] && fastfetch -c ~/.config/fastfetch/config-compact.jsonc [ -f /etc/bashrc ] && . /etc/bashrc [ -f /usr/share/bash-completion/bash-completion ] && . /usr/share/bash-completion/bash-completion [ -f /etc/bash_completion ] && . /etc/bash_completion diff --git a/fastfetch/.config/fastfetch/config-compact.jsonc b/fastfetch/.config/fastfetch/config-compact.jsonc new file mode 100644 index 0000000..f8b1e12 --- /dev/null +++ b/fastfetch/.config/fastfetch/config-compact.jsonc @@ -0,0 +1,72 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "padding": { + "top": 2 + }, + "type": "small" + }, + "display": { + "separator": " -> " + }, + "modules": [ + "break", + { + "type": "title", + "keyWidth": 10, + "format": " {6}{7}{8}" + }, + { + "type": "custom", + "format": " ╭───────────────────────╮" + }, + { + "type": "kernel", + "key": " ", + "keyColor": "yellow" + }, + { + "type": "wm", + "key": " ", + "keyColor": "blue" + }, + { + "type": "shell", + "key": " ", + "keyColor": "yellow" + }, + { + "type": "terminal", + "key": " ", + "keyColor": "blue" + }, + /* + { + "type": "packages", + "key": "󰏖 ", + "keyColor": "yellow" + }, + */ + { + "type": "memory", + "key": "󰍛 ", + "keyColor": "magenta", + // format: used / total + "format": "{1} / {2}" + }, + { + "type": "uptime", + "key": "󰔛 ", + "keyColor": "green" + }, + { + "type": "custom", + "format": " ╰───────────────────────╯" + }, + { + "type": "custom", + "format": " \u001b[31m \u001b[32m \u001b[33m \u001b[34m \u001b[35m \u001b[36m \u001b[37m \u001b[90m " + }, + "break", + ] +} diff --git a/fastfetch/.config/fastfetch/config-orignal.jsonc b/fastfetch/.config/fastfetch/config-orignal.jsonc new file mode 100644 index 0000000..0433d6e --- /dev/null +++ b/fastfetch/.config/fastfetch/config-orignal.jsonc @@ -0,0 +1,27 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": "arch_small", + "modules": [ + "title", + "separator", + "os", + "host", + "kernel", + "uptime", + "packages", + "shell", + "display", + "de", + "wm", + "terminal", + "cpu", + "gpu", + "memory", + "swap", + "disk", + "localip", + "poweradapter", + "break", + "colors" + ] +} diff --git a/fastfetch/.config/fastfetch/config-v2.jsonc b/fastfetch/.config/fastfetch/config-v2.jsonc new file mode 100644 index 0000000..cee27fd --- /dev/null +++ b/fastfetch/.config/fastfetch/config-v2.jsonc @@ -0,0 +1,112 @@ +{ +"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", +"logo": { + //"source": "~/.config/fastfetch/nixos.png", + //"type": "kitty-direct", + "height": 15, + "width": 30, + "padding": { + "top": 1 + } + }, +"display": { + "separator": " ➜ " +}, + +"modules": [ + "break", + { + "type": "os", + "key": " DISTRO", + "keyColor": "31", + }, + { + "type": "kernel", + "key": " ├  ", + "keyColor": "31", + }, + { + "type": "packages", + "key": " ├ 󰏖 ", + "keyColor": "31", + }, + { + "type": "shell", + "key": " └  ", + "keyColor": "31", + }, + "break", + { + "type": "wm", + "key": " DE/WM", + "keyColor": "32", + }, + { + "type": "wmtheme", + "key": " ├ 󰉼 ", + "keyColor": "32", + }, + { + "type": "icons", + "key": " ├ 󰀻 ", + "keyColor": "32", + }, + { + "type": "cursor", + "key": " ├  ", + "keyColor": "32", + }, + { + "type": "terminal", + "key": " ├  ", + "keyColor": "32", + }, + { + "type": "terminalfont", + "key": " └  ", + "keyColor": "32", + }, + "break", + { + "type": "host", + "format": "{2}", + "key": "󰌢 SYSTEM", + "keyColor": "33", + }, + { + "type": "cpu", + "format": "{1} ({3}) @ {7} GHz", + "key": " ├  ", + "keyColor": "33", + }, + { + "type": "gpu", + "format": "{2}", + "key": " ├ 󰢮 ", + "keyColor": "33", + }, + { + "type": "memory", + "key": " ├  ", + "keyColor": "33", + }, + { + "type": "swap", + "key": " ├ 󰓡 ", + "keyColor": "33", + }, + { + "type": "disk", + "key": " ├ 󰋊 ", + "keyColor": "33", + }, + { + "type": "display", + "key": " └  ", + "compactType": "original-with-refresh-rate", + "keyColor": "33", + }, + "break", + "break", +] +} diff --git a/fastfetch/.config/fastfetch/config.jsonc b/fastfetch/.config/fastfetch/config.jsonc new file mode 100644 index 0000000..dfbe1c8 --- /dev/null +++ b/fastfetch/.config/fastfetch/config.jsonc @@ -0,0 +1,128 @@ + +{ +"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", +"logo": { +"padding": { +"top": 1 +} +}, +"display": { +"separator": " 󰑃 " +}, +"modules": [ + "break", + { + "type": "os", + "key": " DISTRO", + "keyColor": "yellow" + }, + { + "type": "kernel", + "key": "│ ├", + "keyColor": "yellow" + }, + { + "type": "packages", + "key": "│ ├󰏖", + "keyColor": "yellow" + }, + { + "type": "shell", + "key": "│ └", + "keyColor": "yellow" + }, + { + "type": "wm", + "key": " DE/WM", + "keyColor": "blue" + }, + { + "type": "wmtheme", + "key": "│ ├󰉼", + "keyColor": "blue" + }, + { + "type": "icons", + "key": "│ ├󰀻", + "keyColor": "blue" + }, + { + "type": "cursor", + "key": "│ ├", + "keyColor": "blue", + }, + { + "type": "terminalfont", + "key": "│ ├", + "keyColor": "blue", + }, + { + "type": "terminal", + "key": "│ └", + "keyColor": "blue" + }, + { + "type": "host", + "key": "󰌢 SYSTEM", + "keyColor": "green" + }, + { + "type": "cpu", + "key": "│ ├󰻠", + "keyColor": "green" + }, + { + "type": "gpu", + "key": "│ ├󰻑", + "format": "{2}", + "keyColor": "green" + }, + { + "type": "display", + "key": "│ ├󰍹", + "keyColor": "green", + "compactType": "original-with-refresh-rate" + }, + { + "type": "memory", + "key": "│ ├󰾆", + "keyColor": "green" + }, + { + "type": "swap", + "key": "│ ├󰓡", + "keyColor": "green" + }, + { + "type": "uptime", + "key": "│ ├󰅐", + "keyColor": "green" + }, + { + "type": "display", + "key": "│ └󰍹", + "keyColor": "green" + }, + { + "type": "sound", + "key": " AUDIO", + "format": "{2}", + "keyColor": "magenta" + }, + { + "type": "player", + "key": "│ ├󰥠", + "keyColor": "magenta" + }, + { + "type": "media", + "key": "│ └󰝚", + "keyColor": "magenta" + }, + { + "type": "custom", + "format": "\u001b[90m \u001b[31m \u001b[32m \u001b[33m \u001b[34m \u001b[35m \u001b[36m \u001b[37m \u001b[38m \u001b[39m \u001b[39m  \u001b[38m \u001b[37m \u001b[36m \u001b[35m \u001b[34m \u001b[33m \u001b[32m \u001b[31m \u001b[90m " + }, + "break", + ] +} diff --git a/fastfetch/.config/fastfetch/nixos.png b/fastfetch/.config/fastfetch/nixos.png new file mode 100644 index 0000000000000000000000000000000000000000..11593f6552e488911348f7a41f741b97d6037532 GIT binary patch literal 79276 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

vd8GPN=Cx{}Z+IC3ESK!=L4iHu*PUGtilSTI^ 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 literal 0 HcmV?d00001 diff --git a/hyprland/.config/ags/config.js b/hyprland/.config/ags/config.js new file mode 100644 index 0000000..278bf35 --- /dev/null +++ b/hyprland/.config/ags/config.js @@ -0,0 +1,31 @@ +"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/hyprland/.config/ags/modules/.configuration/user_options.js b/hyprland/.config/ags/modules/.configuration/user_options.js new file mode 100644 index 0000000..db19439 --- /dev/null +++ b/hyprland/.config/ags/modules/.configuration/user_options.js @@ -0,0 +1,125 @@ + +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", + '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", + '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/hyprland/.config/ags/modules/.miscutils/icons.js b/hyprland/.config/ags/modules/.miscutils/icons.js new file mode 100644 index 0000000..fb1e20d --- /dev/null +++ b/hyprland/.config/ags/modules/.miscutils/icons.js @@ -0,0 +1,13 @@ +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/hyprland/.config/ags/modules/.miscutils/mathfuncs.js b/hyprland/.config/ags/modules/.miscutils/mathfuncs.js new file mode 100644 index 0000000..ba1c0b5 --- /dev/null +++ b/hyprland/.config/ags/modules/.miscutils/mathfuncs.js @@ -0,0 +1,4 @@ + +export function clamp(x, min, max) { + return Math.min(Math.max(x, min), max); +} \ No newline at end of file diff --git a/hyprland/.config/ags/modules/.miscutils/system.js b/hyprland/.config/ags/modules/.miscutils/system.js new file mode 100644 index 0000000..ef7d15c --- /dev/null +++ b/hyprland/.config/ags/modules/.miscutils/system.js @@ -0,0 +1,54 @@ +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/hyprland/.config/ags/modules/.widgethacks/advancedrevealers.js b/hyprland/.config/ags/modules/.widgethacks/advancedrevealers.js new file mode 100644 index 0000000..3f12793 --- /dev/null +++ b/hyprland/.config/ags/modules/.widgethacks/advancedrevealers.js @@ -0,0 +1,86 @@ +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/hyprland/.config/ags/modules/.widgethacks/popupwindow.js b/hyprland/.config/ags/modules/.widgethacks/popupwindow.js new file mode 100644 index 0000000..26dad59 --- /dev/null +++ b/hyprland/.config/ags/modules/.widgethacks/popupwindow.js @@ -0,0 +1,32 @@ +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/hyprland/.config/ags/modules/.widgetutils/clickthrough.js b/hyprland/.config/ags/modules/.widgetutils/clickthrough.js new file mode 100644 index 0000000..505f141 --- /dev/null +++ b/hyprland/.config/ags/modules/.widgetutils/clickthrough.js @@ -0,0 +1,4 @@ +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/hyprland/.config/ags/modules/.widgetutils/cursorhover.js b/hyprland/.config/ags/modules/.widgetutils/cursorhover.js new file mode 100644 index 0000000..89be913 --- /dev/null +++ b/hyprland/.config/ags/modules/.widgetutils/cursorhover.js @@ -0,0 +1,57 @@ +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/hyprland/.config/ags/modules/.widgetutils/keybind.js b/hyprland/.config/ags/modules/.widgetutils/keybind.js new file mode 100644 index 0000000..eda7877 --- /dev/null +++ b/hyprland/.config/ags/modules/.widgetutils/keybind.js @@ -0,0 +1,25 @@ +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/hyprland/.config/ags/modules/overview/actions.js b/hyprland/.config/ags/modules/overview/actions.js new file mode 100644 index 0000000..766cf45 --- /dev/null +++ b/hyprland/.config/ags/modules/overview/actions.js @@ -0,0 +1,28 @@ +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/hyprland/.config/ags/modules/overview/main.js b/hyprland/.config/ags/modules/overview/main.js new file mode 100644 index 0000000..1f5348d --- /dev/null +++ b/hyprland/.config/ags/modules/overview/main.js @@ -0,0 +1,18 @@ +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/hyprland/.config/ags/modules/overview/miscfunctions.js b/hyprland/.config/ags/modules/overview/miscfunctions.js new file mode 100644 index 0000000..187ee6e --- /dev/null +++ b/hyprland/.config/ags/modules/overview/miscfunctions.js @@ -0,0 +1,155 @@ +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/hyprland/.config/ags/modules/overview/overview_hyprland.js b/hyprland/.config/ags/modules/overview/overview_hyprland.js new file mode 100644 index 0000000..034d6c8 --- /dev/null +++ b/hyprland/.config/ags/modules/overview/overview_hyprland.js @@ -0,0 +1,423 @@ +// 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/hyprland/.config/ags/modules/overview/searchbuttons.js b/hyprland/.config/ags/modules/overview/searchbuttons.js new file mode 100644 index 0000000..f5892f3 --- /dev/null +++ b/hyprland/.config/ags/modules/overview/searchbuttons.js @@ -0,0 +1,163 @@ +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/hyprland/.config/ags/modules/overview/searchitem.js b/hyprland/.config/ags/modules/overview/searchitem.js new file mode 100644 index 0000000..2a3303a --- /dev/null +++ b/hyprland/.config/ags/modules/overview/searchitem.js @@ -0,0 +1,65 @@ +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/hyprland/.config/ags/modules/overview/windowcontent.js b/hyprland/.config/ags/modules/overview/windowcontent.js new file mode 100644 index 0000000..7a19dd3 --- /dev/null +++ b/hyprland/.config/ags/modules/overview/windowcontent.js @@ -0,0 +1,262 @@ +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/hyprland/.config/ags/user/style.css b/hyprland/.config/ags/user/style.css new file mode 100644 index 0000000..49d44ad --- /dev/null +++ b/hyprland/.config/ags/user/style.css @@ -0,0 +1,197 @@ +*:not(popover) { + all: unset; +} + +@import '../../../.config/waybar/wallust/colors-waybar.css'; + +/* define some colors */ +@define-color border-color @color12; +@define-color border-color-alt @color1; +@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: 2px solid @border-color; + border-left: 1px solid @border-color-alt; + border-right: 1px solid @border-color-alt; + border-bottom: 2px solid @border-color; + /*box-shadow: 0px 2px 3px alpha(@color0, 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: 2px solid @border-color; + border-left: 1px solid @border-color-alt; + border-right: 1px solid @border-color-alt; + border-bottom: 2px 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: 2px solid @border-color; + border-left: 1px solid @border-color-alt; + border-right: 1px solid @border-color-alt; + border-bottom: 2px 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/hyprland/.config/ags/user_options.js b/hyprland/.config/ags/user_options.js new file mode 100644 index 0000000..9105dec --- /dev/null +++ b/hyprland/.config/ags/user_options.js @@ -0,0 +1,21 @@ + +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/hyprland/.config/ags/variables.js b/hyprland/.config/ags/variables.js new file mode 100644 index 0000000..645a580 --- /dev/null +++ b/hyprland/.config/ags/variables.js @@ -0,0 +1,21 @@ +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'; + } +} diff --git a/hyprland/.config/cava/config b/hyprland/.config/cava/config new file mode 100644 index 0000000..a7867c8 --- /dev/null +++ b/hyprland/.config/cava/config @@ -0,0 +1,292 @@ +# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ # +# /* wallust template - colors-cava */ + +## Configuration file for CAVA. +# Remove the ; to change parameters. + +[general] + +# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. DEPRECATED as of 0.6.0 +; mode = normal + +# Accepts only non-negative values. +; framerate = 60 + +# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off +# new as of 0.6.0 autosens of low values (dynamic range) +# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. DEPRECATED as of 0.6.0 +; autosens = 1 +; overshoot = 20 + +# Manual sensitivity in %. If autosens is enabled, this will only be the initial value. +# 200 means double height. Accepts only non-negative values. +; sensitivity = 100 + +# The number of bars (0-512). 0 sets it to auto (fill up console). +# Bars' width and space between bars in number of characters. +; bars = 0 +; bar_width = 2 +; bar_spacing = 1 +# bar_height is only used for output in "noritake" format +; bar_height = 32 + +# For SDL width and space between bars is in pixels, defaults are: +; bar_width = 20 +; bar_spacing = 5 + +# sdl_glsl have these default values, they are only used to calulate max number of bars. +; bar_width = 1 +; bar_spacing = 0 + + +# Lower and higher cutoff frequencies for lowest and highest bars +# the bandwidth of the visualizer. +# Note: there is a minimum total bandwidth of 43Mhz x number of bars. +# Cava will automatically increase the higher cutoff if a too low band is specified. +; lower_cutoff_freq = 50 +; higher_cutoff_freq = 10000 + + +# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and +# only check for input once per second. Cava will wake up once input is detected. 0 = disable. +; sleep_timer = 0 + + +[input] + +# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss', 'jack' or 'shmem' +# Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with. +# On Mac it defaults to 'portaudio' or 'fifo' +# On windows this is automatic and no input settings are needed. +# +# All input methods uses the same config variable 'source' +# to define where it should get the audio. +# +# For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink +# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them). +# +# For pipewire 'source' will be the object name or object.serial of the device to capture from. +# Both input and output devices are supported. +# +# For alsa 'source' will be the capture device. +# For fifo 'source' will be the path to fifo-file. +# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address +# +# For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'. +# README.md contains further information on how to setup CAVA for sndio. +# +# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device. +# README.md contains further information on how to setup CAVA for OSS on FreeBSD. +# +# For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'. +# README.md contains further information on how to setup CAVA for JACK. +# + method = pulse + source = auto + + method = pipewire + source = auto + +; method = alsa +; source = hw:Loopback,1 + +; method = fifo +; source = /tmp/mpd.fifo + +; method = shmem +; source = /squeezelite-AA:BB:CC:DD:EE:FF + +; method = portaudio +; source = auto + +; method = sndio +; source = default + +; method = oss +; source = /dev/dsp + +; method = jack +; source = default + +# The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' can be configured for some input methods: +# sample_rate: fifo, pipewire, sndio, oss +# sample_bits: fifo, pipewire, sndio, oss +# channels: sndio, oss, jack +# autoconnect: jack +# Other methods ignore these settings. +# +# For 'sndio' and 'oss' they are only preferred values, i.e. if the values are not supported +# by the chosen audio device, the device will use other supported values instead. +# Example: 48000, 32 and 2, but the device only supports 44100, 16 and 1, then it +# will use 44100, 16 and 1. +# +; sample_rate = 44100 +; sample_bits = 16 +; channels = 2 +; autoconnect = 2 + + +[output] + +# Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl' +# or 'sdl_glsl'. +# 'noncurses' (default) uses a buffer and cursor movements to only print +# changes from frame to frame in the terminal. Uses less resources and is less +# prone to tearing (vsync issues) than 'ncurses'. +# +# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data +# stream of the bar heights that can be used to send to other applications. +# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above. +# +# 'noritake' outputs a bitmap in the format expected by a Noritake VFD display +# in graphic mode. It only support the 3000 series graphical VFDs for now. +# +# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context. +# 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or +# use one of the predefined ones. +; method = noncurses + +# Orientation of the visualization. Can be 'bottom', 'top', 'left' or 'right'. +# Default is 'bottom'. Other orientations are only supported on sdl and ncruses +# output. Note: many fonts have weird glyphs for 'top' and 'right' characters, +# which can make ncurses not look right. +; orientation = bottom + +# Visual channels. Can be 'stereo' or 'mono'. +# 'stereo' mirrors both channels with low frequencies in center. +# 'mono' outputs left to right lowest to highest frequencies. +# 'mono_option' set mono to either take input from 'left', 'right' or 'average'. +# set 'reverse' to 1 to display frequencies the other way around. +; channels = stereo +; mono_option = average +; reverse = 0 + +# Raw output target. A fifo will be created if target does not exist. +; raw_target = /dev/stdout + +# Raw data format. Can be 'binary' or 'ascii'. +; data_format = binary + +# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530). +; bit_format = 16bit + +# Ascii max value. In 'ascii' mode range will run from 0 to value specified here +; ascii_max_range = 1000 + +# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters. +# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)). +; bar_delimiter = 59 +; frame_delimiter = 10 + +# sdl window size and position. -1,-1 is centered. +; sdl_width = 1000 +; sdl_height = 500 +; sdl_x = -1 +; sdl_y= -1 +; sdl_full_screen = 0 + +# set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none' +# 'frequency' displays the lower cut off frequency of the bar above. +# Only supported on ncurses and noncurses output. +; xaxis = none + +# enable alacritty synchronized updates. 1 = on, 0 = off +# removes flickering in alacritty terminal emulator. +# defaults to off since the behaviour in other terminal emulators is unknown +; alacritty_sync = 0 + +# Shaders for sdl_glsl, located in $HOME/.config/cava/shaders +; vertex_shader = pass_through.vert +; fragment_shader = bar_spectrum.frag + +; for glsl output mode, keep rendering even if no audio +; continuous_rendering = 0 + +# disable console blank (screen saver) in tty +# (Not supported on FreeBSD) +; disable_blanking = 0 + +# show a flat bar at the bottom of the screen when idle, 1 = on, 0 = off +; show_idle_bar_heads = 1 + +# show waveform instead of frequency spectrum, 1 = on, 0 = off +; waveform = 0 + +[color] + +# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow. +# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires +# a terminal that can change color definitions such as Gnome-terminal or rxvt. +# default is to keep current terminal color +; background = default +; foreground = default + +# SDL and sdl_glsl only support hex code colors, these are the default: +; background = '#111111' +; foreground = '#33ffff' + +# these are default +# Gradient mode, only hex defined colors are supported, +# background must also be defined in hex or remain commented out. 1 = on, 0 = off. +# You can define as many as 8 different colors. They range from bottom to top of screen +; gradient = 0 +; gradient_count = 8 +; gradient_color_1 = '#59cc33' +; gradient_color_2 = '#80cc33' +; gradient_color_3 = '#a6cc33' +; gradient_color_4 = '#cccc33' +; gradient_color_5 = '#cca633' +; gradient_color_6 = '#cc8033' +; gradient_color_7 = '#cc5933' +; gradient_color_8 = '#cc3333' + +# for wallust +gradient = 1 +gradient_count = 8 +gradient_color_1 = '#000004' +gradient_color_2 = '#523F41' +gradient_color_3 = '#49596E' +gradient_color_4 = '#905E56' +gradient_color_5 = '#DCD4CD' +gradient_color_6 = '#AE746D' +gradient_color_7 = '#C07D73' +gradient_color_8 = '#DCD4CD' + + +[smoothing] + +# Percentage value for integral smoothing. Takes values from 0 - 100. +# Higher values means smoother, but less precise. 0 to disable. +# DEPRECATED as of 0.8.0, use noise_reduction instead +; integral = 77 + +# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable. +; monstercat = 0 +; waves = 0 + +# Set gravity percentage for "drop off". Higher values means bars will drop faster. +# Accepts only non-negative values. 50 means half gravity, 200 means double. Set to 0 to disable "drop off". +# DEPRECATED as of 0.8.0, use noise_reduction instead +; gravity = 100 + + +# In bar height, bars that would have been lower that this will not be drawn. +# DEPRECATED as of 0.8.0 +; ignore = 0 + +# Noise reduction, int 0 - 100. default 77 +# the raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth +# 100 will be very slow and smooth, 0 will be fast but noisy. +; noise_reduction = 77 + + +[eq] + +# This one is tricky. You can have as much keys as you want. +# Remember to uncomment more than one key! More keys = more precision. +# Look at readme.md on github for further explanations and examples. +; 1 = 1 # bass +; 2 = 1 +; 3 = 1 # midtone +; 4 = 1 +; 5 = 1 # treble diff --git a/hyprland/.config/cava/shaders/bar_spectrum.frag b/hyprland/.config/cava/shaders/bar_spectrum.frag new file mode 100644 index 0000000..b078913 --- /dev/null +++ b/hyprland/.config/cava/shaders/bar_spectrum.frag @@ -0,0 +1,79 @@ +#version 330 + +in vec2 fragCoord; +out vec4 fragColor; + +// bar values. defaults to left channels first (low to high), then right (high to low). +uniform float bars[512]; + +uniform int bars_count; // number of bars (left + right) (configurable) +uniform int bar_width; // bar width (configurable), not used here +uniform int bar_spacing; // space bewteen bars (configurable) + +uniform vec3 u_resolution; // window resolution + +//colors, configurable in cava config file (r,g,b) (0.0 - 1.0) +uniform vec3 bg_color; // background color +uniform vec3 fg_color; // foreground color + +uniform int gradient_count; +uniform vec3 gradient_colors[8]; // gradient colors + +vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max) +{ + //create color based on fraction of this color and next color + float yr = (y - y_min) / (y_max - y_min); + return col_1 * (1.0 - yr) + col_2 * yr; +} + +void main() +{ + // find which bar to use based on where we are on the x axis + float x = u_resolution.x * fragCoord.x; + int bar = int(bars_count * fragCoord.x); + + //calculate a bar size + float bar_size = u_resolution.x / bars_count; + + //the y coordinate and bar values are the same + float y = bars[bar]; + + // make sure there is a thin line at bottom + if (y * u_resolution.y < 1.0) + { + y = 1.0 / u_resolution.y; + } + + //draw the bar up to current height + if (y > fragCoord.y) + { + //make some space between bars basen on settings + if (x > (bar + 1) * (bar_size) - bar_spacing) + { + fragColor = vec4(bg_color,1.0); + } + else + { + if (gradient_count == 0) + { + fragColor = vec4(fg_color,1.0); + } + else + { + //find which color in the configured gradient we are at + int color = int((gradient_count - 1) * fragCoord.y); + + //find where on y this and next color is supposed to be + float y_min = color / (gradient_count - 1.0); + float y_max = (color + 1.0) / (gradient_count - 1.0); + + //make color + fragColor = vec4(normalize_C(fragCoord.y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0); + } + } + } + else + { + fragColor = vec4(bg_color,1.0); + } +} \ No newline at end of file diff --git a/hyprland/.config/cava/shaders/normalized_bars.frag b/hyprland/.config/cava/shaders/normalized_bars.frag new file mode 100644 index 0000000..81a27e2 --- /dev/null +++ b/hyprland/.config/cava/shaders/normalized_bars.frag @@ -0,0 +1,38 @@ +#version 330 + +in vec2 fragCoord; +out vec4 fragColor; + +// bar values. defaults to left channels first (low to high), then right (high to low). +uniform float bars[512]; + +uniform int bars_count; // number of bars (left + right) (configurable) + +uniform vec3 u_resolution; // window resolution, not used here + +//colors, configurable in cava config file +uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here +uniform vec3 fg_color; // foreground color, not used here + +float normalize_C(float x, float x_min, float x_max, float r_min, float r_max ) +{ + float xr; + xr = (r_max-r_min) * (x - x_min) / (x_max - x_min) + r_min; + return xr; +} + +void main() +{ + // find which bar to use based on where we are on the x axis + int bar = int(bars_count * fragCoord.x); + + // create a normal along the y axis based on the bar height + float x = normalize_C(fragCoord.y, 1.0, 0.0, 0.0, bars[bar]); + + // set color + fragColor.r=fg_color.x*x; + fragColor.g=fg_color.y*x; + fragColor.b=fg_color.z*x; + fragColor.a=1.0; + +} diff --git a/hyprland/.config/cava/shaders/northern_lights.frag b/hyprland/.config/cava/shaders/northern_lights.frag new file mode 100644 index 0000000..ecd859a --- /dev/null +++ b/hyprland/.config/cava/shaders/northern_lights.frag @@ -0,0 +1,34 @@ +#version 330 + +in vec2 fragCoord; +out vec4 fragColor; + +// bar values. defaults to left channels first (low to high), then right (high to low). +uniform float bars[512]; + +uniform int bars_count; // number of bars (left + right) (configurable) + +uniform vec3 u_resolution; // window resolution, not used here + +//colors, configurable in cava config file +uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here +uniform vec3 fg_color; // foreground color, not used here + +void main() +{ + // find which bar to use based on where we are on the x axis + int bar = int(bars_count * fragCoord.x); + + float bar_y = 1.0 - abs((fragCoord.y - 0.5)) * 2.0; + float y = (bars[bar]) * bar_y; + + float bar_x = (fragCoord.x - float(bar) / float(bars_count)) * bars_count; + float bar_r = 1.0 - abs((bar_x - 0.5)) * 2; + + bar_r = bar_r * bar_r * 2; + + // set color + fragColor.r = fg_color.x * y * bar_r; + fragColor.g = fg_color.y * y * bar_r; + fragColor.b = fg_color.z * y * bar_r; +} diff --git a/hyprland/.config/cava/shaders/pass_through.vert b/hyprland/.config/cava/shaders/pass_through.vert new file mode 100644 index 0000000..a4f20e5 --- /dev/null +++ b/hyprland/.config/cava/shaders/pass_through.vert @@ -0,0 +1,14 @@ +#version 330 + + +// Input vertex data, different for all executions of this shader. +layout(location = 0) in vec3 vertexPosition_modelspace; + +// Output data ; will be interpolated for each fragment. +out vec2 fragCoord; + +void main() +{ + gl_Position = vec4(vertexPosition_modelspace,1); + fragCoord = (vertexPosition_modelspace.xy+vec2(1,1))/2.0; +} diff --git a/hyprland/.config/hypr/UserConfigs/ENVariables.conf b/hyprland/.config/hypr/UserConfigs/ENVariables.conf new file mode 100644 index 0000000..6cb01c2 --- /dev/null +++ b/hyprland/.config/hypr/UserConfigs/ENVariables.conf @@ -0,0 +1,53 @@ +# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ # +# Environment variables. See https://wiki.hyprland.org/Configuring/Environment-variables/ + +# Set your defaults here +env = EDITOR,nvim #default editor + +#environment-variables +env = CLUTTER_BACKEND,wayland +env = GDK_BACKEND,wayland,x11 +env = QT_AUTO_SCREEN_SCALE_FACTOR,1 +env = QT_QPA_PLATFORM,wayland;xcb +env = QT_QPA_PLATFORMTHEME,qt5ct +env = QT_QPA_PLATFORMTHEME,qt6ct +env = QT_SCALE_FACTOR,1 +env = QT_WAYLAND_DISABLE_WINDOWDECORATION,1 +env = XDG_CURRENT_DESKTOP,Hyprland +env = XDG_SESSION_DESKTOP,Hyprland +env = XDG_SESSION_TYPE,wayland + +# xwayland apps scale fix (useful if you are use monitor scaling) +# see https://wiki.hyprland.org/Configuring/XWayland/ +# toolkit-specific scale +env = GDK_SCALE,1 + +# firefox +env = MOZ_ENABLE_WAYLAND,1 + +# electron >28 apps (may help) +env = ELECTRON_OZONE_PLATFORM_HINT,auto + +# NVIDIA +# This is from Hyprland Wiki. Below will be activated nvidia gpu detected +# See hyprland wiki https://wiki.hyprland.org/Nvidia/#environment-variables +env = LIBVA_DRIVER_NAME,nvidia +env = __GLX_VENDOR_LIBRARY_NAME,nvidia +env = NVD_BACKEND,direct + +# additional ENV's for nvidia. Caution, activate with care +#env = GBM_BACKEND,nvidia-drm + +#env = __NV_PRIME_RENDER_OFFLOAD,1 +#env = __VK_LAYER_NV_optimus,NVIDIA_only +#env = WLR_DRM_NO_ATOMIC,1 + +# FOR VM and POSSIBLY NVIDIA +# LIBGL_ALWAYS_SOFTWARE software mesa rendering +#env = LIBGL_ALWAYS_SOFTWARE,1 +#env = WLR_RENDERER_ALLOW_SOFTWARE,1 + +# nvidia firefox (for hardware acceleration on FF)? +# check this post https://github.com/elFarto/nvidia-vaapi-driver#configuration +env = MOZ_DISABLE_RDD_SANDBOX,1 +env = EGL_PLATFORM,wayland diff --git a/hyprland/.config/hypr/UserScripts/QuickEdit.sh b/hyprland/.config/hypr/UserScripts/QuickEdit.sh new file mode 100755 index 0000000..efe9600 --- /dev/null +++ b/hyprland/.config/hypr/UserScripts/QuickEdit.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Rofi menu for Quick Edit/View of Settings (SUPER E) + +# Define preferred text editor and terminal +edit=${EDITOR:-nvim} +tty=kitty + +# Paths to configuration directories +configs="$HOME/.config/hypr/configs" +UserConfigs="$HOME/.config/hypr/UserConfigs" + +# Function to display the menu options +menu() { + cat <{calendar}", - "calendar": { - "mode": "year", - "mode-mon-col": 3, - "weeks-pos": "right", - "on-scroll": 1, - "format": { - "months": "{}", - "days": "{}", - "weeks": "W{}", - "weekdays": "{}", - "today": "{}" - } - } -}, -"actions": { - "on-click-right": "mode", - "on-click-forward": "tz_up", - "on-click-backward": "tz_down", - "on-scroll-up": "shift_up", - "on-scroll-down": "shift_down" -}, -"clock#2": { - //"format": " {:%I:%M %p}", // AM PM format - "format": " {:%H:%M}", // 24H - "format-alt": "{:%A | %H:%M | %e %B}", - "tooltip-format": "{:%Y %B}\n{calendar}" -}, -"clock#3": { - //"format": "{:%I:%M %p - %d/%b}", //for AM/PM - "format": "{:%H:%M - %d/%b}", // 24H - "tooltip": false -}, -"clock#4": { - "interval": 60, - //"format": "{:%B | %a %d, %Y | %I:%M %p}", // AM PM format - "format": "{:%B | %a %d, %Y | %H:%M}", // 24H - "format-alt": "{:%a %b %d, %G}", - "tooltip-format": "{:%B %Y}\n{calendar}", -}, -"clock#5": { - //"format": "{:%A, %I:%M %P}", // AM PM format - "format": "{:%a %d | %H:%M}", // 24H - "format-alt": "{:%A, %d %B, %Y (%R)}" -}, -"cpu": { - "format": "{usage}% 󰍛", - "interval": 1, - "min-length": 5, - "format-alt-click": "click", - "format-alt": "{icon0}{icon1}{icon2}{icon3} {usage:>2}% 󰍛", - "format-icons": [ - "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" - ], - "on-click-right": "gnome-system-monitor", -}, -"disk": { - "interval": 30, - //"format": "󰋊", - "path": "/", - //"format-alt-click": "click", - "format": "{percentage_used}% 󰋊", - //"tooltip": true, - "tooltip-format": "{used} used out of {total} on {path} ({percentage_used}%)", -}, -"hyprland/language": { - "format": "Lang: {}", - "format-en": "US", - "format-tr": "Korea", - "keyboard-name": "at-translated-set-2-keyboard", - "on-click": "hyprctl switchxkblayout $SET_KB next" -}, -"hyprland/submap": { - "format": " {}", // Icon: expand-arrows-alt - "tooltip": false, -}, -"hyprland/window": { - "format": "{}", - "max-length": 20, - "separate-outputs": true, - "offscreen-css": true, - "offscreen-css-text": "(inactive)", - "rewrite": { - "(.*) — Mozilla Firefox": " $1", - "(.*) - fish": "> [$1]", - "(.*) - zsh": "> [$1]", - "(.*) - $term": "> [$1]", - }, -}, -"idle_inhibitor": { - "tooltip": true, - "tooltip-format-activated": "Idle_inhibitor active", - "tooltip-format-deactivated": "Idle_inhibitor not active", - "format": "{icon}", - "format-icons": { - "activated": " ", - "deactivated": " ", - } -}, -"keyboard-state": { - //"numlock": true, - "capslock": true, - "format": { - "numlock": "N {icon}", - "capslock": "󰪛 {icon}", - }, - "format-icons": { - "locked": "", - "unlocked": "" - }, -}, -"memory": { - "interval": 10, - "format": "{used:0.1f}G 󰾆", - "format-alt": "{percentage}% 󰾆", - "format-alt-click": "click", - "tooltip": true, - "tooltip-format": "{used:0.1f}GB/{total:0.1f}G", - "on-click-right": "kitty --title btop sh -c 'btop'" -}, -"mpris": { - "interval": 10, - "format": "{player_icon} ", - "format-paused": "{status_icon} {dynamic}", - "on-click-middle": "playerctl play-pause", - "on-click": "playerctl previous", - "on-click-right": "playerctl next", - "scroll-step": 5.0, - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "smooth-scrolling-threshold": 1, - "player-icons": { - "chromium": "", - "default": "", - "firefox": "", - "kdeconnect": "", - "mopidy": "", - "mpv": "󰐹", - "spotify": "", - "vlc": "󰕼", - }, - "status-icons": { - "paused": "󰐎", - "playing": "", - "stopped": "", - }, - // "ignored-players": ["firefox"] - "max-length": 30, -}, -"network": { - "format": "{ifname}", - "format-wifi": "{icon}", - "format-ethernet": "󰌘", - "format-disconnected": "󰌙", - "tooltip-format": "{ipaddr}  {bandwidthUpBits}  {bandwidthDownBits}", - "format-linked": "󰈁 {ifname} (No IP)", - "tooltip-format-wifi": "{essid} {icon} {signalStrength}%", - "tooltip-format-ethernet": "{ifname} 󰌘", - "tooltip-format-disconnected": "󰌙 Disconnected", - "max-length": 30, - "format-icons": [ - "󰤯", "󰤟", "󰤢", "󰤥", "󰤨" - ], - "on-click-right": "kitty nmtui" -}, -"network#speed": { - "interval": 1, - "format": "{ifname}", - "format-wifi": "{icon}  {bandwidthUpBytes}  {bandwidthDownBytes}", - "format-ethernet": "󰌘  {bandwidthUpBytes}  {bandwidthDownBytes}", - "format-disconnected": "󰌙", - "tooltip-format": "{ipaddr}", - "format-linked": "󰈁 {ifname} (No IP)", - "tooltip-format-wifi": "{essid} {icon} {signalStrength}%", - "tooltip-format-ethernet": "{ifname} 󰌘", - "tooltip-format-disconnected": "󰌙 Disconnected", - "min-length": 24, - "max-length": 24, - "format-icons": [ - "󰤯", "󰤟", "󰤢", "󰤥", "󰤨" - ] -}, -"power-profiles-daemon": { - "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", - "tooltip": true, - "format-icons": { - "default": "", - "performance": "", - "balanced": "", - "power-saver": "" - } -}, -"pulseaudio": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} 󰂰 {volume}%", - "format-muted": "󰖁", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": [ - "", "", "󰕾", "" - ], - "ignored-sinks": [ - "Easy Effects Sink" - ], - }, - "scroll-step": 5.0, - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "tooltip-format": "{icon} {desc} | {volume}%", - "smooth-scrolling-threshold": 1, -}, -"pulseaudio#1": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} {volume}%", - "format-bluetooth-muted": " {icon}", - "format-muted": "󰸈", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", "", ""] - }, - "on-click": "pamixer --toggle-mute", - "on-click-right": "pavucontrol -t 3", - "tooltip": true, - "tooltip-format": "{icon} {desc} | {volume}%", -}, -"pulseaudio#microphone": { - "format": "{format_source}", - "format-source": " {volume}%", - "format-source-muted": "", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic", - "on-click-right": "pavucontrol -t 4", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --mic-inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --mic-dec", - "tooltip-format": "{source_desc} | {source_volume}%", - "scroll-step": 5, -}, -"tray": { - "icon-size": 20, - "spacing": 4, -}, -"wireplumber": { - "format": "{icon} {volume} %", - "format-muted": " Mute", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "format-icons": [ - "", "", "󰕾", "" - ], -}, -"wlr/taskbar": { - "format": "{icon} {name}", - "icon-size": 16, - "all-outputs": false, - "tooltip-format": "{title}", - "on-click": "activate", - "on-click-middle": "close", - "ignore-list": [ - "wofi", - "rofi", - "kitty", - "kitty-dropterm" - ], -}, -"custom/cycle_wall": { - "format": " ", - "on-click": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "on-click-right": "$HOME/.config/hypr/UserScripts/WallpaperRandom.sh", - "on-click-middle": "$HOME/.config/hypr/scripts/WaybarStyles.sh", - "tooltip": true, - "tooltip-format": "Left Click: Wallpaper Menu\nMiddle Click: Random wallpaper\nRight Click: Waybar Styles Menu", -}, -"custom/hint": { - "format": "󰺁 HINT!", - "on-click": "$HOME/.config/hypr/scripts/KeyHints.sh", - "tooltip": true, - "tooltip-format": "󱧣 Quick Tips", -}, -// Hypridle inhibitor -"custom/hypridle": { - "format": " 󱫗 ", - "return-type": "json", - "escape": true, - "exec-on-event": true, - "interval": 60, - "exec": "$HOME/.config/hypr/scripts/Hypridle.sh status", - "on-click": "$HOME/.config/hypr/scripts/Hypridle.sh toggle", - "on-click-right": "hyprlock" - }, -"custom/keyboard": { - "exec": "cat $HOME/.cache/kb_layout", - "interval": 1, - "format": " {}", - "on-click": "$HOME/.config/hypr/scripts/SwitchKeyboardLayout.sh", -}, -"custom/light_dark": { - "format": "󰔎", - "on-click": "$HOME/.config/hypr/scripts/DarkLight.sh", - "on-click-right": "$HOME/.config/hypr/scripts/WaybarStyles.sh", - "on-click-middle": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "tooltip": true, - "tooltip-format": "Left Click: Switch Dark-Light Themes\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Styles Menu", -}, -"custom/lock": { - "format": "󰌾", - "on-click": "$HOME/.config/hypr/scripts/LockScreen.sh", - "tooltip": true, - "tooltip-format": "󰷛 Screen Lock", - -}, -"custom/menu": { - "format": "", - "on-click": "pkill rofi || rofi -show drun -modi run,drun,filebrowser,window", - "on-click-middle": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "on-click-right": "$HOME/.config/hypr/scripts/WaybarLayout.sh", - "tooltip": true, - "tooltip-format": "Left Click: Rofi Menu\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Layout Menu", -}, -// This is a custom cava visualizer -"custom/cava_mviz": { - "exec": "$HOME/.config/hypr/scripts/WaybarCava.sh", - "format": "{}" -}, -"custom/playerctl": { - "format": "{}", - "return-type": "json", - "max-length": 35, - "exec": "playerctl -a metadata --format '{\"text\": \"{{artist}} $HOME {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F", - "on-click-middle": "playerctl play-pause", - "on-click": "playerctl previous", - "on-click-right": "playerctl next", - "scroll-step": 5.0, - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "smooth-scrolling-threshold": 1, -}, -"custom/power": { - "format": "⏻ ", - "on-click": "$HOME/.config/hypr/scripts/Wlogout.sh", - "on-click-right": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "tooltip": true, - "tooltip-format": "Left Click: Logout Menu\nRight Click: Change Blur", -}, -"custom/swaync": { - "tooltip": true, - "tooltip-format": "Left Click: Launch Notification Center\nRight Click: Do not Disturb", - "format": "{} {icon}", - "format-icons": { - "notification": "", - "none": "", - "dnd-notification": "", - "dnd-none": "", - "inhibited-notification": "", - "inhibited-none": "", - "dnd-inhibited-notification": "", - "dnd-inhibited-none": "" - }, - "return-type": "json", - "exec-if": "which swaync-client", - "exec": "swaync-client -swb", - "on-click": "sleep 0.1 && swaync-client -t -sw", - "on-click-right": "swaync-client -d -sw", - "escape": true, -}, -// NOTE:! This is only for Arch and Arch Based Distros depend: pacman-contrib -"custom/updater": { - "format": " {}", - "exec": "checkupdates | wc -l", - "exec-if": "[[ $(checkupdates | wc -l) ]]", - "interval": 15, - "on-click": "if command -v paru &> /dev/null; then kitty -T update paru -Syu; else kitty -T update yay -Syu; fi && notify-send 'The system has been updated'", - "tooltip": true, - "tooltip-format": "Left Click: Update System\nArch Linux Only", -}, - -// Separators -"custom/separator#dot": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#dot-line": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#line": { - "format": "|", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank_2": { - "format": " ", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank_3": { - "format": " ", - "interval": "once", - "tooltip": false -}, -// Modules below are for vertical layout -"backlight#vertical": { - "interval": 2, - "align": 0.35, - "rotate": 1, - "format": "{icon}", - //"format-icons": ["󰃞", "󰃟", "󰃠"], - "format-icons": [ - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" - ], - "on-click": "", - "on-click-middle": "", - "on-click-right": "", - "on-update": "", - "on-scroll-up": "$HOME/.config/hypr/scripts/Brightness.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Brightness.sh --dec", - "smooth-scrolling-threshold": 1, - "tooltip-format": "{percent}%", -}, -"clock#vertical": { - "format": "\n{:%H\n%M\n%S\n\n \n%d\n%m\n%y}", - "interval": 1, - //"format": "\n{:%I\n%M\n%p\n\n \n%d\n%m\n%y}", - "tooltip": true, - "tooltip-format": "{calendar}", - "calendar": { - "mode": "year", - "mode-mon-col": 3, - "format": { - "today": "{}", - } - } -}, -"cpu#vertical": { - "format": "󰍛\n{usage}%", - "interval": 1, - "on-click-right": "gnome-system-monitor", -}, -"memory#vertical": { - "interval": 10, - "format": "󰾆\n{percentage}%", - "format-alt": "󰾆\n{used:0.1f}G", - "format-alt-click": "click", - "tooltip": true, - "tooltip-format": "{used:0.1f}GB/{total:0.1f}G", - "on-click-right": "kitty --title btop sh -c 'btop'", -}, -"pulseaudio#vertical": { - "format": "{icon}", - "format-bluetooth": "󰂰", - "format-muted": "󰖁", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": [ - "", "", "󰕾", "" - ], - "tooltip-format": "{icon} {desc} | {volume}%", - "ignored-sinks": [ - "Easy Effects Sink" - ], - }, - "scroll-step": 5.0, - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "tooltip-format": "{icon} {desc} | {volume}%", - "smooth-scrolling-threshold": 1, -}, -"pulseaudio#microphone_vertical": { - "format": "{format_source}", - "format-source": "󰍬", - "format-source-muted": "󰍭", - "on-click-right": "pavucontrol", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --mic-inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --mic-dec", - "max-volume": 100, - "tooltip": true, - "tooltip-format": "{source_desc} | {source_volume}%", -}, -"custom/power_vertical": { - "format": "⏻", - "exec": "echo ; echo 󰟡 power // blur", - "on-click": "$HOME/.config/hypr/scripts/Wlogout.sh", - "on-click-right": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "interval": 86400, // once every day - "tooltip": true, -}, -} diff --git a/hyprland/.config/waybar/Modules.2 b/hyprland/.config/waybar/Modules.2 deleted file mode 100644 index e825e53..0000000 --- a/hyprland/.config/waybar/Modules.2 +++ /dev/null @@ -1,696 +0,0 @@ -//* ---- 💫 https://github.com/JaKooLit 💫 ---- *// -/* Waybar Modules */ - -{ -/* NOTE: hyprland-workspaces on a separate file */ -// Weather and Temperature Modules as this is most like to change always. -// Result is of course easier to edit -"custom/weather": { - "format": "{}", - "format-alt": "{alt}: {}", - "format-alt-click": "click", - "interval": 3600, - "return-type": "json", - "exec": "$HOME/.config/hypr/UserScripts/Weather.sh", - //"exec": "$HOME/.config/hypr/UserScripts/Weather.py", - "exec-if": "ping wttr.in -c1", - "tooltip": true, -}, -"temperature": { - "interval": 10, - "tooltip": true, - "hwmon-path": [ - "/sys/class/hwmon/hwmon1/temp1_input", - "/sys/class/thermal/thermal_zone0/temp" - ], - //"thermal-zone": 0, - "critical-threshold": 82, - "format-critical": "{temperatureC}°C {icon}", - "format": "{temperatureC}°C {icon}", - "format-icons": [ - "󰈸" - ], - "on-click-right": "kitty --title nvtop sh -c 'nvtop'" -}, -"temperature#vertical": { - "interval": 10, - "tooltip": true, - "hwmon-path": [ - "/sys/class/hwmon/hwmon1/temp1_input", - "/sys/class/thermal/thermal_zone0/temp" - ], - //"thermal-zone": 0, - "critical-threshold": 80, - "format-critical": "{icon}\n{temperatureC}°C", - "format": " {icon}", - "format-icons": [ - "󰈸" - ], - "on-click-right": "kitty --title nvtop sh -c 'nvtop'" -}, - - -// GROUP -"group/motherboard": { - "orientation": "horizontal", - "modules": [ - "cpu", - "memory", - "temperature", - "disk", - ] -}, -"group/mobo_drawer": { - "orientation": "inherit", - "drawer": { - "transition-duration": 500, - "children-class": "cpu", - "transition-left-to-right": true - }, - "modules": [ - "temperature", - "cpu", - "memory", - "disk", - ] -}, -"group/laptop": { - "orientation": "inherit", - "modules": [ - "backlight", - "battery", - ] -}, -"group/audio": { - "orientation": "inherit", - "drawer": { - "transition-duration": 500, - "children-class": "pulseaudio", - "transition-left-to-right": true - }, - "modules": [ - "pulseaudio", - "pulseaudio#microphone", - ] -}, -"group/connections": { - "orientation": "inherit", - "drawer": { - "transition-duration": 500, - "children-class": "bluetooth", - "transition-left-to-right": true - }, - "modules": [ - "network", - "bluetooth", - ] -}, -"backlight": { - "interval": 2, - "align": 0, - "rotate": 0, - //"format": "{icon} {percent}%", - "format-icons": [ - " ", - " ", - " ", - "󰃝 ", - "󰃞 ", - "󰃟 ", - "󰃠 " - ], - "format": "{icon}", - //"format-icons": ["","","","","","","","","","","","","","",""], - "tooltip-format": "backlight {percent}%", - "icon-size": 10, - "on-click": "", - "on-click-middle": "", - "on-click-right": "", - "on-update": "", - "on-scroll-up": "$HOME/.config/hypr/scripts/Brightness.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Brightness.sh --dec", - "smooth-scrolling-threshold": 1, -}, -"backlight#2": { - "device": "intel_backlight", - "format": "{icon} {percent}%", - "format-icons": ["", ""] -}, -"battery": { - //"interval": 5, - "align": 0, - "rotate": 0, - //"bat": "BAT1", - //"adapter": "ACAD", - "full-at": 100, - "design-capacity": false, - "states": { - "good": 95, - "warning": 30, - "critical": 15 - }, - "format": "{icon} {capacity}%", - "format-charging": " {capacity}%", - "format-plugged": "󱘖 {capacity}%", - "format-alt-click": "click", - "format-full": "{icon} Full", - "format-alt": "{icon} {time}", - "format-icons": [ - "󰂎", "󰁺", "󰁻", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹" - ], - "format-time": "{H}h {M}min", - "tooltip": true, - "tooltip-format": "{timeTo} {power}w", - "on-click-middle": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "on-click-right": "$HOME/.config/hypr/scripts/Wlogout.sh", -}, -"bluetooth": { - "format": "", - "format-disabled": "󰂳", - "format-connected": "󰂱 {num_connections}", - "tooltip-format": " {device_alias}", - "tooltip-format-connected": "{device_enumerate}", - "tooltip-format-enumerate-connected": " {device_alias} 󰂄{device_battery_percentage}%", - "tooltip": true, - "on-click": "blueman-manager", -}, -"clock": { - "interval": 1, - //"format": " {:%I:%M %p}", // AM PM format - "format": " {:%H:%M:%S}", // 24H - "format-alt": " {:%H:%M  %Y, %d %B, %A}", - "tooltip-format": "{calendar}", - "calendar": { - "mode": "year", - "mode-mon-col": 3, - "weeks-pos": "right", - "on-scroll": 1, - "format": { - "months": "{}", - "days": "{}", - "weeks": "W{}", - "weekdays": "{}", - "today": "{}" - } - } -}, -"actions": { - "on-click-right": "mode", - "on-click-forward": "tz_up", - "on-click-backward": "tz_down", - "on-scroll-up": "shift_up", - "on-scroll-down": "shift_down" -}, -"clock#2": { - //"format": " {:%I:%M %p}", // AM PM format - "format": " {:%H:%M}", // 24H - "format-alt": "{:%A | %H:%M | %e %B}", - "tooltip-format": "{:%Y %B}\n{calendar}" -}, -"clock#3": { - //"format": "{:%I:%M %p - %d/%b}", //for AM/PM - "format": "{:%H:%M - %d/%b}", // 24H - "tooltip": false -}, -"clock#4": { - "interval": 60, - //"format": "{:%B | %a %d, %Y | %I:%M %p}", // AM PM format - "format": "{:%B | %a %d, %Y | %H:%M}", // 24H - "format-alt": "{:%a %b %d, %G}", - "tooltip-format": "{:%B %Y}\n{calendar}", -}, -"clock#5": { - //"format": "{:%A, %I:%M %P}", // AM PM format - "format": "{:%a %d | %H:%M}", // 24H - "format-alt": "{:%A, %d %B, %Y (%R)}" -}, -"cpu": { - "format": "{usage}% 󰍛", - "interval": 1, - "min-length": 5, - "format-alt-click": "click", - "format-alt": "{icon0}{icon1}{icon2}{icon3} {usage:>2}% 󰍛", - "format-icons": [ - "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" - ], - "on-click-right": "gnome-system-monitor", -}, -"disk": { - "interval": 30, - //"format": "󰋊", - "path": "/", - //"format-alt-click": "click", - "format": "{percentage_used}% 󰋊", - //"tooltip": true, - "tooltip-format": "{used} used out of {total} on {path} ({percentage_used}%)", -}, -"hyprland/language": { - "format": "Lang: {}", - "format-en": "US", - "format-tr": "Korea", - "keyboard-name": "at-translated-set-2-keyboard", - "on-click": "hyprctl switchxkblayout $SET_KB next" -}, -"hyprland/submap": { - "format": " {}", // Icon: expand-arrows-alt - "tooltip": false, -}, -"hyprland/window": { - "format": "{}", - "max-length": 20, - "separate-outputs": true, - "offscreen-css": true, - "offscreen-css-text": "(inactive)", - "rewrite": { - "(.*) — Mozilla Firefox": " $1", - "(.*) - fish": "> [$1]", - "(.*) - zsh": "> [$1]", - "(.*) - $term": "> [$1]", - }, -}, -"idle_inhibitor": { - "tooltip": true, - "tooltip-format-activated": "Idle_inhibitor active", - "tooltip-format-deactivated": "Idle_inhibitor not active", - "format": "{icon}", - "format-icons": { - "activated": " ", - "deactivated": " ", - } -}, -"keyboard-state": { - //"numlock": true, - "capslock": true, - "format": { - "numlock": "N {icon}", - "capslock": "󰪛 {icon}", - }, - "format-icons": { - "locked": "", - "unlocked": "" - }, -}, -"memory": { - "interval": 10, - "format": "{used:0.1f}G 󰾆", - "format-alt": "{percentage}% 󰾆", - "format-alt-click": "click", - "tooltip": true, - "tooltip-format": "{used:0.1f}GB/{total:0.1f}G", - "on-click-right": "kitty --title btop sh -c 'btop'" -}, -"mpris": { - "interval": 10, - "format": "{player_icon} ", - "format-paused": "{status_icon} {dynamic}", - "on-click-middle": "playerctl play-pause", - "on-click": "playerctl previous", - "on-click-right": "playerctl next", - "scroll-step": 5.0, - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "smooth-scrolling-threshold": 1, - "player-icons": { - "chromium": "", - "default": "", - "firefox": "", - "kdeconnect": "", - "mopidy": "", - "mpv": "󰐹", - "spotify": "", - "vlc": "󰕼", - }, - "status-icons": { - "paused": "󰐎", - "playing": "", - "stopped": "", - }, - // "ignored-players": ["firefox"] - "max-length": 30, -}, -"network": { - "format": "{ifname}", - "format-wifi": "{icon}", - "format-ethernet": "󰌘", - "format-disconnected": "󰌙", - "tooltip-format": "{ipaddr}  {bandwidthUpBits}  {bandwidthDownBits}", - "format-linked": "󰈁 {ifname} (No IP)", - "tooltip-format-wifi": "{essid} {icon} {signalStrength}%", - "tooltip-format-ethernet": "{ifname} 󰌘", - "tooltip-format-disconnected": "󰌙 Disconnected", - "max-length": 30, - "format-icons": [ - "󰤯", "󰤟", "󰤢", "󰤥", "󰤨" - ], - "on-click-right": "kitty nmtui" -}, -"network#speed": { - "interval": 1, - "format": "{ifname}", - "format-wifi": "{icon}  {bandwidthUpBytes}  {bandwidthDownBytes}", - "format-ethernet": "󰌘  {bandwidthUpBytes}  {bandwidthDownBytes}", - "format-disconnected": "󰌙", - "tooltip-format": "{ipaddr}", - "format-linked": "󰈁 {ifname} (No IP)", - "tooltip-format-wifi": "{essid} {icon} {signalStrength}%", - "tooltip-format-ethernet": "{ifname} 󰌘", - "tooltip-format-disconnected": "󰌙 Disconnected", - "min-length": 24, - "max-length": 24, - "format-icons": [ - "󰤯", "󰤟", "󰤢", "󰤥", "󰤨" - ] -}, -"power-profiles-daemon": { - "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", - "tooltip": true, - "format-icons": { - "default": "", - "performance": "", - "balanced": "", - "power-saver": "" - } -}, -"pulseaudio": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} 󰂰 {volume}%", - "format-muted": "󰖁", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": [ - "", "", "󰕾", "" - ], - "ignored-sinks": [ - "Easy Effects Sink" - ], - }, - "scroll-step": 5.0, - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "tooltip-format": "{icon} {desc} | {volume}%", - "smooth-scrolling-threshold": 1, -}, -"pulseaudio#1": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} {volume}%", - "format-bluetooth-muted": " {icon}", - "format-muted": "󰸈", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", "", ""] - }, - "on-click": "pamixer --toggle-mute", - "on-click-right": "pavucontrol -t 3", - "tooltip": true, - "tooltip-format": "{icon} {desc} | {volume}%", -}, -"pulseaudio#microphone": { - "format": "{format_source}", - "format-source": " {volume}%", - "format-source-muted": "", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic", - "on-click-right": "pavucontrol -t 4", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --mic-inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --mic-dec", - "tooltip-format": "{source_desc} | {source_volume}%", - "scroll-step": 5, -}, -"tray": { - "icon-size": 20, - "spacing": 4, -}, -"wireplumber": { - "format": "{icon} {volume} %", - "format-muted": " Mute", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "format-icons": [ - "", "", "󰕾", "" - ], -}, -"wlr/taskbar": { - "format": "{icon} {name}", - "icon-size": 16, - "all-outputs": false, - "tooltip-format": "{title}", - "on-click": "activate", - "on-click-middle": "close", - "ignore-list": [ - "wofi", - "rofi", - "kitty", - "kitty-dropterm" - ], -}, -"custom/cycle_wall": { - "format": " ", - "on-click": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "on-click-right": "$HOME/.config/hypr/UserScripts/WallpaperRandom.sh", - "on-click-middle": "$HOME/.config/hypr/scripts/WaybarStyles.sh", - "tooltip": true, - "tooltip-format": "Left Click: Wallpaper Menu\nMiddle Click: Random wallpaper\nRight Click: Waybar Styles Menu", -}, -"custom/hint": { - "format": "󰺁 HINT!", - "on-click": "$HOME/.config/hypr/scripts/KeyHints.sh", - "tooltip": true, - "tooltip-format": "󱧣 Quick Tips", -}, -// Hypridle inhibitor -"custom/hypridle": { - "format": " 󱫗 ", - "return-type": "json", - "escape": true, - "exec-on-event": true, - "interval": 60, - "exec": "$HOME/.config/hypr/scripts/Hypridle.sh status", - "on-click": "$HOME/.config/hypr/scripts/Hypridle.sh toggle", - "on-click-right": "hyprlock" - }, -"custom/keyboard": { - "exec": "cat $HOME/.cache/kb_layout", - "interval": 1, - "format": " {}", - "on-click": "$HOME/.config/hypr/scripts/SwitchKeyboardLayout.sh", -}, -"custom/light_dark": { - "format": "󰔎", - "on-click": "$HOME/.config/hypr/scripts/DarkLight.sh", - "on-click-right": "$HOME/.config/hypr/scripts/WaybarStyles.sh", - "on-click-middle": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "tooltip": true, - "tooltip-format": "Left Click: Switch Dark-Light Themes\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Styles Menu", -}, -"custom/lock": { - "format": "󰌾", - "on-click": "$HOME/.config/hypr/scripts/LockScreen.sh", - "tooltip": true, - "tooltip-format": "󰷛 Screen Lock", - -}, -"custom/menu": { - "format": "", - "on-click": "pkill rofi || rofi -show drun -modi run,drun,filebrowser,window", - "on-click-middle": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "on-click-right": "$HOME/.config/hypr/scripts/WaybarLayout.sh", - "tooltip": true, - "tooltip-format": "Left Click: Rofi Menu\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Layout Menu", -}, -// This is a custom cava visualizer -"custom/cava_mviz": { - "exec": "$HOME/.config/hypr/scripts/WaybarCava.sh", - "format": "{}" -}, -"custom/playerctl": { - "format": "{}", - "return-type": "json", - "max-length": 35, - "exec": "playerctl -a metadata --format '{\"text\": \"{{artist}} $HOME {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F", - "on-click-middle": "playerctl play-pause", - "on-click": "playerctl previous", - "on-click-right": "playerctl next", - "scroll-step": 5.0, - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "smooth-scrolling-threshold": 1, -}, -"custom/power": { - "format": "⏻ ", - "on-click": "$HOME/.config/hypr/scripts/Wlogout.sh", - "on-click-right": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "tooltip": true, - "tooltip-format": "Left Click: Logout Menu\nRight Click: Change Blur", -}, -"custom/swaync": { - "tooltip": true, - "tooltip-format": "Left Click: Launch Notification Center\nRight Click: Do not Disturb", - "format": "{} {icon}", - "format-icons": { - "notification": "", - "none": "", - "dnd-notification": "", - "dnd-none": "", - "inhibited-notification": "", - "inhibited-none": "", - "dnd-inhibited-notification": "", - "dnd-inhibited-none": "" - }, - "return-type": "json", - "exec-if": "which swaync-client", - "exec": "swaync-client -swb", - "on-click": "sleep 0.1 && swaync-client -t -sw", - "on-click-right": "swaync-client -d -sw", - "escape": true, -}, -// NOTE:! This is only for Arch and Arch Based Distros depend: pacman-contrib -"custom/updater": { - "format": " {}", - "exec": "checkupdates | wc -l", - "exec-if": "[[ $(checkupdates | wc -l) ]]", - "interval": 15, - "on-click": "if command -v paru &> /dev/null; then kitty -T update paru -Syu; else kitty -T update yay -Syu; fi && notify-send 'The system has been updated'", - "tooltip": true, - "tooltip-format": "Left Click: Update System\nArch Linux Only", -}, - -// Separators -"custom/separator#dot": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#dot-line": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#line": { - "format": "|", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank_2": { - "format": " ", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank_3": { - "format": " ", - "interval": "once", - "tooltip": false -}, -// Modules below are for vertical layout -"backlight#vertical": { - "interval": 2, - "align": 0.35, - "rotate": 1, - "format": "{icon}", - //"format-icons": ["󰃞", "󰃟", "󰃠"], - "format-icons": [ - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" - ], - "on-click": "", - "on-click-middle": "", - "on-click-right": "", - "on-update": "", - "on-scroll-up": "$HOME/.config/hypr/scripts/Brightness.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Brightness.sh --dec", - "smooth-scrolling-threshold": 1, - "tooltip-format": "{percent}%", -}, -"clock#vertical": { - "format": "\n{:%H\n%M\n%S\n\n \n%d\n%m\n%y}", - "interval": 1, - //"format": "\n{:%I\n%M\n%p\n\n \n%d\n%m\n%y}", - "tooltip": true, - "tooltip-format": "{calendar}", - "calendar": { - "mode": "year", - "mode-mon-col": 3, - "format": { - "today": "{}", - } - } -}, -"cpu#vertical": { - "format": "󰍛\n{usage}%", - "interval": 1, - "on-click-right": "gnome-system-monitor", -}, -"memory#vertical": { - "interval": 10, - "format": "󰾆\n{percentage}%", - "format-alt": "󰾆\n{used:0.1f}G", - "format-alt-click": "click", - "tooltip": true, - "tooltip-format": "{used:0.1f}GB/{total:0.1f}G", - "on-click-right": "kitty --title btop sh -c 'btop'", -}, -"pulseaudio#vertical": { - "format": "{icon}", - "format-bluetooth": "󰂰", - "format-muted": "󰖁", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": [ - "", "", "󰕾", "" - ], - "tooltip-format": "{icon} {desc} | {volume}%", - "ignored-sinks": [ - "Easy Effects Sink" - ], - }, - "scroll-step": 5.0, - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "tooltip-format": "{icon} {desc} | {volume}%", - "smooth-scrolling-threshold": 1, -}, -"pulseaudio#microphone_vertical": { - "format": "{format_source}", - "format-source": "󰍬", - "format-source-muted": "󰍭", - "on-click-right": "pavucontrol", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --mic-inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --mic-dec", - "max-volume": 100, - "tooltip": true, - "tooltip-format": "{source_desc} | {source_volume}%", -}, -"custom/power_vertical": { - "format": "⏻", - "exec": "echo ; echo 󰟡 power // blur", - "on-click": "$HOME/.config/hypr/scripts/Wlogout.sh", - "on-click-right": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "interval": 86400, // once every day - "tooltip": true, -}, -} diff --git a/hyprland/.config/waybar/Modules.3 b/hyprland/.config/waybar/Modules.3 deleted file mode 100644 index e825e53..0000000 --- a/hyprland/.config/waybar/Modules.3 +++ /dev/null @@ -1,696 +0,0 @@ -//* ---- 💫 https://github.com/JaKooLit 💫 ---- *// -/* Waybar Modules */ - -{ -/* NOTE: hyprland-workspaces on a separate file */ -// Weather and Temperature Modules as this is most like to change always. -// Result is of course easier to edit -"custom/weather": { - "format": "{}", - "format-alt": "{alt}: {}", - "format-alt-click": "click", - "interval": 3600, - "return-type": "json", - "exec": "$HOME/.config/hypr/UserScripts/Weather.sh", - //"exec": "$HOME/.config/hypr/UserScripts/Weather.py", - "exec-if": "ping wttr.in -c1", - "tooltip": true, -}, -"temperature": { - "interval": 10, - "tooltip": true, - "hwmon-path": [ - "/sys/class/hwmon/hwmon1/temp1_input", - "/sys/class/thermal/thermal_zone0/temp" - ], - //"thermal-zone": 0, - "critical-threshold": 82, - "format-critical": "{temperatureC}°C {icon}", - "format": "{temperatureC}°C {icon}", - "format-icons": [ - "󰈸" - ], - "on-click-right": "kitty --title nvtop sh -c 'nvtop'" -}, -"temperature#vertical": { - "interval": 10, - "tooltip": true, - "hwmon-path": [ - "/sys/class/hwmon/hwmon1/temp1_input", - "/sys/class/thermal/thermal_zone0/temp" - ], - //"thermal-zone": 0, - "critical-threshold": 80, - "format-critical": "{icon}\n{temperatureC}°C", - "format": " {icon}", - "format-icons": [ - "󰈸" - ], - "on-click-right": "kitty --title nvtop sh -c 'nvtop'" -}, - - -// GROUP -"group/motherboard": { - "orientation": "horizontal", - "modules": [ - "cpu", - "memory", - "temperature", - "disk", - ] -}, -"group/mobo_drawer": { - "orientation": "inherit", - "drawer": { - "transition-duration": 500, - "children-class": "cpu", - "transition-left-to-right": true - }, - "modules": [ - "temperature", - "cpu", - "memory", - "disk", - ] -}, -"group/laptop": { - "orientation": "inherit", - "modules": [ - "backlight", - "battery", - ] -}, -"group/audio": { - "orientation": "inherit", - "drawer": { - "transition-duration": 500, - "children-class": "pulseaudio", - "transition-left-to-right": true - }, - "modules": [ - "pulseaudio", - "pulseaudio#microphone", - ] -}, -"group/connections": { - "orientation": "inherit", - "drawer": { - "transition-duration": 500, - "children-class": "bluetooth", - "transition-left-to-right": true - }, - "modules": [ - "network", - "bluetooth", - ] -}, -"backlight": { - "interval": 2, - "align": 0, - "rotate": 0, - //"format": "{icon} {percent}%", - "format-icons": [ - " ", - " ", - " ", - "󰃝 ", - "󰃞 ", - "󰃟 ", - "󰃠 " - ], - "format": "{icon}", - //"format-icons": ["","","","","","","","","","","","","","",""], - "tooltip-format": "backlight {percent}%", - "icon-size": 10, - "on-click": "", - "on-click-middle": "", - "on-click-right": "", - "on-update": "", - "on-scroll-up": "$HOME/.config/hypr/scripts/Brightness.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Brightness.sh --dec", - "smooth-scrolling-threshold": 1, -}, -"backlight#2": { - "device": "intel_backlight", - "format": "{icon} {percent}%", - "format-icons": ["", ""] -}, -"battery": { - //"interval": 5, - "align": 0, - "rotate": 0, - //"bat": "BAT1", - //"adapter": "ACAD", - "full-at": 100, - "design-capacity": false, - "states": { - "good": 95, - "warning": 30, - "critical": 15 - }, - "format": "{icon} {capacity}%", - "format-charging": " {capacity}%", - "format-plugged": "󱘖 {capacity}%", - "format-alt-click": "click", - "format-full": "{icon} Full", - "format-alt": "{icon} {time}", - "format-icons": [ - "󰂎", "󰁺", "󰁻", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹" - ], - "format-time": "{H}h {M}min", - "tooltip": true, - "tooltip-format": "{timeTo} {power}w", - "on-click-middle": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "on-click-right": "$HOME/.config/hypr/scripts/Wlogout.sh", -}, -"bluetooth": { - "format": "", - "format-disabled": "󰂳", - "format-connected": "󰂱 {num_connections}", - "tooltip-format": " {device_alias}", - "tooltip-format-connected": "{device_enumerate}", - "tooltip-format-enumerate-connected": " {device_alias} 󰂄{device_battery_percentage}%", - "tooltip": true, - "on-click": "blueman-manager", -}, -"clock": { - "interval": 1, - //"format": " {:%I:%M %p}", // AM PM format - "format": " {:%H:%M:%S}", // 24H - "format-alt": " {:%H:%M  %Y, %d %B, %A}", - "tooltip-format": "{calendar}", - "calendar": { - "mode": "year", - "mode-mon-col": 3, - "weeks-pos": "right", - "on-scroll": 1, - "format": { - "months": "{}", - "days": "{}", - "weeks": "W{}", - "weekdays": "{}", - "today": "{}" - } - } -}, -"actions": { - "on-click-right": "mode", - "on-click-forward": "tz_up", - "on-click-backward": "tz_down", - "on-scroll-up": "shift_up", - "on-scroll-down": "shift_down" -}, -"clock#2": { - //"format": " {:%I:%M %p}", // AM PM format - "format": " {:%H:%M}", // 24H - "format-alt": "{:%A | %H:%M | %e %B}", - "tooltip-format": "{:%Y %B}\n{calendar}" -}, -"clock#3": { - //"format": "{:%I:%M %p - %d/%b}", //for AM/PM - "format": "{:%H:%M - %d/%b}", // 24H - "tooltip": false -}, -"clock#4": { - "interval": 60, - //"format": "{:%B | %a %d, %Y | %I:%M %p}", // AM PM format - "format": "{:%B | %a %d, %Y | %H:%M}", // 24H - "format-alt": "{:%a %b %d, %G}", - "tooltip-format": "{:%B %Y}\n{calendar}", -}, -"clock#5": { - //"format": "{:%A, %I:%M %P}", // AM PM format - "format": "{:%a %d | %H:%M}", // 24H - "format-alt": "{:%A, %d %B, %Y (%R)}" -}, -"cpu": { - "format": "{usage}% 󰍛", - "interval": 1, - "min-length": 5, - "format-alt-click": "click", - "format-alt": "{icon0}{icon1}{icon2}{icon3} {usage:>2}% 󰍛", - "format-icons": [ - "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" - ], - "on-click-right": "gnome-system-monitor", -}, -"disk": { - "interval": 30, - //"format": "󰋊", - "path": "/", - //"format-alt-click": "click", - "format": "{percentage_used}% 󰋊", - //"tooltip": true, - "tooltip-format": "{used} used out of {total} on {path} ({percentage_used}%)", -}, -"hyprland/language": { - "format": "Lang: {}", - "format-en": "US", - "format-tr": "Korea", - "keyboard-name": "at-translated-set-2-keyboard", - "on-click": "hyprctl switchxkblayout $SET_KB next" -}, -"hyprland/submap": { - "format": " {}", // Icon: expand-arrows-alt - "tooltip": false, -}, -"hyprland/window": { - "format": "{}", - "max-length": 20, - "separate-outputs": true, - "offscreen-css": true, - "offscreen-css-text": "(inactive)", - "rewrite": { - "(.*) — Mozilla Firefox": " $1", - "(.*) - fish": "> [$1]", - "(.*) - zsh": "> [$1]", - "(.*) - $term": "> [$1]", - }, -}, -"idle_inhibitor": { - "tooltip": true, - "tooltip-format-activated": "Idle_inhibitor active", - "tooltip-format-deactivated": "Idle_inhibitor not active", - "format": "{icon}", - "format-icons": { - "activated": " ", - "deactivated": " ", - } -}, -"keyboard-state": { - //"numlock": true, - "capslock": true, - "format": { - "numlock": "N {icon}", - "capslock": "󰪛 {icon}", - }, - "format-icons": { - "locked": "", - "unlocked": "" - }, -}, -"memory": { - "interval": 10, - "format": "{used:0.1f}G 󰾆", - "format-alt": "{percentage}% 󰾆", - "format-alt-click": "click", - "tooltip": true, - "tooltip-format": "{used:0.1f}GB/{total:0.1f}G", - "on-click-right": "kitty --title btop sh -c 'btop'" -}, -"mpris": { - "interval": 10, - "format": "{player_icon} ", - "format-paused": "{status_icon} {dynamic}", - "on-click-middle": "playerctl play-pause", - "on-click": "playerctl previous", - "on-click-right": "playerctl next", - "scroll-step": 5.0, - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "smooth-scrolling-threshold": 1, - "player-icons": { - "chromium": "", - "default": "", - "firefox": "", - "kdeconnect": "", - "mopidy": "", - "mpv": "󰐹", - "spotify": "", - "vlc": "󰕼", - }, - "status-icons": { - "paused": "󰐎", - "playing": "", - "stopped": "", - }, - // "ignored-players": ["firefox"] - "max-length": 30, -}, -"network": { - "format": "{ifname}", - "format-wifi": "{icon}", - "format-ethernet": "󰌘", - "format-disconnected": "󰌙", - "tooltip-format": "{ipaddr}  {bandwidthUpBits}  {bandwidthDownBits}", - "format-linked": "󰈁 {ifname} (No IP)", - "tooltip-format-wifi": "{essid} {icon} {signalStrength}%", - "tooltip-format-ethernet": "{ifname} 󰌘", - "tooltip-format-disconnected": "󰌙 Disconnected", - "max-length": 30, - "format-icons": [ - "󰤯", "󰤟", "󰤢", "󰤥", "󰤨" - ], - "on-click-right": "kitty nmtui" -}, -"network#speed": { - "interval": 1, - "format": "{ifname}", - "format-wifi": "{icon}  {bandwidthUpBytes}  {bandwidthDownBytes}", - "format-ethernet": "󰌘  {bandwidthUpBytes}  {bandwidthDownBytes}", - "format-disconnected": "󰌙", - "tooltip-format": "{ipaddr}", - "format-linked": "󰈁 {ifname} (No IP)", - "tooltip-format-wifi": "{essid} {icon} {signalStrength}%", - "tooltip-format-ethernet": "{ifname} 󰌘", - "tooltip-format-disconnected": "󰌙 Disconnected", - "min-length": 24, - "max-length": 24, - "format-icons": [ - "󰤯", "󰤟", "󰤢", "󰤥", "󰤨" - ] -}, -"power-profiles-daemon": { - "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", - "tooltip": true, - "format-icons": { - "default": "", - "performance": "", - "balanced": "", - "power-saver": "" - } -}, -"pulseaudio": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} 󰂰 {volume}%", - "format-muted": "󰖁", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": [ - "", "", "󰕾", "" - ], - "ignored-sinks": [ - "Easy Effects Sink" - ], - }, - "scroll-step": 5.0, - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "tooltip-format": "{icon} {desc} | {volume}%", - "smooth-scrolling-threshold": 1, -}, -"pulseaudio#1": { - "format": "{icon} {volume}%", - "format-bluetooth": "{icon} {volume}%", - "format-bluetooth-muted": " {icon}", - "format-muted": "󰸈", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": ["", "", ""] - }, - "on-click": "pamixer --toggle-mute", - "on-click-right": "pavucontrol -t 3", - "tooltip": true, - "tooltip-format": "{icon} {desc} | {volume}%", -}, -"pulseaudio#microphone": { - "format": "{format_source}", - "format-source": " {volume}%", - "format-source-muted": "", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic", - "on-click-right": "pavucontrol -t 4", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --mic-inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --mic-dec", - "tooltip-format": "{source_desc} | {source_volume}%", - "scroll-step": 5, -}, -"tray": { - "icon-size": 20, - "spacing": 4, -}, -"wireplumber": { - "format": "{icon} {volume} %", - "format-muted": " Mute", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "format-icons": [ - "", "", "󰕾", "" - ], -}, -"wlr/taskbar": { - "format": "{icon} {name}", - "icon-size": 16, - "all-outputs": false, - "tooltip-format": "{title}", - "on-click": "activate", - "on-click-middle": "close", - "ignore-list": [ - "wofi", - "rofi", - "kitty", - "kitty-dropterm" - ], -}, -"custom/cycle_wall": { - "format": " ", - "on-click": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "on-click-right": "$HOME/.config/hypr/UserScripts/WallpaperRandom.sh", - "on-click-middle": "$HOME/.config/hypr/scripts/WaybarStyles.sh", - "tooltip": true, - "tooltip-format": "Left Click: Wallpaper Menu\nMiddle Click: Random wallpaper\nRight Click: Waybar Styles Menu", -}, -"custom/hint": { - "format": "󰺁 HINT!", - "on-click": "$HOME/.config/hypr/scripts/KeyHints.sh", - "tooltip": true, - "tooltip-format": "󱧣 Quick Tips", -}, -// Hypridle inhibitor -"custom/hypridle": { - "format": " 󱫗 ", - "return-type": "json", - "escape": true, - "exec-on-event": true, - "interval": 60, - "exec": "$HOME/.config/hypr/scripts/Hypridle.sh status", - "on-click": "$HOME/.config/hypr/scripts/Hypridle.sh toggle", - "on-click-right": "hyprlock" - }, -"custom/keyboard": { - "exec": "cat $HOME/.cache/kb_layout", - "interval": 1, - "format": " {}", - "on-click": "$HOME/.config/hypr/scripts/SwitchKeyboardLayout.sh", -}, -"custom/light_dark": { - "format": "󰔎", - "on-click": "$HOME/.config/hypr/scripts/DarkLight.sh", - "on-click-right": "$HOME/.config/hypr/scripts/WaybarStyles.sh", - "on-click-middle": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "tooltip": true, - "tooltip-format": "Left Click: Switch Dark-Light Themes\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Styles Menu", -}, -"custom/lock": { - "format": "󰌾", - "on-click": "$HOME/.config/hypr/scripts/LockScreen.sh", - "tooltip": true, - "tooltip-format": "󰷛 Screen Lock", - -}, -"custom/menu": { - "format": "", - "on-click": "pkill rofi || rofi -show drun -modi run,drun,filebrowser,window", - "on-click-middle": "$HOME/.config/hypr/UserScripts/WallpaperSelect.sh", - "on-click-right": "$HOME/.config/hypr/scripts/WaybarLayout.sh", - "tooltip": true, - "tooltip-format": "Left Click: Rofi Menu\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Layout Menu", -}, -// This is a custom cava visualizer -"custom/cava_mviz": { - "exec": "$HOME/.config/hypr/scripts/WaybarCava.sh", - "format": "{}" -}, -"custom/playerctl": { - "format": "{}", - "return-type": "json", - "max-length": 35, - "exec": "playerctl -a metadata --format '{\"text\": \"{{artist}} $HOME {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F", - "on-click-middle": "playerctl play-pause", - "on-click": "playerctl previous", - "on-click-right": "playerctl next", - "scroll-step": 5.0, - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "smooth-scrolling-threshold": 1, -}, -"custom/power": { - "format": "⏻ ", - "on-click": "$HOME/.config/hypr/scripts/Wlogout.sh", - "on-click-right": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "tooltip": true, - "tooltip-format": "Left Click: Logout Menu\nRight Click: Change Blur", -}, -"custom/swaync": { - "tooltip": true, - "tooltip-format": "Left Click: Launch Notification Center\nRight Click: Do not Disturb", - "format": "{} {icon}", - "format-icons": { - "notification": "", - "none": "", - "dnd-notification": "", - "dnd-none": "", - "inhibited-notification": "", - "inhibited-none": "", - "dnd-inhibited-notification": "", - "dnd-inhibited-none": "" - }, - "return-type": "json", - "exec-if": "which swaync-client", - "exec": "swaync-client -swb", - "on-click": "sleep 0.1 && swaync-client -t -sw", - "on-click-right": "swaync-client -d -sw", - "escape": true, -}, -// NOTE:! This is only for Arch and Arch Based Distros depend: pacman-contrib -"custom/updater": { - "format": " {}", - "exec": "checkupdates | wc -l", - "exec-if": "[[ $(checkupdates | wc -l) ]]", - "interval": 15, - "on-click": "if command -v paru &> /dev/null; then kitty -T update paru -Syu; else kitty -T update yay -Syu; fi && notify-send 'The system has been updated'", - "tooltip": true, - "tooltip-format": "Left Click: Update System\nArch Linux Only", -}, - -// Separators -"custom/separator#dot": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#dot-line": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#line": { - "format": "|", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank": { - "format": "", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank_2": { - "format": " ", - "interval": "once", - "tooltip": false -}, -"custom/separator#blank_3": { - "format": " ", - "interval": "once", - "tooltip": false -}, -// Modules below are for vertical layout -"backlight#vertical": { - "interval": 2, - "align": 0.35, - "rotate": 1, - "format": "{icon}", - //"format-icons": ["󰃞", "󰃟", "󰃠"], - "format-icons": [ - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" - ], - "on-click": "", - "on-click-middle": "", - "on-click-right": "", - "on-update": "", - "on-scroll-up": "$HOME/.config/hypr/scripts/Brightness.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Brightness.sh --dec", - "smooth-scrolling-threshold": 1, - "tooltip-format": "{percent}%", -}, -"clock#vertical": { - "format": "\n{:%H\n%M\n%S\n\n \n%d\n%m\n%y}", - "interval": 1, - //"format": "\n{:%I\n%M\n%p\n\n \n%d\n%m\n%y}", - "tooltip": true, - "tooltip-format": "{calendar}", - "calendar": { - "mode": "year", - "mode-mon-col": 3, - "format": { - "today": "{}", - } - } -}, -"cpu#vertical": { - "format": "󰍛\n{usage}%", - "interval": 1, - "on-click-right": "gnome-system-monitor", -}, -"memory#vertical": { - "interval": 10, - "format": "󰾆\n{percentage}%", - "format-alt": "󰾆\n{used:0.1f}G", - "format-alt-click": "click", - "tooltip": true, - "tooltip-format": "{used:0.1f}GB/{total:0.1f}G", - "on-click-right": "kitty --title btop sh -c 'btop'", -}, -"pulseaudio#vertical": { - "format": "{icon}", - "format-bluetooth": "󰂰", - "format-muted": "󰖁", - "format-icons": { - "headphone": "", - "hands-free": "", - "headset": "", - "phone": "", - "portable": "", - "car": "", - "default": [ - "", "", "󰕾", "" - ], - "tooltip-format": "{icon} {desc} | {volume}%", - "ignored-sinks": [ - "Easy Effects Sink" - ], - }, - "scroll-step": 5.0, - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle", - "on-click-right": "pavucontrol -t 3", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --dec", - "tooltip-format": "{icon} {desc} | {volume}%", - "smooth-scrolling-threshold": 1, -}, -"pulseaudio#microphone_vertical": { - "format": "{format_source}", - "format-source": "󰍬", - "format-source-muted": "󰍭", - "on-click-right": "pavucontrol", - "on-click": "$HOME/.config/hypr/scripts/Volume.sh --toggle-mic", - "on-scroll-up": "$HOME/.config/hypr/scripts/Volume.sh --mic-inc", - "on-scroll-down": "$HOME/.config/hypr/scripts/Volume.sh --mic-dec", - "max-volume": 100, - "tooltip": true, - "tooltip-format": "{source_desc} | {source_volume}%", -}, -"custom/power_vertical": { - "format": "⏻", - "exec": "echo ; echo 󰟡 power // blur", - "on-click": "$HOME/.config/hypr/scripts/Wlogout.sh", - "on-click-right": "$HOME/.config/hypr/scripts/ChangeBlur.sh", - "interval": 86400, // once every day - "tooltip": true, -}, -} diff --git a/hyprland/.config/waybar/wallust/colors-waybar.css b/hyprland/.config/waybar/wallust/colors-waybar.css index 6fc876b..467de4d 100644 --- a/hyprland/.config/waybar/wallust/colors-waybar.css +++ b/hyprland/.config/waybar/wallust/colors-waybar.css @@ -1,23 +1,23 @@ /* ---- 💫 https://github.com/JaKooLit 💫 ---- */ /* wallust template - colors-waybar */ -@define-color foreground #D3E2F1; -@define-color background rgba(31,31,34,0.25); -@define-color cursor #D3E2F1; +@define-color foreground #ECE7E2; +@define-color background rgba(0,0,4,0.25); +@define-color cursor #ECE7E2; -@define-color color0 #464549; -@define-color color1 #171623; -@define-color color2 #1B1D2A; -@define-color color3 #37455A; -@define-color color4 #40546A; -@define-color color5 #4E6781; -@define-color color6 #6082A0; -@define-color color7 #B7CDE2; -@define-color color8 #80909E; -@define-color color9 #1E1E2E; -@define-color color10 #242738; -@define-color color11 #495D77; -@define-color color12 #56708E; -@define-color color13 #6889AC; -@define-color color14 #80ADD6; -@define-color color15 #B7CDE2; +@define-color color0 #000004; +@define-color color1 #292B33; +@define-color color2 #523F41; +@define-color color3 #49596E; +@define-color color4 #825752; +@define-color color5 #905E56; +@define-color color6 #978B80; +@define-color color7 #DCD4CD; +@define-color color8 #9A948F; +@define-color color9 #373944; +@define-color color10 #6E5457; +@define-color color11 #627792; +@define-color color12 #AE746D; +@define-color color13 #C07D73; +@define-color color14 #C9B9AB; +@define-color color15 #DCD4CD; diff --git a/kitty/.config/kitty/kitty.conf b/kitty/.config/kitty/kitty.conf index 7a1ae9f..d5b4249 100644 --- a/kitty/.config/kitty/kitty.conf +++ b/kitty/.config/kitty/kitty.conf @@ -1,172 +1,39 @@ # vim:fileencoding=utf-8:ft=conf -# Font family. You can also specify different fonts for the -# bold/italic/bold-italic variants. By default they are derived automatically, -# by the OSes font system. Setting them manually is useful for font families -# that have many weight variants like Book, Medium, Thick, etc. For example: -# font_family Operator Mono Book -# bold_font Operator Mono Thick -# bold_italic_font Operator Mono Medium -# font_family Input Mono -#font_family FiraCode Nerd Font Mono font_family MesloLGS Nerd Font Mono italic_font auto bold_font auto bold_italic_font auto # Font size (in pts) -font_size 14.0 +font_size 16.0 -# The foreground color -# foreground #c0b18b - -# The background color -# background #262626 +window_padding_width 4 +linux_display_server auto background_opacity 0.9 -# The foreground for selections -# selection_foreground #2f2f2f - -# The background for selections -# selection_background #d75f5f - -# The cursor color -# cursor #8fee96 - -# The cursor shape can be one of (block, beam, underline) cursor_shape block - -# The interval (in seconds) at which to blink the cursor. Set to zero to -# disable blinking. cursor_blink_interval 0.5 - -# Stop blinking cursor after the specified number of seconds of keyboard inactivity. Set to -# zero or a negative number to never stop blinking. cursor_stop_blinking_after 15.0 - -# Number of lines of history to keep in memory for scrolling back scrollback_lines 2000 - -# Program with which to view scrollback in a new window. The scrollback buffer is passed as -# STDIN to this program. If you change it, make sure the program you use can -# handle ANSI escape sequences for colors and text formatting. scrollback_pager less +G -R - -# Wheel scroll multiplier (modify the amount scrolled by the mouse wheel) wheel_scroll_multiplier 5.0 - -# The interval between successive clicks to detect double/triple clicks (in seconds) click_interval 0.5 - -# Characters considered part of a word when double clicking. In addition to these characters -# any character that is marked as an alpha-numeric character in the unicode -# database will be matched. select_by_word_characters :@-./_~?&=%+# - -# Hide mouse cursor after the specified number of seconds of the mouse not being used. Set to -# zero or a negative number to disable mouse cursor hiding. mouse_hide_wait 0.0 - -# The enabled window layouts. A comma separated list of layout names. The special value * means -# all layouts. The first listed layout will be used as the startup layout. -# For a list of available layouts, see the file layouts.py enabled_layouts * - -# If enabled, the window size will be remembered so that new instances of kitty will have the same -# size as the previous instance. If disabled, the window will initially have size configured -# by initial_window_width/height, in pixels. remember_window_size no initial_window_width 640 initial_window_height 400 - -# Delay (in milliseconds) between screen updates. Decreasing it, increases fps -# at the cost of more CPU usage. The default value yields ~100fps which is more -# that sufficient for most uses. -# repaint_delay 10 repaint_delay 10 - -# Delay (in milliseconds) before input from the program running in the terminal -# is processed. Note that decreasing it will increase responsiveness, but also -# increase CPU usage and might cause flicker in full screen programs that -# redraw the entire screen on each loop, because kitty is so fast that partial -# screen updates will be drawn. input_delay 3 - -# Visual bell duration. Flash the screen when a bell occurs for the specified number of -# seconds. Set to zero to disable. visual_bell_duration 0.0 - -# Enable/disable the audio bell. Useful in environments that require silence. enable_audio_bell no - -# The modifier keys to press when clicking with the mouse on URLs to open the URL open_url_modifiers ctrl+shift - -# The program with which to open URLs that are clicked on. The special value "default" means to -# use the operating system's default URL handler. open_url_with default - -# The value of the TERM environment variable to set term xterm-kitty - -# The width (in pts) of window borders. Will be rounded to the nearest number of pixels based on screen resolution. window_border_width 0 - window_margin_width 15 -# The color for the border of the active window -# active_border_color #ffffff - -# The color for the border of inactive windows -# inactive_border_color #cccccc - -# Tab-bar colors -# active_tab_foreground #000 -# active_tab_background #eee -# inactive_tab_foreground #444 -# inactive_tab_background #999 - - -# The 16 terminal colors. There are 8 basic colors, each color has a dull and -# bright version. - -# black -# color0 #2f2f2f -# color8 #656565 - -# red -# color1 #d75f5f -# color9 #d75f5f - -# green -# color2 #d4d232 -# color10 #8fee96 - -# yellow -# color3 #af865a -# color11 #cd950c - -# blue -# color4 #22c3a1 -# color12 #22c3a1 - -# magenta -# color5 #775759 -# color13 #775759 - -# cyan -# color6 #84edb9 -# color14 #84edb9 - -# white -# color7 #c0b18b -# color15 #d8d8d8 - -# Key mapping -# For a list of key names, see: http://www.glfw.org/docs/latest/group__keys.html -# For a list of modifier names, see: http://www.glfw.org/docs/latest/group__mods.html -# You can use the special action no_op to unmap a keyboard shortcut that is -# assigned in the default configuration. - # Clipboard map super+v paste_from_clipboard map ctrl+shift+s paste_from_selection @@ -218,35 +85,13 @@ map ctrl+shift+up increase_font_size map ctrl+shift+down decrease_font_size map ctrl+shift+backspace restore_font_size -# Symbol mapping (special font for specified unicode code points). Map the -# specified unicode codepoints to a particular font. Useful if you need special -# rendering for some symbols, such as for Powerline. Avoids the need for -# patched fonts. Each unicode code point is specified in the form U+. You can specify multiple code points, separated by commas -# and ranges separated by hyphens. symbol_map itself can be specified multiple times. -# Syntax is: -# -# symbol_map codepoints Font Family Name -# -# For example: -# -#symbol_map U+E0A0-U+E0A2,U+E0B0-U+E0B3 PowerlineSymbols -#hide_window_decorations yes macos_option_as_alt no remember_window_size yes confirm_os_window_close 0 - -# Change the color of the kitty window's titlebar on macOS. A value of "system" -# means to use the default system color, a value of "background" means to use -# the default background color and finally you can use an arbitrary color, such -# as #12af59 or "red". -# macos_titlebar_color background - allow_remote_control yes include ./theme.conf - # BEGIN_KITTY_THEME # Catppuccin-Mocha include current-theme.conf -# END_KITTY_THEME \ No newline at end of file +# END_KITTY_THEME