From f4618c3271436a9ae3b72b0900a8a5b86b92ed14 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Wed, 1 May 2024 10:21:28 -0400 Subject: [PATCH] feat(ags): use experimental clipboard manager --- home/wofi/default.nix | 17 --- home/wofi/style.css | 92 --------------- modules/ags/clipboard/default.nix | 19 +++ modules/ags/clipboard/script.sh | 45 +++++++ .../config/scss/wim-widgets/clipboard.scss | 64 ++++++++++ modules/ags/config/scss/wim.scss | 1 + modules/ags/config/ts/clipboard/main.ts | 110 ++++++++++++++++++ modules/ags/config/wim.ts | 2 + modules/ags/default.nix | 1 + modules/hyprland/packages.nix | 4 +- 10 files changed, 243 insertions(+), 112 deletions(-) delete mode 100644 home/wofi/default.nix delete mode 100644 home/wofi/style.css create mode 100644 modules/ags/clipboard/default.nix create mode 100755 modules/ags/clipboard/script.sh create mode 100644 modules/ags/config/scss/wim-widgets/clipboard.scss create mode 100644 modules/ags/config/ts/clipboard/main.ts diff --git a/home/wofi/default.nix b/home/wofi/default.nix deleted file mode 100644 index 03838d1..0000000 --- a/home/wofi/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{...}: { - programs = { - wofi = { - enable = true; - settings = { - prompt = ""; - allow_images = true; - normal_window = true; - image_size = "48"; - matching = "fuzzy"; - insensitive = true; - no_actions = true; - }; - style = builtins.readFile ./style.css; - }; - }; -} diff --git a/home/wofi/style.css b/home/wofi/style.css deleted file mode 100644 index 62a32b6..0000000 --- a/home/wofi/style.css +++ /dev/null @@ -1,92 +0,0 @@ -/* https://github.com/dracula/wofi/blob/master/style.css */ -* { - font-size: 16px; -} - -window, -undershoot { - all: unset; -} - -#input { - all: unset; - border-radius: 9px; - color: #f8f8f2; - background-color: rgba(#44475a, 0.6); - border: 1px solid #44475a; - padding: 8px; - margin: 16.2px; - margin-bottom: 0; -} - -#outer-box { - all: unset; - box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.6); - border: 2px solid rgba(189, 147, 249, 0.8); - border-radius: 25px; - background-color: rgba(40, 42, 54, 0.8); - color: #f8f8f2; - padding: 16.2px; -} - -#inner-box { - padding: 16.2px; - min-width: 500px; - min-height: 450px; -} - -#scroll scrollbar, #scroll scrollbar * { - all: unset; -} - -#scroll scrollbar { - transition: 200ms; - background-color: rgba(23, 23, 23, 0.3); - - &:hover { - background-color: rgba(23, 23, 23, 0.7); - } -} -#scroll scrollbar.vertical:hover slider { - background-color: rgba(238, 238, 238, 0.7); - min-width: .6em; -} -#scroll scrollbar.horizontal:hover slider { - background-color: rgba(238, 238, 238, 0.7); - min-height: .6em; -} -#scroll .vertical slider { - background-color: rgba(238, 238, 238, 0.5); - border-radius: 9px; - min-width: .4em; - min-height: 2em; - transition: 200ms; -} -#scroll .horizontal slider { - background-color: rgba(238, 238, 238, 0.5); - border-radius: 9px; - min-height: .4em; - min-width: 2em; - transition: 200ms; -} - -#entry { - all: unset; - padding: 9px; -} - -#entry image, #entry label { - all: unset; -} - #entry image { - margin-right: 9px; -} - -#entry:selected { - background-color: rgba(189, 147, 249, 0.5); - border-radius: 9px; - box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03); -} -#entry:selected image { - -gtk-icon-shadow: 3px 3px rgba(0, 0, 0, 0.8); -} diff --git a/modules/ags/clipboard/default.nix b/modules/ags/clipboard/default.nix new file mode 100644 index 0000000..c9487b9 --- /dev/null +++ b/modules/ags/clipboard/default.nix @@ -0,0 +1,19 @@ +{ + cliphist, + gawk, + imagemagick, + ripgrep, + writeShellApplication, + ... +}: +writeShellApplication { + name = "clipboard-manager"; + runtimeInputs = [ + cliphist + gawk + imagemagick + ripgrep + ]; + + text = builtins.readFile ./script.sh; +} diff --git a/modules/ags/clipboard/script.sh b/modules/ags/clipboard/script.sh new file mode 100755 index 0000000..01e7bde --- /dev/null +++ b/modules/ags/clipboard/script.sh @@ -0,0 +1,45 @@ +set +o errexit + +# Modified from https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-wofi-img + +# set up thumbnail directory +thumb_dir="/tmp/cliphist/thumbs" +mkdir -p "$thumb_dir" + +cliphist_list="$(cliphist list)" + +# delete thumbnails in cache but not in cliphist +for thumb in "$thumb_dir"/*; do + clip_id="${thumb##*/}" + clip_id="${clip_id%.*}" + check=$(rg <<< "$cliphist_list" "^$clip_id\s") + if [ -z "$check" ]; then + >&2 rm -v "$thumb" + fi +done + +# create thumbnail if image not processed already +read -r -d '' prog <' $thumb_dir/"image ) + print "img:$thumb_dir/"image + next +} + +1 +EOF + +output=$(gawk <<< "$cliphist_list" "$prog") + +# Use a while loop with read to iterate over each line +echo "$output" | while IFS= read -r line; do + if [[ ! $line =~ ^img:/tmp/cliphist/thumbs ]]; then + [[ $line =~ ([0-9]+) ]] + line=${BASH_REMATCH[1]} + fi + + echo "$line" +done diff --git a/modules/ags/config/scss/wim-widgets/clipboard.scss b/modules/ags/config/scss/wim-widgets/clipboard.scss new file mode 100644 index 0000000..d08f16e --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/clipboard.scss @@ -0,0 +1,64 @@ +.clipboard { + all: unset; + border: 2px solid $contrast-bg; + border-radius: 25px; + background-color: $bg; + color: #f8f8f2; + padding: 2px; + + * { + font-size: 16px; + } + + list, row { + all: unset; + } + + scrolledwindow { + padding: 10px; + padding-bottom: 0; + min-width: 900px; + min-height: 750px; + + scrollbar, scrollbar * { + all: unset; + } + + scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); + margin: 20px 0; + + &:hover { + background-color: rgba(23, 23, 23, 0.7); + + slider { + background-color: rgba(238, 238, 238, 0.7); + min-width: .6em; + } + } + + slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-width: .4em; + min-height: 2em; + transition: 200ms; + } + } + } + + .item { + all: unset; + transition: 200ms; + border-radius: 9px; + + box { + padding: 10px; + } + } + + *:selected, .item:hover, .item:focus { + background-color: #363449; + } +} diff --git a/modules/ags/config/scss/wim.scss b/modules/ags/config/scss/wim.scss index fdc0460..91f9b23 100644 --- a/modules/ags/config/scss/wim.scss +++ b/modules/ags/config/scss/wim.scss @@ -21,3 +21,4 @@ undershoot { @import "./wim-widgets/applauncher"; @import "./wim-widgets/osd"; @import "./wim-widgets/osk"; +@import "./wim-widgets/clipboard"; diff --git a/modules/ags/config/ts/clipboard/main.ts b/modules/ags/config/ts/clipboard/main.ts new file mode 100644 index 0000000..15e28be --- /dev/null +++ b/modules/ags/config/ts/clipboard/main.ts @@ -0,0 +1,110 @@ +const { Box, Icon, Label, ListBox, Scrollable } = Widget; +const { execAsync } = Utils; + +import Gtk from 'gi://Gtk?version=3.0'; + +import CursorBox from '../misc/cursorbox.ts'; +import PopupWindow from '../misc/popup.ts'; + + +const N_ITEMS = 30; + +export default () => { + const list = ListBox(); + + list.set_sort_func((row1, row2) => { + const getKey = (r: Gtk.ListBoxRow) => parseInt(r.get_child()?.name ?? ''); + + return getKey(row2) - getKey(row1); + }); + + const updateItems = () => { + (list.get_children() as Gtk.ListBoxRow[]).forEach((r) => { + r.changed(); + }); + }; + + const makeItem = (key: string, val: string) => { + const widget = CursorBox({ + class_name: 'item', + name: key, + + on_primary_click_release: () => { + execAsync([ + 'bash', '-c', `cliphist list | grep ${key} | cliphist decode | wl-copy`, + ]).then(() => { + App.closeWindow('win-clipboard'); + }); + }, + + child: Box({ + children: [ + val.startsWith('img:') ? + Icon({ + icon: val.replace('img:', ''), + size: 100 * 2, + }) : + + Label({ + label: val, + truncate: 'end', + max_width_chars: 100, + }), + ], + }), + }); + + list.add(widget); + widget.show_all(); + updateItems(); + }; + + // Decode old item: + const decodeItem = (index: string) => { + execAsync([ + 'bash', '-c', `cliphist list | grep ${index} | cliphist decode`, + ]).then((out) => { + makeItem(index, out); + }); + }; + + const on_open = () => { + execAsync('clipboard-manager').then((out) => { + list.get_children()?.forEach((ch) => { + ch.destroy(); + }); + + const items = out.split('\n'); + + for (let i = 0; i < N_ITEMS; ++i) { + if (items[i].includes('img')) { + makeItem((items[i].match('[0-9]+') ?? [''])[0], items[i]); + } + else { + decodeItem(items[i]); + } + } + }).catch(console.log); + }; + + on_open(); + + return PopupWindow({ + name: 'clipboard', + on_open, + + child: Box({ + class_name: 'clipboard', + children: [ + Scrollable({ + hscroll: 'never', + vscroll: 'automatic', + child: Box({ + vertical: true, + children: [list], + }), + }), + ], + }), + }); +}; diff --git a/modules/ags/config/wim.ts b/modules/ags/config/wim.ts index aafdd1b..fce2713 100644 --- a/modules/ags/config/wim.ts +++ b/modules/ags/config/wim.ts @@ -3,6 +3,7 @@ import AppLauncher from './ts/applauncher/main.ts'; import Bar from './ts/bar/wim.ts'; import BgFade from './ts/misc/background-fade.ts'; import Calendar from './ts/date.ts'; +import Clipboard from './ts/clipboard/main.ts'; import Corners from './ts/corners/main.ts'; import { NotifPopups, NotifCenter } from './ts/notifications/wim.ts'; import OSD from './ts/osd/main.ts'; @@ -23,6 +24,7 @@ App.config({ AppLauncher(), Calendar(), + Clipboard(), NotifCenter(), OSD(), OSK(), diff --git a/modules/ags/default.nix b/modules/ags/default.nix index c428f70..d315a54 100644 --- a/modules/ags/default.nix +++ b/modules/ags/default.nix @@ -107,6 +107,7 @@ in { dart-sass bun playerctl + (callPackage ./clipboard {}) ## gui pavucontrol # TODO: replace with ags widget diff --git a/modules/hyprland/packages.nix b/modules/hyprland/packages.nix index 40a617a..0363c26 100644 --- a/modules/hyprland/packages.nix +++ b/modules/hyprland/packages.nix @@ -17,7 +17,6 @@ in { ../../home/foot.nix ../../home/mpv ../../home/obs.nix - ../../home/wofi ({config, ...}: let symlink = config.lib.file.mkOutOfStoreSymlink; @@ -115,7 +114,6 @@ in { ]; windowrule = [ - "noborder,^(wofi)$" "tile,^(libreoffice)$" "float,^(org.gnome.Calculator)$" "float,^(com.gabm.satty)$" @@ -133,7 +131,7 @@ in { "$mainMod, Q, exec, foot" # Clipboard History - "$mainMod, V, exec, killall -r wofi || cliphist list | wofi --dmenu | cliphist decode | wl-copy" + "$mainMod, V, exec, ags -t win-clipboard" " , Print, exec, screenshot" "$mainMod, Print, exec, grim -g \"$(slurp)\" - | satty -f - --output-filename \"screenshot-$(date --iso-8601=seconds)\""