diff --git a/config/clipboard.rasi b/config/clipboard.rasi new file mode 100644 index 0000000..5f21ee9 --- /dev/null +++ b/config/clipboard.rasi @@ -0,0 +1,121 @@ +// Config // +configuration { + modi: "drun"; + show-icons: false; +} + +* { + main-bg : #11111be6; + main-fg : #cdd6f4ff; + main-br : #cba6f7ff; + main-ex : #f5e0dcff; + select-bg : #b4befeff; + select-fg : #11111bff; + separatorcolor : transparent; + border-color : transparent; + } + +// Main // +window { + width: 23em; + height: 30em; + transparency: "real"; + fullscreen: false; + enabled: true; + cursor: "default"; + spacing: 0em; + padding: 0em; + border-color: @main-br; + background-color: @main-bg; +} +mainbox { + enabled: true; + spacing: 0em; + padding: 0.5em; + orientation: vertical; + children: [ "wallbox" , "listbox" ]; + background-color: transparent; +} +wallbox { + spacing: 0em; + padding: 0em; + expand: false; + orientation: horizontal; + background-color: transparent; + background-image: url("~/dotfiles/config/backgrounds/aurora_borealis.png", width); + children: [ "wallframe" , "inputbar" ]; +} +wallframe { + width: 5em; + spacing: 0em; + padding: 0em; + expand: false; + background-color: @main-bg; + background-image: url("~/dotfiles/config/backgrounds/aurora_borealis.png", width); +} + + +// Inputs // +inputbar { + enabled: true; + padding: 0em; + children: [ "entry" ]; + background-color: @main-bg; + expand: true; +} +entry { + enabled: true; + padding: 1.8em; + text-color: @main-fg; + background-color: transparent; +} + + +// Lists // +listbox { + spacing: 0em; + padding: 0em; + orientation: vertical; + children: [ "dummy" , "listview" , "dummy" ]; + background-color: transparent; +} +listview { + enabled: true; + padding: 0.5em; + columns: 1; + lines: 11; + cycle: true; + fixed-height: true; + fixed-columns: false; + expand: false; + cursor: "default"; + background-color: transparent; + text-color: @main-fg; +} +dummy { + spacing: 0em; + padding: 0em; + background-color: transparent; +} + + +// Elements // +element { + enabled: true; + padding: 0.5em; + cursor: pointer; + background-color: transparent; + text-color: @main-fg; +} +element selected.normal { + background-color: @select-bg; + text-color: @select-fg; +} +element-text { + vertical-align: 0.0; + horizontal-align: 0.0; + cursor: inherit; + background-color: transparent; + text-color: inherit; +} + diff --git a/nixos/home/desktop/hyprland/clipboard-rofi.nix b/nixos/home/desktop/hyprland/clipboard-rofi.nix new file mode 100644 index 0000000..e5b87be --- /dev/null +++ b/nixos/home/desktop/hyprland/clipboard-rofi.nix @@ -0,0 +1,186 @@ +{ + lib, + config, + pkgs, + ... +}: +{ + options = { + rofi.clipboard.enable = lib.mkEnableOption "rofi-clipboard"; + }; + + config = lib.mkIf config.rofi.clipboard.enable { + home.file = { + ".config/rofi/cliboard.rasi".source = ../../../../config/clipboard.rasi; + }; + + home.packages = with pkgs; [ + wl-clipboard + cliphist + (writeShellScriptBin "clipboard" '' + export confDir="''${XDG_CONFIG_HOME:-$HOME/.config}" + roconf="''${confDir}/rofi/clipboard.rasi" + favoritesFile="''${HOME}/.cliphist_favorites" + + if printenv HYPRLAND_INSTANCE_SIGNATURE &> /dev/null; then + export hypr_border="$(hyprctl -j getoption decoration:rounding | jq '.int')" + export hypr_width="$(hyprctl -j getoption general:border_size | jq '.int')" + fi + + # Set rofi scaling + [[ "''${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10 + r_scale="configuration {font: \"JetBrainsMono Nerd Font ''${rofiScale}\";}" + wind_border=$((hypr_border * 3 / 2)) + elem_border=$([ $hypr_border -eq 0 ] && echo "5" || echo $hypr_border) + + # Evaluate spawn position + readarray -t curPos < <(hyprctl cursorpos -j | jq -r '.x,.y') + readarray -t monRes < <(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width,.height,.scale,.x,.y') + readarray -t offRes < <(hyprctl -j monitors | jq -r '.[] | select(.focused==true).reserved | map(tostring) | join("\n")') + monRes[2]="$(echo "''${monRes[2]}" | sed "s/\.//")" + monRes[0]="$(( ''${monRes[0]} * 100 / ''${monRes[2]} ))" + monRes[1]="$(( ''${monRes[1]} * 100 / ''${monRes[2]} ))" + curPos[0]="$(( ''${curPos[0]} - ''${monRes[3]} ))" + curPos[1]="$(( ''${curPos[1]} - ''${monRes[4]} ))" + + if [ "''${curPos[0]}" -ge "$((monRes[0] / 2))" ] ; then + x_pos="east" + x_off="-$((monRes[0] - curPos[0] - offRes[2]))" + else + x_pos="west" + x_off="$((curPos[0] - offRes[0]))" + fi + + if [ "''${curPos[1]}" -ge "$((monRes[1] / 2))" ] ; then + y_pos="south" + y_off="-$((monRes[1] - curPos[1] - offRes[3]))" + else + y_pos="north" + y_off="$((curPos[1] - offRes[1]))" + fi + + r_override="window{location:''${x_pos} ''${y_pos};anchor:''${x_pos} ''${y_pos};x-offset:''${x_off}px;y-offset:''${y_off}px;border:''${hypr_width}px;border-radius:''${wind_border}px;} wallbox{border-radius:''${elem_border}px;} element{border-radius:''${elem_border}px;}" + + # Show main menu if no arguments are passed + if [ $# -eq 0 ]; then + main_action=$(echo -e "History\nDelete\nView Favorites\nManage Favorites\nClear History" | rofi -dmenu -theme-str "entry { placeholder: \"Choose action\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + else + main_action="History" + fi + + case "''${main_action}" in + "History") + selected_item=$(cliphist list | rofi -dmenu -theme-str "entry { placeholder: \"History...\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + if [ -n "$selected_item" ]; then + echo "$selected_item" | cliphist decode | wl-copy + notify-send "Copied to clipboard." + fi + ;; + "Delete") + selected_item=$(cliphist list | rofi -dmenu -theme-str "entry { placeholder: \"Delete...\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + if [ -n "$selected_item" ]; then + echo "$selected_item" | cliphist delete + notify-send "Deleted." + fi + ;; + "View Favorites") + if [ -f "$favoritesFile" ] && [ -s "$favoritesFile" ]; then + mapfile -t favorites < "$favoritesFile" + decoded_lines=() + for favorite in "''${favorites[@]}"; do + decoded_favorite=$(echo "$favorite" | base64 --decode) + single_line_favorite=$(echo "$decoded_favorite" | tr '\n' ' ') + decoded_lines+=("$single_line_favorite") + done + selected_favorite=$(printf "%s\n" "''${decoded_lines[@]}" | rofi -dmenu -theme-str "entry { placeholder: \"View Favorites\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + if [ -n "$selected_favorite" ]; then + index=$(printf "%s\n" "''${decoded_lines[@]}" | grep -nxF "$selected_favorite" | cut -d: -f1) + if [ -n "$index" ]; then + selected_encoded_favorite="''${favorites[$((index - 1))]}" + echo "$selected_encoded_favorite" | base64 --decode | wl-copy + notify-send "Copied to clipboard." + else + notify-send "Error: Selected favorite not found." + fi + fi + else + notify-send "No favorites." + fi + ;; + "Manage Favorites") + manage_action=$(echo -e "Add to Favorites\nDelete from Favorites\nClear All Favorites" | rofi -dmenu -theme-str "entry { placeholder: \"Manage Favorites\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + + case "''${manage_action}" in + "Add to Favorites") + item=$(cliphist list | rofi -dmenu -theme-str "entry { placeholder: \"Add to Favorites...\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + if [ -n "$item" ]; then + full_item=$(echo "$item" | cliphist decode) + encoded_item=$(echo "$full_item" | base64 -w 0) + if grep -Fxq "$encoded_item" "$favoritesFile"; then + notify-send "Item is already in favorites." + else + echo "$encoded_item" >> "$favoritesFile" + notify-send "Added in favorites." + fi + fi + ;; + "Delete from Favorites") + if [ -f "$favoritesFile" ] && [ -s "$favoritesFile" ]; then + mapfile -t favorites < "$favoritesFile" + decoded_lines=() + for favorite in "''${favorites[@]}"; do + decoded_favorite=$(echo "$favorite" | base64 --decode) + single_line_favorite=$(echo "$decoded_favorite" | tr '\n' ' ') + decoded_lines+=("$single_line_favorite") + done + selected_favorite=$(printf "%s\n" "''${decoded_lines[@]}" | rofi -dmenu -theme-str "entry { placeholder: \"Remove from Favorites...\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + if [ -n "$selected_favorite" ]; then + index=$(printf "%s\n" "''${decoded_lines[@]}" | grep -nxF "$selected_favorite" | cut -d: -f1) + if [ -n "$index" ]; then + selected_encoded_favorite="''${favorites[$((index - 1))]}" + if [ "$(wc -l < "$favoritesFile")" -eq 1 ]; then + > "$favoritesFile" + else + grep -vF -x "$selected_encoded_favorite" "$favoritesFile" > "''${favoritesFile}.tmp" && mv "''${favoritesFile}.tmp" "$favoritesFile" + fi + notify-send "Item removed from favorites." + else + notify-send "Error: Selected favorite not found." + fi + fi + else + notify-send "No favorites to remove." + fi + ;; + "Clear All Favorites") + if [ -f "$favoritesFile" ] && [ -s "$favoritesFile" ]; then + confirm=$(echo -e "Yes\nNo" | rofi -dmenu -theme-str "entry { placeholder: \"Clear All Favorites?\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}") + if [ "$confirm" = "Yes" ]; then + > "$favoritesFile" + notify-send "All favorites have been deleted." + fi + else + notify-send "No favorites to delete." + fi + ;; + *) + echo "Invalid action" + exit 1 + ;; + esac + ;; + "Clear History") + if [ "$(echo -e "Yes\nNo" | rofi -dmenu -theme-str "entry { placeholder: \"Clear Clipboard History?\";}" -theme-str "''${r_scale}" -theme-str "''${r_override}" -config "''${roconf}")" == "Yes" ] ; then + cliphist wipe + notify-send "Clipboard history cleared." + fi + ;; + *) + echo "Invalid action" + exit 1 + ;; + esac + '') + ]; + }; +} \ No newline at end of file diff --git a/nixos/home/desktop/hyprland/rofi.nix b/nixos/home/desktop/hyprland/rofi.nix index 54e5f7c..c1a77d1 100644 --- a/nixos/home/desktop/hyprland/rofi.nix +++ b/nixos/home/desktop/hyprland/rofi.nix @@ -8,11 +8,11 @@ rofi.enable = lib.mkEnableOption "enable Rofi module"; }; - config = lib.mkIf config.rofi.enable { - home.packages = [ - pkgs.rofi-wayland - ]; + imports = [ + ./clipboard-rofi.nix + ]; + config = lib.mkIf config.rofi.enable { programs.rofi = { enable = true; cycle = true; @@ -23,17 +23,6 @@ theme = let inherit (config.lib.formats.rasi) mkLiteral; in { - # "*" = { - # main-bg = mkLiteral "#11111be6"; - # main-fg = mkLiteral "#cdd6f4ff"; - # main-br = mkLiteral "#cba6f7ff"; - # main-ex = mkLiteral "#f5e0dcff"; - # select-bg = mkLiteral "#b4befeff"; - # select-fg = mkLiteral "#11111bff"; - # separatorcolor = mkLiteral "transparent"; - # border-color = mkLiteral "transparent"; - # }; - # "configuration" = { modi = "drun,filebrowser,window,run"; show-icons = true;