cliphist icon indicating copy to clipboard operation
cliphist copied to clipboard

rofi (custom mode with images) really slow

Open littleblack111 opened this issue 1 year ago • 1 comments

its way slower then the normal dmenu one... why.

littleblack111 avatar Oct 06 '24 09:10 littleblack111

is it possible to just add the chars for icon to the list command like cliphist list --image, so we don't need to use regex etc to make it slower

littleblack111 avatar Oct 06 '24 10:10 littleblack111

My guess this one makes it significantly slow https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-rofi-img

Every call for the clipboard removes the images, then adds it again.

kRHYME7 avatar Oct 24 '24 02:10 kRHYME7

Yes i know that is the one that made it slow(as specified in title) i proposed a solution too. In case anyone wanna implement it to be faster

littleblack111 avatar Oct 24 '24 02:10 littleblack111

For now, I will be using this. Added some checks so if file exist then do not create. 1.2s to 0.500s

Having the images handled by cliphist is a great idea

#!/usr/bin/env bash

tmp_dir="/tmp/cliphist"
mkdir -p "$tmp_dir"

if [[ -n "$1" ]]; then
    cliphist decode <<<"$1" | wl-copy
    exit
fi

read -r -d '' prog <<EOF
/^[0-9]+\s<meta http-equiv=/ { next }
/\[ binary/ {
    if (match(\$0, /^([0-9]+)\s(\[\[\s)?binary.*(jpg|jpeg|png|bmp)/, grp)) {
        file_path = "$tmp_dir/" grp[1] "." grp[3]
        if (system("[ -f " file_path " ]") != 0) {
            system("echo " grp[1] "\\\\\t | cliphist decode >" file_path)
        }
        print \$0"\0icon\x1f" file_path
        next
    }
}
1
EOF

cliphist list | gawk "$prog"

image

kRHYME7 avatar Oct 24 '24 05:10 kRHYME7

@littleblack111 Something like this ?

image

kRHYME7 avatar Oct 24 '24 06:10 kRHYME7

No. Maybe generate something like the original script, the benefit of this is not needing to pipe it to the program again everytime of an image, since it can be grabbed internally. And prob add an option to put them(like in the script it’s /tmp, maybe default to that)so u can: cliphist -show-image then pipe it to rofi

Sorry im on vacation rn, will get back to u with a more detailed explanation

littleblack111 avatar Oct 24 '24 06:10 littleblack111

Like this ? @littleblack111
image

kRHYME7 avatar Oct 24 '24 06:10 kRHYME7

Yes that would be it. How’s the performance? Thank you!

littleblack111 avatar Oct 24 '24 06:10 littleblack111

Not too significant (given the benefit) . And I think the owner of the repo has a better way to optimize this image

However, I don't really know if this deserves a merge, given that cliphist is clean & minimal. I would still open a draft pull request though.

kRHYME7 avatar Oct 24 '24 06:10 kRHYME7

Thank you!

littleblack111 avatar Oct 24 '24 07:10 littleblack111

@littleblack111 BTW, I needed some few suggestions regarding on how we should interface this.

I think it's odd if it only supports rofi. One can write a lightweight clipboard implementation using cliphist with image preview etc. So I don't want to restrain the feature for rofi only. so the PR might add 2 or 3 flags.

-image <delimeter string>  export and list the images to the target directory plus add the delimiter string  
-image-dir <target/dir>         optional directory, This is optional as I was thinking screenshots are confidential so they might want to safe keep it somewhere.  default: /tmp/cliphist

Also, performance is improved by just creating the file if not yet existed. image

kRHYME7 avatar Oct 24 '24 07:10 kRHYME7

Yes that’s true.

That should work.

littleblack111 avatar Oct 24 '24 08:10 littleblack111

Can you test the patch?

  • But take your time, no rush

kRHYME7 avatar Oct 24 '24 11:10 kRHYME7

yep, this is amazing. had to do a pipe to head -n 100 to achieve the same performance with original script

littleblack111 avatar Oct 25 '24 18:10 littleblack111

Hi, incase the PR won't be merge I wrote something in python.

image


#!/usr/bin/env python3

import os
import subprocess
import re


tmp_dir = os.getenv("XDG_RUNTIME_DIR", "/tmp")
tmp_dir = os.path.join(tmp_dir, "cliphist")


def decode_and_save_image(grp):
    img_path = os.path.join(tmp_dir, f"{grp[0]}.{grp[2]}")
    if not os.path.exists(img_path):
        proc = subprocess.run(
            ["cliphist", "decode", grp[0]], capture_output=True, check=True
        )
        with open(img_path, "wb") as img_file:
            img_file.write(proc.stdout)
    return img_path


def main():
    os.makedirs(tmp_dir, exist_ok=True)

    prog = re.compile(r"^([0-9]+)\s(\[\[\s)?binary.*(jpg|jpeg|png|bmp)")

    result = subprocess.run(
        ["cliphist", "list"], capture_output=True, text=True, check=True
    )
    lines = result.stdout.splitlines()

    for line in lines:
        if re.match(r"^[0-9]+\s<meta http-equiv=", line):
            continue

        match = prog.match(line)
        if match:
            grp = match.groups()
            img_path = decode_and_save_image(grp)
            print(f"{line}\0icon\x1f{img_path}")
        else:
            print(line)


if __name__ == "__main__":
    import sys
    main()

kRHYME7 avatar Jan 05 '25 05:01 kRHYME7

Hi, just in case anyone is looking for an alternative: https://github.com/szaffarano/rofi-tools

szaffarano avatar Jan 27 '25 12:01 szaffarano

sorry all, closing in favour of the external scripts in the thread here

sentriz avatar Apr 06 '25 17:04 sentriz