From a9c40bc86d33137bf8a98d8d815c3cdcdeaebc46 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sat, 26 Apr 2025 14:17:13 +0200 Subject: [PATCH] color generation --- .config/matugen/config.toml | 31 +++ .config/matugen/templates/colors.json | 51 +++++ .config/matugen/templates/fuzzel/fuzzel.ini | 21 ++ .config/matugen/templates/gtk/gtk-colors.css | 22 +++ .../matugen/templates/hyprland/colors.conf | 32 ++++ .../matugen/templates/hyprland/hyprlock.conf | 83 ++++++++ .../modules/common/ConfigOptions.qml | 3 + .../modules/common/widgets/RoundCorner.qml | 4 + .../modules/overview/SearchWidget.qml | 59 +++++- .../modules/sidebarRight/SidebarRight.qml | 10 +- .../modules/sidebarRight/todo/TodoWidget.qml | 3 +- .config/quickshell/scripts/applycolor.sh | 58 ++++++ .../scripts/generate_colors_material.py | 181 ++++++++++++++++++ .config/quickshell/scripts/kvantum/adwsvg.py | 79 ++++++++ .../quickshell/scripts/kvantum/adwsvgDark.py | 87 +++++++++ .../scripts/kvantum/changeAdwColors.py | 71 +++++++ .../quickshell/scripts/kvantum/materialQT.sh | 42 ++++ .config/quickshell/scripts/switchwall.sh | 137 +++++++++++++ .../scripts/terminal/scheme-base.json | 38 ++++ .../quickshell/scripts/terminal/sequences.txt | 1 + .config/quickshell/services/MaterialTheme.qml | 53 +++++ .config/quickshell/shell.qml | 6 + 22 files changed, 1065 insertions(+), 7 deletions(-) create mode 100644 .config/matugen/config.toml create mode 100644 .config/matugen/templates/colors.json create mode 100644 .config/matugen/templates/fuzzel/fuzzel.ini create mode 100644 .config/matugen/templates/gtk/gtk-colors.css create mode 100644 .config/matugen/templates/hyprland/colors.conf create mode 100644 .config/matugen/templates/hyprland/hyprlock.conf create mode 100755 .config/quickshell/scripts/applycolor.sh create mode 100755 .config/quickshell/scripts/generate_colors_material.py create mode 100644 .config/quickshell/scripts/kvantum/adwsvg.py create mode 100644 .config/quickshell/scripts/kvantum/adwsvgDark.py create mode 100644 .config/quickshell/scripts/kvantum/changeAdwColors.py create mode 100755 .config/quickshell/scripts/kvantum/materialQT.sh create mode 100755 .config/quickshell/scripts/switchwall.sh create mode 100644 .config/quickshell/scripts/terminal/scheme-base.json create mode 100644 .config/quickshell/scripts/terminal/sequences.txt create mode 100644 .config/quickshell/services/MaterialTheme.qml diff --git a/.config/matugen/config.toml b/.config/matugen/config.toml new file mode 100644 index 00000000..f56c1a9a --- /dev/null +++ b/.config/matugen/config.toml @@ -0,0 +1,31 @@ +[config] +version_check = false + +[config.wallpaper] +command = "swww" +arguments = ["img", "--transition-step", "100", "--transition-fps", "120", "--transition-type", "grow", "--transition-angle", "30", "--transition-duration", "1"] + +[templates.m3colors] +input_path = '~/.config/matugen/templates/colors.json' +output_path = '~/.local/state/quickshell/user/generated/colors.json' + +[templates.hyprland] +input_path = '~/.config/matugen/templates/hyprland/colors.conf' +output_path = '~/.config/hypr/hyprland/hyprland/colors.conf' + +[templates.hyprlock] +input_path = '~/.config/matugen/templates/hyprland/hyprlock.conf' +output_path = '~/.config/hypr/hyprlock.conf' + +[templates.fuzzel] +input_path = '~/.config/matugen/templates/fuzzel/fuzzel.ini' +output_path = '~/.config/fuzzel/fuzzel.ini' + +[templates.gtk3] +input_path = '~/.config/matugen/templates/gtk/gtk-colors.css' +output_path = '~/.config/gtk-3.0/gtk.css' + +[templates.gtk4] +input_path = '~/.config/matugen/templates/gtk/gtk-colors.css' +output_path = '~/.config/gtk-4.0/gtk.css' + diff --git a/.config/matugen/templates/colors.json b/.config/matugen/templates/colors.json new file mode 100644 index 00000000..25f80e83 --- /dev/null +++ b/.config/matugen/templates/colors.json @@ -0,0 +1,51 @@ +{ + "background": "{{colors.background.default.hex}}", + "error": "{{colors.error.default.hex}}", + "error_container": "{{colors.error_container.default.hex}}", + "inverse_on_surface": "{{colors.inverse_on_surface.default.hex}}", + "inverse_primary": "{{colors.inverse_primary.default.hex}}", + "inverse_surface": "{{colors.inverse_surface.default.hex}}", + "on_background": "{{colors.on_background.default.hex}}", + "on_error": "{{colors.on_error.default.hex}}", + "on_error_container": "{{colors.on_error_container.default.hex}}", + "on_primary": "{{colors.on_primary.default.hex}}", + "on_primary_container": "{{colors.on_primary_container.default.hex}}", + "on_primary_fixed": "{{colors.on_primary_fixed.default.hex}}", + "on_primary_fixed_variant": "{{colors.on_primary_fixed_variant.default.hex}}", + "on_secondary": "{{colors.on_secondary.default.hex}}", + "on_secondary_container": "{{colors.on_secondary_container.default.hex}}", + "on_secondary_fixed": "{{colors.on_secondary_fixed.default.hex}}", + "on_secondary_fixed_variant": "{{colors.on_secondary_fixed_variant.default.hex}}", + "on_surface": "{{colors.on_surface.default.hex}}", + "on_surface_variant": "{{colors.on_surface_variant.default.hex}}", + "on_tertiary": "{{colors.on_tertiary.default.hex}}", + "on_tertiary_container": "{{colors.on_tertiary_container.default.hex}}", + "on_tertiary_fixed": "{{colors.on_tertiary_fixed.default.hex}}", + "on_tertiary_fixed_variant": "{{colors.on_tertiary_fixed_variant.default.hex}}", + "outline": "{{colors.outline.default.hex}}", + "outline_variant": "{{colors.outline_variant.default.hex}}", + "primary": "{{colors.primary.default.hex}}", + "primary_container": "{{colors.primary_container.default.hex}}", + "primary_fixed": "{{colors.primary_fixed.default.hex}}", + "primary_fixed_dim": "{{colors.primary_fixed_dim.default.hex}}", + "scrim": "{{colors.scrim.default.hex}}", + "secondary": "{{colors.secondary.default.hex}}", + "secondary_container": "{{colors.secondary_container.default.hex}}", + "secondary_fixed": "{{colors.secondary_fixed.default.hex}}", + "secondary_fixed_dim": "{{colors.secondary_fixed_dim.default.hex}}", + "shadow": "{{colors.shadow.default.hex}}", + "surface": "{{colors.surface.default.hex}}", + "surface_bright": "{{colors.surface_bright.default.hex}}", + "surface_container": "{{colors.surface_container.default.hex}}", + "surface_container_high": "{{colors.surface_container_high.default.hex}}", + "surface_container_highest": "{{colors.surface_container_highest.default.hex}}", + "surface_container_low": "{{colors.surface_container_low.default.hex}}", + "surface_container_lowest": "{{colors.surface_container_lowest.default.hex}}", + "surface_dim": "{{colors.surface_dim.default.hex}}", + "surface_tint": "{{colors.surface_tint.default.hex}}", + "surface_variant": "{{colors.surface_variant.default.hex}}", + "tertiary": "{{colors.tertiary.default.hex}}", + "tertiary_container": "{{colors.tertiary_container.default.hex}}", + "tertiary_fixed": "{{colors.tertiary_fixed.default.hex}}", + "tertiary_fixed_dim": "{{colors.tertiary_fixed_dim.default.hex}}" +} diff --git a/.config/matugen/templates/fuzzel/fuzzel.ini b/.config/matugen/templates/fuzzel/fuzzel.ini new file mode 100644 index 00000000..138799de --- /dev/null +++ b/.config/matugen/templates/fuzzel/fuzzel.ini @@ -0,0 +1,21 @@ +font=Gabarito +terminal=foot -e +prompt=">> " +layer=overlay + +[colors] +background={{colors.background.default.hex_stripped}}ff +text={{colors.on_background.default.hex_stripped}}ff +selection={{colors.surface_variant.default.hex_stripped}}ff +selection-text={{colors.on_surface_variant.default.hex_stripped}}ff +border={{colors.surface_variant.default.hex_stripped}}dd +match={{colors.primary.default.hex_stripped}}ff +selection-match={{colors.primary.default.hex_stripped}}ff + + +[border] +radius=17 +width=1 + +[dmenu] +exit-immediately-if-empty=yes diff --git a/.config/matugen/templates/gtk/gtk-colors.css b/.config/matugen/templates/gtk/gtk-colors.css new file mode 100644 index 00000000..c0054f86 --- /dev/null +++ b/.config/matugen/templates/gtk/gtk-colors.css @@ -0,0 +1,22 @@ +/* +* GTK Colors +* Generated with Matugen +*/ + +@define-color accent_color {{colors.primary.default.hex}}; +@define-color accent_fg_color {{colors.on_primary.default.hex}}; +@define-color accent_bg_color {{colors.primary.default.hex}}; +@define-color window_bg_color {{colors.background.default.hex}}; +@define-color window_fg_color {{colors.on_background.default.hex}}; +@define-color headerbar_bg_color {{colors.surface_dim.default.hex}}; +@define-color headerbar_fg_color {{colors.on_surface.default.hex}}; +@define-color popover_bg_color {{colors.surface_dim.default.hex}}; +@define-color popover_fg_color {{colors.on_surface.default.hex}}; +@define-color view_bg_color {{colors.surface.default.hex}}; +@define-color view_fg_color {{colors.on_surface.default.hex}}; +@define-color card_bg_color {{colors.surface.default.hex}}; +@define-color card_fg_color {{colors.on_surface.default.hex}}; +@define-color sidebar_bg_color @window_bg_color; +@define-color sidebar_fg_color @window_fg_color; +@define-color sidebar_border_color @window_bg_color; +@define-color sidebar_backdrop_color @window_bg_color; diff --git a/.config/matugen/templates/hyprland/colors.conf b/.config/matugen/templates/hyprland/colors.conf new file mode 100644 index 00000000..db99e72f --- /dev/null +++ b/.config/matugen/templates/hyprland/colors.conf @@ -0,0 +1,32 @@ +general { + col.active_border = rgba({{colors.on_surface.default.hex_stripped}}39) + col.inactive_border = rgba({{colors.outline.default.hex_stripped}}30) +} + +misc { + background_color = rgba({{colors.surface.default.hex_stripped}}FF) +} + +plugin { + hyprbars { + # Honestly idk if it works like css, but well, why not + bar_text_font = Rubik, Geist, AR One Sans, Reddit Sans, Inter, Roboto, Ubuntu, Noto Sans, sans-serif + bar_height = 30 + bar_padding = 10 + bar_button_padding = 5 + bar_precedence_over_border = true + bar_part_of_window = true + + bar_color = rgba({{colors.background.default.hex_stripped}}FF) + col.text = rgba({{colors.on_background.default.hex_stripped}}FF) + + + # example buttons (R -> L) + # hyprbars-button = color, size, on-click + hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖭, hyprctl dispatch killactive + hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖯, hyprctl dispatch fullscreen 1 + hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖰, hyprctl dispatch movetoworkspacesilent special + } +} + +windowrulev2 = bordercolor rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77),pinned:1 diff --git a/.config/matugen/templates/hyprland/hyprlock.conf b/.config/matugen/templates/hyprland/hyprlock.conf new file mode 100644 index 00000000..9ee4114f --- /dev/null +++ b/.config/matugen/templates/hyprland/hyprlock.conf @@ -0,0 +1,83 @@ +$text_color = rgba({{colors.primary_fixed.default.hex_stripped}}FF) +$entry_background_color = rgba({{colors.on_primary_fixed.default.hex_stripped}}11) +$entry_border_color = rgba({{colors.outline.default.hex_stripped}}55) +$entry_color = rgba({{colors.primary_fixed.default.hex_stripped}}FF) +$font_family = Rubik Light +$font_family_clock = Rubik Light +$font_material_symbols = Material Symbols Rounded + +background { + color = rgba(181818FF) + # path = {{image}} + + # path = screenshot + # blur_size = 15 + # blur_passes = 4 +} +input-field { + monitor = + size = 250, 50 + outline_thickness = 2 + dots_size = 0.1 + dots_spacing = 0.3 + outer_color = $entry_border_color + inner_color = $entry_background_color + font_color = $entry_color + fade_on_empty = true + + position = 0, 20 + halign = center + valign = center +} + +label { # Clock + monitor = + text = $TIME + color = $text_color + font_size = 65 + font_family = $font_family_clock + + position = 0, 300 + halign = center + valign = center +} +label { # Date + monitor = + text = cmd[update:5000] date +"%A, %B %d" + color = $text_color + font_size = 17 + font_family = $font_family + + position = 0, 240 + halign = center + valign = center +} + +label { # User + monitor = + text =  $USER + color = $text_color + shadow_passes = 1 + shadow_boost = 0.35 + outline_thickness = 2 + dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8 + dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0 + dots_center = true + font_size = 20 + font_family = $font_family + position = 0, 50 + halign = center + valign = bottom +} + +label { # Status + monitor = + text = cmd[update:5000] ${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprlock/status.sh + color = $text_color + font_size = 14 + font_family = $font_family + + position = 30, -30 + halign = left + valign = top +} \ No newline at end of file diff --git a/.config/quickshell/modules/common/ConfigOptions.qml b/.config/quickshell/modules/common/ConfigOptions.qml index 858d211f..2dff5bf6 100644 --- a/.config/quickshell/modules/common/ConfigOptions.qml +++ b/.config/quickshell/modules/common/ConfigOptions.qml @@ -45,6 +45,9 @@ Singleton { property int nonAppResultDelay: 30 // This prevents lagging when typing property string engineBaseUrl: "https://www.google.com/search?q=" property list excludedSites: [ "quora.com" ] + property QtObject prefix: QtObject { + property string action: "/" + } } property QtObject hacks: QtObject { diff --git a/.config/quickshell/modules/common/widgets/RoundCorner.qml b/.config/quickshell/modules/common/widgets/RoundCorner.qml index 6a9020bc..59e9a0c0 100644 --- a/.config/quickshell/modules/common/widgets/RoundCorner.qml +++ b/.config/quickshell/modules/common/widgets/RoundCorner.qml @@ -6,6 +6,10 @@ Item { property int size: 25 property color color: "#000000" + onColorChanged: { + canvas.requestPaint(); + } + property QtObject cornerEnum: QtObject { property int topLeft: 0 property int topRight: 1 diff --git a/.config/quickshell/modules/overview/SearchWidget.qml b/.config/quickshell/modules/overview/SearchWidget.qml index b566f1b3..73a2d96d 100644 --- a/.config/quickshell/modules/overview/SearchWidget.qml +++ b/.config/quickshell/modules/overview/SearchWidget.qml @@ -1,7 +1,9 @@ import "root:/" +import "root:/services/" import "root:/modules/common" import "root:/modules/common/widgets" import Qt5Compat.GraphicalEffects +import Qt.labs.platform import QtQuick import QtQuick.Controls import QtQuick.Layouts @@ -11,6 +13,7 @@ import Quickshell.Io Item { // Wrapper id: root required property var panelWindow + readonly property string xdgConfigHome: StandardPaths.standardLocations(StandardPaths.ConfigLocation)[0] property string searchingText: "" property bool showResults: searchingText != "" property real searchBarHeight: searchBar.height + Appearance.sizes.elevationMargin * 2 @@ -18,6 +21,41 @@ Item { // Wrapper implicitHeight: searchWidgetContent.implicitHeight + Appearance.sizes.elevationMargin * 2 property string mathResult: "" + property var searchActions: [ + { + action: "img", + execute: () => { + executor.executeCommand(`${xdgConfigHome}/quickshell/scripts/switchwall.sh`.replace(/file:\/\//, "")) + } + }, + { + action: "dark", + execute: () => { + executor.executeCommand(`${xdgConfigHome}/quickshell/scripts/switchwall.sh --mode dark --noswitch`.replace(/file:\/\//, "")) + } + }, + { + action: "light", + execute: () => { + executor.executeCommand(`${xdgConfigHome}/quickshell/scripts/switchwall.sh --mode light --noswitch`.replace(/file:\/\//, "")) + } + }, + { + action: "accentcolor", + execute: (args) => { + console.log(args) + executor.executeCommand( + `${xdgConfigHome}/quickshell/scripts/switchwall.sh --noswitch --color ${args != '' ? ("'"+args+"'") : ""}` + .replace(/file:\/\//, "")) + } + }, + { + action: "todo", + execute: (args) => { + Todo.addTask(args) + } + }, + ] function focusFirstItemIfNeeded() { if (searchInput.focus) appResults.currentIndex = 0; // Focus the first item @@ -178,7 +216,8 @@ Item { // Wrapper Layout.rightMargin: 15 padding: 15 color: activeFocus ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3onSurfaceVariant - selectedTextColor: Appearance.m3colors.m3onSurface + selectedTextColor: Appearance.m3colors.m3onPrimary + selectionColor: Appearance.m3colors.m3primary placeholderText: qsTr("Search, calculate or run") placeholderTextColor: Appearance.m3colors.m3outline implicitWidth: root.searchingText == "" ? Appearance.sizes.searchWidthCollapsed : Appearance.sizes.searchWidth @@ -275,6 +314,22 @@ Item { // Wrapper ); // Add non-app results + // Launcher actions + for (let action of root.searchActions) { + const actionString = `${ConfigOptions.search.prefix.action}${action.action}` + if (actionString.startsWith(root.searchingText) || root.searchingText.startsWith(actionString)) { + result.push({ + name: root.searchingText.startsWith(actionString) ? root.searchingText : actionString, + clickActionName: "Run", + type: "Action", + materialSymbol: 'settings_suggest', + execute: () => { + action.execute(root.searchingText.split(" ").slice(1).join(" ")) + }, + }); + } + } + // Qalc math result result.push({ name: root.mathResult, clickActionName: "Copy", @@ -285,6 +340,7 @@ Item { // Wrapper copyText.copyTextToClipboard(root.mathResult); } }); + // Run command result.push({ name: searchingText, clickActionName: "Run", @@ -295,6 +351,7 @@ Item { // Wrapper executor.executeCommand(searchingText.startsWith('sudo') ? `${ConfigOptions.apps.terminal} fish -C '${root.searchingText}'` : root.searchingText); } }); + // Web search result.push({ name: root.searchingText, clickActionName: "Search", diff --git a/.config/quickshell/modules/sidebarRight/SidebarRight.qml b/.config/quickshell/modules/sidebarRight/SidebarRight.qml index 4491d3d0..f5b6472e 100644 --- a/.config/quickshell/modules/sidebarRight/SidebarRight.qml +++ b/.config/quickshell/modules/sidebarRight/SidebarRight.qml @@ -99,11 +99,11 @@ Scope { Layout.topMargin: 5 Layout.bottomMargin: 0 - CustomIcon { - width: 25 - height: 25 - source: SystemInfo.distroIcon - } + // CustomIcon { + // width: 25 + // height: 25 + // source: SystemInfo.distroIcon + // } StyledText { font.pixelSize: Appearance.font.pixelSize.normal diff --git a/.config/quickshell/modules/sidebarRight/todo/TodoWidget.qml b/.config/quickshell/modules/sidebarRight/todo/TodoWidget.qml index 7464e988..7db2e1c5 100644 --- a/.config/quickshell/modules/sidebarRight/todo/TodoWidget.qml +++ b/.config/quickshell/modules/sidebarRight/todo/TodoWidget.qml @@ -273,7 +273,8 @@ Item { Layout.rightMargin: 16 padding: 10 color: activeFocus ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3onSurfaceVariant - selectedTextColor: Appearance.m3colors.m3onSurface + selectedTextColor: Appearance.m3colors.m3onPrimary + selectionColor: Appearance.m3colors.m3primary placeholderText: qsTr("Task description") placeholderTextColor: Appearance.m3colors.m3outline focus: root.showAddDialog diff --git a/.config/quickshell/scripts/applycolor.sh b/.config/quickshell/scripts/applycolor.sh new file mode 100755 index 00000000..3ba7862e --- /dev/null +++ b/.config/quickshell/scripts/applycolor.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" +XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" +XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" +CONFIG_DIR="$XDG_CONFIG_HOME/quickshell" +CACHE_DIR="$XDG_CACHE_HOME/quickshell" +STATE_DIR="$XDG_STATE_HOME/quickshell" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +term_alpha=100 #Set this to < 100 make all your terminals transparent +# sleep 0 # idk i wanted some delay or colors dont get applied properly +if [ ! -d "$CACHE_DIR"/user/generated ]; then + mkdir -p "$CACHE_DIR"/user/generated +fi +cd "$CONFIG_DIR" || exit + +colornames='' +colorstrings='' +colorlist=() +colorvalues=() + +colornames=$(cat $STATE_DIR/user/generated/material_colors.scss | cut -d: -f1) +colorstrings=$(cat $STATE_DIR/user/generated/material_colors.scss | cut -d: -f2 | cut -d ' ' -f2 | cut -d ";" -f1) +IFS=$'\n' +colorlist=($colornames) # Array of color names +colorvalues=($colorstrings) # Array of color values + +apply_term() { + # Check if terminal escape sequence template exists + if [ ! -f "$SCRIPT_DIR"/terminal/sequences.txt ]; then + echo "Template file not found for Terminal. Skipping that." + return + fi + # Copy template + mkdir -p "$CACHE_DIR"/user/generated/terminal + cp "$SCRIPT_DIR"/terminal/sequences.txt "$CACHE_DIR"/user/generated/terminal/sequences.txt + # Apply colors + for i in "${!colorlist[@]}"; do + sed -i "s/${colorlist[$i]} #/${colorvalues[$i]#\#}/g" "$CACHE_DIR"/user/generated/terminal/sequences.txt + done + + sed -i "s/\$alpha/$term_alpha/g" "$CACHE_DIR/user/generated/terminal/sequences.txt" + + for file in /dev/pts/*; do + if [[ $file =~ ^/dev/pts/[0-9]+$ ]]; then + cat "$CACHE_DIR"/user/generated/terminal/sequences.txt >"$file" + fi + done +} + +apply_qt() { + sh "$CONFIG_DIR/scripts/kvantum/materialQT.sh" # generate kvantum theme + python "$CONFIG_DIR/scripts/kvantum/changeAdwColors.py" # apply config colors +} + +apply_qt & +apply_term & diff --git a/.config/quickshell/scripts/generate_colors_material.py b/.config/quickshell/scripts/generate_colors_material.py new file mode 100755 index 00000000..db6b1664 --- /dev/null +++ b/.config/quickshell/scripts/generate_colors_material.py @@ -0,0 +1,181 @@ +#!/usr/bin/env -S\_/bin/sh\_-c\_"source\_\$(eval\_echo\_\$ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate&&exec\_python\_-E\_"\$0"\_"\$@"" +import argparse +import math +import json +from PIL import Image +from materialyoucolor.quantize import QuantizeCelebi +from materialyoucolor.score.score import Score +from materialyoucolor.hct import Hct +from materialyoucolor.dynamiccolor.material_dynamic_colors import MaterialDynamicColors +from materialyoucolor.utils.color_utils import (rgba_from_argb, argb_from_rgb, argb_from_rgba) +from materialyoucolor.utils.math_utils import (sanitize_degrees_double, difference_degrees, rotation_direction) + +parser = argparse.ArgumentParser(description='Color generation script') +parser.add_argument('--path', type=str, default=None, help='generate colorscheme from image') +parser.add_argument('--size', type=int , default=128 , help='bitmap image size') +parser.add_argument('--color', type=str, default=None, help='generate colorscheme from color') +parser.add_argument('--mode', type=str, choices=['dark', 'light'], default='dark', help='dark or light mode') +parser.add_argument('--scheme', type=str, default='vibrant', help='material scheme to use') +parser.add_argument('--smart', action='store_true', default=False, help='decide scheme type based on image color') +parser.add_argument('--transparency', type=str, choices=['opaque', 'transparent'], default='opaque', help='enable transparency') +parser.add_argument('--termscheme', type=str, default=None, help='JSON file containg the terminal scheme for generating term colors') +parser.add_argument('--harmony', type=float , default=0.8, help='(0-1) Color hue shift towards accent') +parser.add_argument('--harmonize_threshold', type=float , default=100, help='(0-180) Max threshold angle to limit color hue shift') +parser.add_argument('--term_fg_boost', type=float , default=0.35, help='Make terminal foreground more different from the background') +parser.add_argument('--blend_bg_fg', action='store_true', default=False, help='Shift terminal background or foreground towards accent') +parser.add_argument('--cache', type=str, default=None, help='file path to store the generated color') +parser.add_argument('--debug', action='store_true', default=False, help='debug mode') +args = parser.parse_args() + +rgba_to_hex = lambda rgba: "#{:02X}{:02X}{:02X}".format(rgba[0], rgba[1], rgba[2]) +argb_to_hex = lambda argb: "#{:02X}{:02X}{:02X}".format(*map(round, rgba_from_argb(argb))) +hex_to_argb = lambda hex_code: argb_from_rgb(int(hex_code[1:3], 16), int(hex_code[3:5], 16), int(hex_code[5:], 16)) +display_color = lambda rgba : "\x1B[38;2;{};{};{}m{}\x1B[0m".format(rgba[0], rgba[1], rgba[2], "\x1b[7m \x1b[7m") + +def calculate_optimal_size (width: int, height: int, bitmap_size: int) -> (int, int): + image_area = width * height; + bitmap_area = bitmap_size ** 2 + scale = math.sqrt(bitmap_area/image_area) if image_area > bitmap_area else 1 + new_width = round(width * scale) + new_height = round(height * scale) + if new_width == 0: + new_width = 1 + if new_height == 0: + new_height = 1 + return new_width, new_height + +def harmonize (design_color: int, source_color: int, threshold: float = 35, harmony: float = 0.5) -> int: + from_hct = Hct.from_int(design_color) + to_hct = Hct.from_int(source_color) + difference_degrees_ = difference_degrees(from_hct.hue, to_hct.hue) + rotation_degrees = min(difference_degrees_ * harmony, threshold) + output_hue = sanitize_degrees_double( + from_hct.hue + rotation_degrees * rotation_direction(from_hct.hue, to_hct.hue) + ) + return Hct.from_hct(output_hue, from_hct.chroma, from_hct.tone).to_int() + +def boost_chroma_tone (argb: int, chroma: float = 1, tone: float = 1) -> int: + hct = Hct.from_int(argb) + return Hct.from_hct(hct.hue, hct.chroma * chroma, hct.tone * tone).to_int() + +darkmode = (args.mode == 'dark') +transparent = (args.transparency == 'transparent') + +if args.path is not None: + image = Image.open(args.path) + + if image.format == "GIF": + image.seek(1) + + if image.mode in ["L", "P"]: + image = image.convert('RGB') + wsize, hsize = image.size + wsize_new, hsize_new = calculate_optimal_size(wsize, hsize, args.size) + if wsize_new < wsize or hsize_new < hsize: + image = image.resize((wsize_new, hsize_new), Image.Resampling.BICUBIC) + colors = QuantizeCelebi(list(image.getdata()), 128) + argb = Score.score(colors)[0] + + if args.cache is not None: + with open(args.cache, 'w') as file: + file.write(argb_to_hex(argb)) + hct = Hct.from_int(argb) + if(args.smart): + if(hct.chroma < 20): + args.scheme = 'neutral' +elif args.color is not None: + argb = hex_to_argb(args.color) + hct = Hct.from_int(argb) + +if args.scheme == 'scheme-fruit-salad': + from materialyoucolor.scheme.scheme_fruit_salad import SchemeFruitSalad as Scheme +elif args.scheme == 'scheme-expressive': + from materialyoucolor.scheme.scheme_expressive import SchemeExpressive as Scheme +elif args.scheme == 'scheme-monochrome': + from materialyoucolor.scheme.scheme_monochrome import SchemeMonochrome as Scheme +elif args.scheme == 'scheme-rainbow': + from materialyoucolor.scheme.scheme_rainbow import SchemeRainbow as Scheme +elif args.scheme == 'scheme-tonal-spot': + from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot as Scheme +elif args.scheme == 'scheme-neutral': + from materialyoucolor.scheme.scheme_neutral import SchemeNeutral as Scheme +elif args.scheme == 'scheme-fidelity': + from materialyoucolor.scheme.scheme_fidelity import SchemeFidelity as Scheme +elif args.scheme == 'scheme-content': + from materialyoucolor.scheme.scheme_content import SchemeContent as Scheme +elif args.scheme == 'scheme-vibrant': + from materialyoucolor.scheme.scheme_vibrant import SchemeVibrant as Scheme +else: + from materialyoucolor.scheme.scheme_tonal_spot import SchemeTonalSpot as Scheme +# Generate +scheme = Scheme(hct, darkmode, 0.0) + +material_colors = {} +term_colors = {} + +for color in vars(MaterialDynamicColors).keys(): + color_name = getattr(MaterialDynamicColors, color) + if hasattr(color_name, "get_hct"): + rgba = color_name.get_hct(scheme).to_rgba() + material_colors[color] = rgba_to_hex(rgba) + +# Extended material +if darkmode == True: + material_colors['success'] = '#B5CCBA' + material_colors['onSuccess'] = '#213528' + material_colors['successContainer'] = '#374B3E' + material_colors['onSuccessContainer'] = '#D1E9D6' +else: + material_colors['success'] = '#4F6354' + material_colors['onSuccess'] = '#FFFFFF' + material_colors['successContainer'] = '#D1E8D5' + material_colors['onSuccessContainer'] = '#0C1F13' + +# Terminal Colors +if args.termscheme is not None: + with open(args.termscheme, 'r') as f: + json_termscheme = f.read() + term_source_colors = json.loads(json_termscheme)['dark' if darkmode else 'light'] + + primary_color_argb = hex_to_argb(material_colors['primary_paletteKeyColor']) + for color, val in term_source_colors.items(): + if(args.scheme == 'monochrome') : + term_colors[color] = val + continue + if args.blend_bg_fg and color == "term0": + harmonized = boost_chroma_tone(hex_to_argb(material_colors['surfaceContainerLow']), 1.2, 0.95) + elif args.blend_bg_fg and color == "term15": + harmonized = boost_chroma_tone(hex_to_argb(material_colors['onSurface']), 3, 1) + else: + harmonized = harmonize(hex_to_argb(val), primary_color_argb, args.harmonize_threshold, args.harmony) + harmonized = boost_chroma_tone(harmonized, 1, 1 + (args.term_fg_boost * (1 if darkmode else -1))) + term_colors[color] = argb_to_hex(harmonized) + +if args.debug == False: + print(f"$darkmode: {darkmode};") + print(f"$transparent: {transparent};") + for color, code in material_colors.items(): + print(f"${color}: {code};") + for color, code in term_colors.items(): + print(f"${color}: {code};") +else: + if args.path is not None: + print('\n--------------Image properties-----------------') + print(f"Image size: {wsize} x {hsize}") + print(f"Resized image: {wsize_new} x {hsize_new}") + print('\n---------------Selected color------------------') + print(f"Dark mode: {darkmode}") + print(f"Scheme: {args.scheme}") + print(f"Accent color: {display_color(rgba_from_argb(argb))} {argb_to_hex(argb)}") + print(f"HCT: {hct.hue:.2f} {hct.chroma:.2f} {hct.tone:.2f}") + print('\n---------------Material colors-----------------') + for color, code in material_colors.items(): + rgba = rgba_from_argb(hex_to_argb(code)) + print(f"{color.ljust(32)} : {display_color(rgba)} {code}") + print('\n----------Harmonize terminal colors------------') + for color, code in term_colors.items(): + rgba = rgba_from_argb(hex_to_argb(code)) + code_source = term_source_colors[color] + rgba_source = rgba_from_argb(hex_to_argb(code_source)) + print(f"{color.ljust(6)} : {display_color(rgba_source)} {code_source} --> {display_color(rgba)} {code}") + print('-----------------------------------------------') diff --git a/.config/quickshell/scripts/kvantum/adwsvg.py b/.config/quickshell/scripts/kvantum/adwsvg.py new file mode 100644 index 00000000..10ce1d15 --- /dev/null +++ b/.config/quickshell/scripts/kvantum/adwsvg.py @@ -0,0 +1,79 @@ +import re +import os + +def read_scss(file_path): + """Reads an SCSS file and returns a dictionary of color variables.""" + colors = {} + with open(file_path, 'r') as file: + for line in file: + match = re.match(r'\$(\w+):\s*(#[0-9A-Fa-f]{6});', line.strip()) + if match: + variable_name, color = match.groups() + colors[variable_name] = color + return colors + +def update_svg_colors(svg_path, old_to_new_colors, output_path): + """ + Updates the colors in an SVG file based on the provided color map. + + :param svg_path: Path to the SVG file. + :param old_to_new_colors: Dictionary mapping old colors to new colors. + :param output_path: Path to save the updated SVG file. + """ + # Read the SVG content + with open(svg_path, 'r') as file: + svg_content = file.read() + + # Replace old colors with new colors + for old_color, new_color in old_to_new_colors.items(): + svg_content = re.sub(old_color, new_color, svg_content, flags=re.IGNORECASE) + + # Write the updated SVG content to the output file + with open(output_path, 'w') as file: + file.write(svg_content) + + print(f"SVG colors have been updated and saved to {output_path}!") + +def main(): + xdg_config_home = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")) + xdg_state_home = os.environ.get("XDG_STATE_HOME", os.path.expanduser("~/.local/state")) + + scss_file = os.path.join(xdg_state_home, "quickshell", "user", "generated", "material_colors.scss") + svg_path = os.path.join(xdg_config_home, "Kvantum", "Colloid", "Colloid.svg") + output_path = os.path.join(xdg_config_home, "Kvantum", "MaterialAdw", "MaterialAdw.svg") + + # Read colors from the SCSS file + color_data = read_scss(scss_file) + + # Specify the old colors and map them to new colors from the SCSS file + old_to_new_colors = { + #'#cccccc': color_data['surfaceDim'], # Map old SVG color to new SCSS color + #'#666666': color_data['surfaceDim'], + '#3c84f7': color_data['primary'], + #'#5a5a5a': color_data['neutral_paletteKeyColor'], + '#000000': color_data['shadow'], + '#f04a50': color_data['error'], + '#4285f4': color_data['primaryFixedDim'], + '#f2f2f2': color_data['background'], + #'#dfdfdf': color_data['surfaceContainerLow'], + '#ffffff': color_data['background'], + '#1e1e1e': color_data['onPrimaryFixed'], + #'#b6b6b6': color_data['surfaceContainer'], + '#333': color_data['inverseSurface'], + '#212121': color_data['onSecondaryFixed'], + '#5b9bf8': color_data['secondaryContainer'], + '#26272a': color_data['term7'], + #'#b3b3b3': color_data['surfaceBright'], + #'#b74aff': color_data['tertiary'], + #'#989898': color_data['surfaceContainerHighest'], + #'#c1c1c1': color_data['surfaceContainerHigh'], + '#444444': color_data['onBackground'], + '#333333': color_data['onPrimaryFixed'], + } + + # Update the SVG colors + update_svg_colors(svg_path, old_to_new_colors, output_path) + +if __name__ == "__main__": + main() + diff --git a/.config/quickshell/scripts/kvantum/adwsvgDark.py b/.config/quickshell/scripts/kvantum/adwsvgDark.py new file mode 100644 index 00000000..9fb09774 --- /dev/null +++ b/.config/quickshell/scripts/kvantum/adwsvgDark.py @@ -0,0 +1,87 @@ +import re +import os + +def read_scss(file_path): + """Reads an SCSS file and returns a dictionary of color variables.""" + colors = {} + with open(file_path, 'r') as file: + for line in file: + match = re.match(r'\$(\w+):\s*(#[0-9A-Fa-f]{6});', line.strip()) + if match: + variable_name, color = match.groups() + colors[variable_name] = color + return colors + +def update_svg_colors(svg_path, old_to_new_colors, output_path): + """ + Updates the colors in an SVG file based on the provided color map. + + :param svg_path: Path to the SVG file. + :param old_to_new_colors: Dictionary mapping old colors to new colors. + :param output_path: Path to save the updated SVG file. + """ + # Read the SVG content + with open(svg_path, 'r') as file: + svg_content = file.read() + + # Replace old colors with new colors + for old_color, new_color in old_to_new_colors.items(): + svg_content = re.sub(old_color, new_color, svg_content, flags=re.IGNORECASE) + + # Write the updated SVG content to the output file + with open(output_path, 'w') as file: + file.write(svg_content) + + print(f"SVG colors have been updated and saved to {output_path}!") + +def main(): + xdg_config_home = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")) + xdg_state_home = os.environ.get("XDG_STATE_HOME", os.path.expanduser("~/.local/state")) + + scss_file = os.path.join(xdg_state_home, "quickshell", "user", "generated", "material_colors.scss") + svg_path = os.path.join(xdg_config_home, "Kvantum", "Colloid", "ColloidDark.svg") + output_path = os.path.join(xdg_config_home, "Kvantum", "MaterialAdw", "MaterialAdw.svg") + + # Read colors from the SCSS file + color_data = read_scss(scss_file) + + # Specify the old colors and map them to new colors from the SCSS file + old_to_new_colors = { + #'#525252': color_data['surfaceDim'], # Map old SVG color to new SCSS color + #'#666666': color_data['surfaceDim'], + '#31363b': color_data['background'], + #'#eff0f1': color_data['neutral_paletteKeyColor'], + '#000000': color_data['shadow'], + '#5b9bf8': color_data['primary'], + '#93cee9': color_data['onSecondaryContainer'], + '#3daee9': color_data['secondary'], + #'#fff': color_data['term10'], + #'#5a5a5a': color_data['surfaceVariant'], + #'#acb1bc': color_data['onPrimaryFixed'], + '#ffffff': color_data['term11'], + '#5a616e': color_data['surfaceVariant'], + '#f04a50': color_data['error'], + '#4285f4': color_data['secondary'], + '#242424': color_data['background'], + '#2c2c2c': color_data['background'], + #'#dfdfdf': color_data['onSurfaceVariant'], + #'#646464': color_data['surfaceContainerHighest'], + #'#989898': color_data['surfaceContainerHigh'], + #'#c1c1c1': color_data['primaryFixedDim'], + '#1e1e1e': color_data['background'], + '#3c3c3c': color_data['background'], + '#26272a': color_data['surfaceBright'], + '#000000': color_data['shadow'], + '#b74aff': color_data['tertiary'], + #'#b6b6b6': color_data['onSurfaceVariant'], + '#1a1a1a': color_data['background'], + '#333': color_data['term0'], + '#212121': color_data['background'], + } + + # Update the SVG colors + update_svg_colors(svg_path, old_to_new_colors, output_path) + +if __name__ == "__main__": + main() + diff --git a/.config/quickshell/scripts/kvantum/changeAdwColors.py b/.config/quickshell/scripts/kvantum/changeAdwColors.py new file mode 100644 index 00000000..26d067ad --- /dev/null +++ b/.config/quickshell/scripts/kvantum/changeAdwColors.py @@ -0,0 +1,71 @@ +import re +import os + +def get_colors_from_scss(scss_file): + colors = {} + with open(scss_file, 'r') as file: + for line in file: + match = re.match(r'\$(\w+):\s*(#[0-9A-Fa-f]{6});', line) + if match: + colors[match.group(1)] = match.group(2) + return colors + +def update_config_colors(config_file, colors, mappings): + with open(config_file, 'r') as file: + config_content = file.read() + + for key, variable in mappings.items(): + if variable in colors: + color = colors[variable] + pattern = rf'({key}=)#?\w+\b' + new_line = f'\\1{color}' + if re.search(pattern, config_content): + config_content = re.sub(pattern, new_line, config_content) + else: + config_content += f"\n{key}={color}" + + with open(config_file, 'w') as file: + file.write(config_content) + +if __name__ == "__main__": + xdg_config_home = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")) + xdg_state_home = os.environ.get("XDG_STATE_HOME", os.path.expanduser("~/.local/state")) + + config_file = os.path.join(xdg_config_home, "Kvantum", "MaterialAdw", "MaterialAdw.kvconfig") + scss_file = os.path.join(xdg_state_home, "quickshell", "user", "generated", "material_colors.scss") + + # Define your mappings here + mappings = { + 'window.color': 'background', + 'base.color': 'background', + 'alt.base.color': 'background', + 'button.color': 'surfaceContainer', + 'light.color': 'surfaceContainerLow', + 'mid.light.color': 'surfaceContainer', + 'dark.color': 'surfaceContainerHighest', + 'mid.color': 'surfaceContainerHigh', + 'highlight.color': 'primary', + 'inactive.highlight.color': 'primary', + 'text.color': 'onBackground', + 'window.text.color': 'onBackground', + 'button.text.color': 'onBackground', + 'disabled.text.color': 'onBackground', + 'tooltip.text.color': 'onBackground', + 'highlight.text.color': 'onSurface', + 'link.color': 'tertiary', + 'link.visited.color': 'tertiaryFixed', + 'progress.indicator.text.color': 'onBackground', + 'text.normal.color': 'onBackground', + 'text.focus.color': 'onBackground', + 'text.press.color': 'onsecondarycontainer', + 'text.toggle.color': 'onsecondarycontainer', + 'text.disabled.color': 'surfaceDim', + + + # Add more mappings as needed + } + + colors = get_colors_from_scss(scss_file) + update_config_colors(config_file, colors, mappings) + print("Config colors updated successfully!") + diff --git a/.config/quickshell/scripts/kvantum/materialQT.sh b/.config/quickshell/scripts/kvantum/materialQT.sh new file mode 100755 index 00000000..3d1f8a7b --- /dev/null +++ b/.config/quickshell/scripts/kvantum/materialQT.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" +XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" +XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" +CONFIG_DIR="$XDG_CONFIG_HOME/quickshell" +CACHE_DIR="$XDG_CACHE_HOME/quickshell" +STATE_DIR="$XDG_STATE_HOME/quickshell" + +get_light_dark() { + current_mode=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'") + if [[ "$current_mode" == "prefer-dark" ]]; then + echo "dark" + else + echo "light" + fi +} + +apply_qt() { + # Check if the theme exists + FOLDER_PATH="$XDG_CONFIG_HOME/Kvantum/Colloid/" + + if [ ! -d "$FOLDER_PATH" ]; then + # Send a notification + notify-send "Colloid-kde theme required" " The folder '$FOLDER_PATH' does not exist." + exit 1 # Exit the function if the folder does not exist + fi + + lightdark=$(get_light_dark) + if [ "$lightdark" = "light" ]; then + # apply ligght colors + cp "$XDG_CONFIG_HOME/Kvantum/Colloid/Colloid.kvconfig" "$XDG_CONFIG_HOME/Kvantum/MaterialAdw/MaterialAdw.kvconfig" + python "$CONFIG_DIR/scripts/kvantum/adwsvg.py" + + else + #apply dark colors + cp "$XDG_CONFIG_HOME/Kvantum/Colloid/ColloidDark.kvconfig" "$XDG_CONFIG_HOME/Kvantum/MaterialAdw/MaterialAdw.kvconfig" + python "$CONFIG_DIR/scripts/kvantum/adwsvgDark.py" + fi +} + +apply_qt diff --git a/.config/quickshell/scripts/switchwall.sh b/.config/quickshell/scripts/switchwall.sh new file mode 100755 index 00000000..32fb7c8a --- /dev/null +++ b/.config/quickshell/scripts/switchwall.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash + +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" +XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" +XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" +CONFIG_DIR="$XDG_CONFIG_HOME/quickshell" +CACHE_DIR="$XDG_CACHE_HOME/quickshell" +STATE_DIR="$XDG_STATE_HOME/quickshell" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +terminalscheme="$XDG_CONFIG_HOME/quickshell/scripts/terminal/scheme-base.json" + +pre_process() { + if [ ! -d "$CACHE_DIR"/user/generated ]; then + mkdir -p "$CACHE_DIR"/user/generated + fi +} + +post_process() { + local mode_flag="$1" + # Set GNOME color-scheme if mode_flag is dark or light + if [[ "$mode_flag" == "dark" ]]; then + gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' + gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark' + elif [[ "$mode_flag" == "light" ]]; then + gsettings set org.gnome.desktop.interface color-scheme 'prefer-light' + gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3' + fi +} + +switch() { + imgpath="$1" + mode_flag="$2" + type_flag="$3" + color_flag="$4" + color="$5" + read scale screenx screeny screensizey < <(hyprctl monitors -j | jq '.[] | select(.focused) | .scale, .x, .y, .height' | xargs) + cursorposx=$(hyprctl cursorpos -j | jq '.x' 2>/dev/null) || cursorposx=960 + cursorposx=$(bc <<< "scale=0; ($cursorposx - $screenx) * $scale / 1") + cursorposy=$(hyprctl cursorpos -j | jq '.y' 2>/dev/null) || cursorposy=540 + cursorposy=$(bc <<< "scale=0; ($cursorposy - $screeny) * $scale / 1") + cursorposy_inverted=$((screensizey - cursorposy)) + + if [[ "$color_flag" == "1" ]]; then + matugen_args=(color hex "$color") + generate_colors_material_args=(--color "$color") + else + if [[ -z "$imgpath" ]]; then + echo 'Aborted' + exit 0 + fi + matugen_args=(image "$imgpath") + generate_colors_material_args=(--path "$imgpath") + fi + + # Determine mode if not set + if [[ -z "$mode_flag" ]]; then + current_mode=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'") + if [[ "$current_mode" == "prefer-dark" ]]; then + mode_flag="dark" + else + mode_flag="light" + fi + fi + + # Dark/light mode, material scheme + [[ -n "$mode_flag" ]] && matugen_args+=(--mode "$mode_flag") && generate_colors_material_args+=(--mode "$mode_flag") + [[ -n "$type_flag" ]] && matugen_args+=(--type "$type_flag") && generate_colors_material_args+=(--scheme "$type_flag") + # Terminal scheme + generate_colors_material_args+=(--termscheme "$terminalscheme" --blend_bg_fg) + generate_colors_material_args+=(--cache "$STATE_DIR/user/color.txt") + + pre_process + + # Generate with matugen + matugen "${matugen_args[@]}" + # Use custom script for mixing (matugen can't D:) + source "$(eval echo $ILLOGICAL_IMPULSE_VIRTUAL_ENV)/bin/activate" + python "$SCRIPT_DIR/generate_colors_material.py" "${generate_colors_material_args[@]}" \ + > "$STATE_DIR"/user/generated/material_colors.scss + "$SCRIPT_DIR"/applycolor.sh + deactivate + + post_process "$mode_flag" +} + +main() { + imgpath="" + mode_flag="" + type_flag="" + color_flag="" + color="" + noswitch_flag="" + + while [[ $# -gt 0 ]]; do + case "$1" in + --mode) + mode_flag="$2" + shift 2 + ;; + --type) + type_flag="$2" + shift 2 + ;; + --color) + color_flag="1" + if [[ "$2" =~ ^#?[A-Fa-f0-9]{6}$ ]]; then + color="$2" + shift 2 + else + color=$(hyprpicker --no-fancy) + shift + fi + ;; + --noswitch) + noswitch_flag="1" + imgpath=$(swww query | awk -F 'image: ' '{print $2}') + shift + ;; + *) + if [[ -z "$imgpath" ]]; then + imgpath="$1" + fi + shift + ;; + esac + done + + # Only prompt for wallpaper if not using --color and not using --noswitch and no imgpath set + if [[ -z "$imgpath" && -z "$color_flag" && -z "$noswitch_flag" ]]; then + cd "$(xdg-user-dir PICTURES)/Wallpapers" 2>/dev/null || cd "$(xdg-user-dir PICTURES)" || return 1 + imgpath="$(yad --width 1200 --height 800 --file --add-preview --large-preview --title='Choose wallpaper')" + fi + + switch "$imgpath" "$mode_flag" "$type_flag" "$color_flag" "$color" +} + +main "$@" \ No newline at end of file diff --git a/.config/quickshell/scripts/terminal/scheme-base.json b/.config/quickshell/scripts/terminal/scheme-base.json new file mode 100644 index 00000000..e4b78e7e --- /dev/null +++ b/.config/quickshell/scripts/terminal/scheme-base.json @@ -0,0 +1,38 @@ +{ + "dark": { + "term0" : "#282828", + "term1" : "#CC241D", + "term2" : "#98971A", + "term3" : "#D79921", + "term4" : "#458588", + "term5" : "#B16286", + "term6" : "#689D6A", + "term7" : "#A89984", + "term8" : "#928374", + "term9" : "#FB4934", + "term10" : "#B8BB26", + "term11" : "#FABD2F", + "term12" : "#83A598", + "term13" : "#D3869B", + "term14" : "#8EC07C", + "term15" : "#EBDBB2" + }, + "light": { + "term0" : "#FDF9F3", + "term1" : "#FF6188", + "term2" : "#A9DC76", + "term3" : "#FC9867", + "term4" : "#FFD866", + "term5" : "#F47FD4", + "term6" : "#78DCE8", + "term7" : "#333034", + "term8" : "#121212", + "term9" : "#FF6188", + "term10" : "#A9DC76", + "term11" : "#FC9867", + "term12" : "#FFD866", + "term13" : "#F47FD4", + "term14" : "#78DCE8", + "term15" : "#333034" + } +} diff --git a/.config/quickshell/scripts/terminal/sequences.txt b/.config/quickshell/scripts/terminal/sequences.txt new file mode 100644 index 00000000..0308e0b3 --- /dev/null +++ b/.config/quickshell/scripts/terminal/sequences.txt @@ -0,0 +1 @@ +]4;0;#$term0 #\]1;0;#$term0 #\]4;1;#$term1 #\]4;2;#$term2 #\]4;3;#$term3 #\]4;4;#$term4 #\]4;5;#$term5 #\]4;6;#$term6 #\]4;7;#$term7 #\]4;8;#$term8 #\]4;9;#$term9 #\]4;10;#$term10 #\]4;11;#$term11 #\]4;12;#$term12 #\]4;13;#$term13 #\]4;14;#$term14 #\]4;15;#$term15 #\]10;#$term7 #\]11;[100]#$term0 #\]12;#$term7 #\]13;#$term7 #\]17;#$term7 #\]19;#$term0 #\]4;232;#$term7 #\]4;256;#$term7 #\]708;[100]#$term0 #\]11;#$term0 #\ diff --git a/.config/quickshell/services/MaterialTheme.qml b/.config/quickshell/services/MaterialTheme.qml new file mode 100644 index 00000000..94b117b4 --- /dev/null +++ b/.config/quickshell/services/MaterialTheme.qml @@ -0,0 +1,53 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import "root:/modules/common" +import QtQuick +import Quickshell +import Quickshell.Io +import Qt.labs.platform + +Singleton { + id: root + property string filePath: `${StandardPaths.standardLocations(StandardPaths.StateLocation)[0]}/user/generated/colors.json` + + function reapplyTheme() { + themeFileView.reload() + } + + function applyColors(fileContent) { + const json = JSON.parse(fileContent) + for (const key in json) { + if (json.hasOwnProperty(key)) { + // Convert snake_case to CamelCase + const camelCaseKey = key.replace(/_([a-z])/g, (g) => g[1].toUpperCase()) + const m3Key = `m3${camelCaseKey}` + Appearance.m3colors[m3Key] = json[key] + } + } + } + + Timer { + id: delayedFileRead + interval: ConfigOptions.hacks.arbitraryRaceConditionDelay + repeat: false + running: false + onTriggered: { + root.applyColors(themeFileView.text()) + } + } + + FileView { + id: themeFileView + path: root.filePath + watchChanges: true + onFileChanged: { + this.reload() + delayedFileRead.start() + } + onLoadedChanged: { + const fileContent = themeFileView.text() + root.applyColors(fileContent) + } + } +} diff --git a/.config/quickshell/shell.qml b/.config/quickshell/shell.qml index fdc1f8b1..e6ca2179 100644 --- a/.config/quickshell/shell.qml +++ b/.config/quickshell/shell.qml @@ -12,8 +12,14 @@ import QtQuick.Controls import QtQuick.Layouts import QtQuick.Window import Quickshell +import "./services/" ShellRoot { + Component.onCompleted: { + console.log("ShellRoot loaded") + MaterialTheme.reapplyTheme() + } + Bar {} NotificationPopup {} OnScreenDisplayBrightness {}