naelstrof / maim

maim (make image) takes screenshots of your desktop. It has options to take only a region, and relies on slop to query for regions. maim is supposed to be an improved scrot.
Other
2.15k stars 78 forks source link

option to freeze screen while taking screenshot #193

Open devsnek opened 4 years ago

devsnek commented 4 years ago

imagemagick's import command freezes the desktop while the region is being selected. It would be awesome to have this functionality in maim.

naelstrof commented 4 years ago

Check out issue #186

With piping shenanigans you can pull off essentially the same feature with simple tools. There's an example in issue 186

devsnek commented 4 years ago

I suppose that works, but it has a noticeable delay. Admittedly I have no idea what imagemagick is doing for this feature, but if it doesn't involve importing an image viewer or something complex like that it would be great to have in maim itself.

(The script in 186 also hides the outline of the region selection)

naelstrof commented 4 years ago

Switching maim into jpg mode should speed it up significantly. Or change the compression settings.

I definitely won't implement a "freeze" feature, it kinda exceeds the scope of the app in my opinion.

foxpy commented 4 years ago

I definitely won't implement a "freeze" feature, it kinda exceeds the scope of the app in my opinion.

As far as I understand, the only maim's purpose is to capture image immediately and write it to a pipe or a file. So, the best option to solve this particular issue would be to write a little "freeze" application. Running maim and then feh before actually taking an image is too much overhead. It takes quite a long time, it does not support multiple displays.

So, in my best considerations, with this "freeze" program a complete solution would look like:

freeze &
maim -s | xclip -selection clipboard -t image/png
kill %1
p3lim commented 3 years ago

A workaround for now, which should work with multiple displays:

# take screenshot without cursor and pipe to feh, get its pid
maim -u | feh - &
feh_pid=$!

# wait for feh to start
while [ -z "$(xdotool search --pid "$feh_pid")" ]; do
    sleep 0.1
done

# get window ID of feh
wid="$(xdotool search --pid "$feh_pid")"

# fullscreen feh and move top-left (works with multi-monitor)
xdotool windowsize "$wid" 100% 100%
xdotool windowmove "$wid" 0 0

# take the new screenshot by selection, pipe to clipboard
maim -s | xclip -selection clipboard -t image/png

# kill feh
kill "$feh_pid"

As @foxpy mentioned, feh is really slow with starting (hence the while loop), and using xdotool to resize it makes the experience jarring due to the screen flashing.

foxpy commented 2 years ago

After digging into scrot source code I have realized it grabs whole X server to prevent rendering of other applications. Not sure about imagemagick's import application, source code seemed to be too weird for me and I didn't bother reading that.

So, writing standalone "freeze" application is not a good idea because it would block maim, too. Freeze option should be implemented in maim.

And, yeah, by the time being, @p3lim's workaround is the best option we have for now.

foxpy commented 2 years ago

I definitely won't implement a "freeze" feature, it kinda exceeds the scope of the app in my opinion.

Why? I am pretty sure application itself is the best place to implement this feature. It should be pretty easy using Xlib functions XGrabServer and XUngrabServer.

Well, I have placed calls to these functions inside of maim and they didn't make any effect. I will investigate this when I have more free time.

Again, adding this feature should not (in theory) increase complexity of application or introduce new dependencies, so I am personally voting YES for the "freeze" feature.

Goosegit11 commented 1 year ago

I am voting YES for the "freeze" feature too!

duarm commented 1 year ago

I don't like the freeze feature, I prefer to screenshot in silence and then later snip the part I want, even so, it can be easily implemented externally. I made the nsxiv version of the above script, it opens so fast I can barely notice nsxiv opening in fullscreen. It requires a temp file, since nsxiv cant open from stdin.

maim -u /dev/shm/screenshot.png
nsxiv -f --anti-alias=no -b /dev/shm/screenshot.png &
nsxiv_pid=$!

# take the new screenshot by selection, pipe to clipboard
maim -s | xclip -selection clipboard -t image/png

# kill nsxiv
kill "$nsxiv_pid"
rm /dev/shm/screenshot.png

Maim would benefit from a keyboard pass-through for certain keys tho, it would be more useful than a niche freeze feature, this would allow me to interact with nsxiv without aborting maim.

vincentbernat commented 1 year ago

This is cool. To make it work on dualscreen, I have modified to use nsxiv -N nsxiv-screenshot --anti-alias=no -b /dev/shm/screenshot.png & and put that in i3 configuration:

for_window [instance="nsxiv-screenshot"] floating enable, fullscreen enable global
Goosegit11 commented 1 year ago

@duarm well, it works but it's not really smooth. it flashes when starting it, and then it flashes when taking screenshot. there's no such problem with scrot --freeze

imo, instead of workarounds we should have a real solution.