neXromancers / hacksaw

hacksaw (Select Operation)
Mozilla Public License 2.0
97 stars 7 forks source link

Sometimes returns negative offset values #29

Open FallenWarrior2k opened 4 years ago

FallenWarrior2k commented 4 years ago

Spotify doesn't start maximized, but still takes up the full screen. Trying to use hacksaw to grab the size and coordinates of that window in it's non-maximized form returns a Y offset of -8, which breaks things trying to consume that value. For comparison, slop returns a Y offset of 0 for the same window.

I'm not really sure what information to provide beyond this, but I'll provide what I can if you ask me for it.

Lonami commented 4 years ago

-8 is still a valid offset, though? I can drag windows to be partly outside my desktop (top left) and I will get negative offsets as expected.

9ary commented 4 years ago

Yes, it's perfectly normal for a window's geometry to overflow the bounds of the screen. Whether it's up to hacksaw to clamp the return value is a very good question though. There are arguments either way, and considering it's not a trivial thing to do in a script, I suppose an option could be added for it.

Lonami commented 4 years ago

Not that complicated?

hacksaw | sed -r 's/-[0-9]+/0/g'
9ary commented 4 years ago

That's not enough, you also need to subtract the excess from the width and height, and account for overflow on the bottom and right edges.

Lonami commented 4 years ago

Behold my bash skills. Yeah probably just adding --clamp is the best.

FallenWarrior2k commented 4 years ago

In this case, my point was to equal parts that the window is not actually off-screen and the difference to slop for the same window.

The program that broke was ffmpeg, or more specifically the x11grab input which seems to be either unable to handle the negative offsets (in the format output by hacksaw) or requires some other special casing for negative offsets.

FallenWarrior2k commented 4 years ago

I know that filtering out the negative values as a workaround isn't too difficult (esp. since I'm parsing the output into separate variables anyway for this script), but I was wondering about why this happens as well.

9ary commented 4 years ago

As for an example of unclamped geometry being useful, when you pass both -g and -i to shotgun, you can actually capture the window's contents directly, independently of backgrounds (for windows that make use of the alpha channel), obstruction from another window, or part of the window being off-screen. Out of bounds geometry without -i will most likely break though, because then you're trying to capture the root window (and that also applies to ffmpeg's x11grab indeed).

In this case, my point was to equal parts that the window is not actually off-screen and the difference to slop for the same window.

I'm not entirely sure I understood that sentence, but it sounds like your window manager's decorations are off-screen, while the window contents are not. The -r option might help, but it's not the real solution to the problem.

I know that filtering out the negative values as a workaround isn't too difficult (esp. since I'm parsing the output into separate variables anyway for this script), but I was wondering about why this happens as well.

It's just a limitation of the X11 protocol, albeit a reasonable one. You can't capture the contents of a window outside of its boundaries.

FallenWarrior2k commented 4 years ago

I'm not entirely sure I understood that sentence, but it sounds like your window manager's decorations are off-screen, while the window contents are not. The -r option might help, but it's not the real solution to the problem.

I think it's easiest to show with images. This is how the window looks maximized, while this is how it looks right when starting up. As you can see, there's some pixels of background on the top corners due to rounded corners on the title bar, but otherwise they look exactly the same (save for the different title, which is solely because I hadn't restarted playback yet).

Yet the first returns a vertical offset of 0, while the second comes out to -8.

9ary commented 4 years ago

This is strange. To be honest I'm not sure what could be causing this. What's your DE/window manager? Does it add shadows to your windows?

FallenWarrior2k commented 4 years ago

I'm using GNOME 3.36.2 on Arch, and no, there's no shadows as far as I'm aware.

If you want me to, I could whip out good ol' GDB and look into it further, e.g. by comparing the values going into and coming out of libxcb.

9ary commented 4 years ago

GNOME is known to do weird things that no other WM does, I believe that's what _NET_FRAME_EXTENTS is for. Not sure whether slop actually clamps the geometry to root window boundaries though.

FallenWarrior2k commented 4 years ago

This is the reply from xcb::get_geometry: image I was trying to grab one from slop as well, but froze my session in the process (placed a breakpoint in a function that was called on hovering over a window; had to switch to TTY to kill -9 it). However, in the process, I discovered this by chance. I'm no X wiz, so I'm assuming y'all can do more with that than I can.

FallenWarrior2k commented 4 years ago

Based on what you said and that comment, I'm assuming it's indeed Mutter doing something stupid, as usual.

9ary commented 4 years ago

Yes, I was looking at the same piece of code. The reason for this is precisely what the comment says: Mutter (and GTK3 CSD) draws shadows as part of the decoration window rather than as a compositor effect (why?), so the actual window is larger than it looks, even if your theme has no visible shadows. This means that we need to do the same thing as slop here (maybe optionally, because you may still want to capture the shadow). With that said, I suspect that slop will also return out of bounds geometry if you drag the window to be partially off-screen. I think it would definitely be interesting to allow clamping the output value to better support floating window managers.

expectocode commented 4 years ago

Something that might work as a fix for your particular situation could be to change the -r level, which might remove the window decorations.

FallenWarrior2k commented 4 years ago

Indeed, using -r 1 removes the title bar entirely, leaving me with a vertical offset of 30. Whether I wanna keep them and clamp the values manually or just remove them is something I gotta think about another time.

However, there's another thing. I tried testing the out-of-bounds thing with slop on bspwm with a window that was out of the screen in the top-left corner, and both hacksaw and slop returned the same geometry with negative values for X and Y. So far, so good. But, in the process I noticed that somehow, hacksaw starts lagging hard in comparison to slop when there's lots of moving parts on the screen. An example. This happened even without recording, so it's definitely not an issue of the encoder hogging my CPU (which it's configured not to do anyway).

9ary commented 4 years ago

Indeed, using -r 1 removes the title bar entirely, leaving me with a vertical offset of 30.

That's the expected behavior.

Whether I wanna keep them and clamp the values manually or just remove them is something I gotta think about another time.

I think both _NET_FRAME_EXTENTS and clamping are worth supporting, but I'll leave that up to the others because I don't really have a way to test hacksaw anymore since I'm using sway now.

However, there's another thing. I tried testing the out-of-bounds thing with slop on bspwm with a window that was out of the screen in the top-left corner, and both hacksaw and slop returned the same geometry with negative values for X and Y.

Yep, @expectocode has also confirmed this, so the only difference here is just us not supporting _NET_FRAME_EXTENTS.

But, in the process I noticed that somehow, hacksaw starts lagging hard in comparison to slop when there's lots of moving parts on the screen. An example. This happened even without recording, so it's definitely not an issue of the encoder hogging my CPU (which it's configured not to do anyway).

I'm not quite sure what would cause this, but you should open a separate issue about it.

FallenWarrior2k commented 4 years ago

Gonna do that tomorrow probs. Thanks for the help and quick responses.

FallenWarrior2k commented 4 years ago

Okay, I'm assuming this ties in with the whole Mutter thing, but I noticed something else as well: All the other coordinates are somewhat off as well, as you can see in the following snippet. Noticed because I was trying to with manual clamping but still got out-of-bounds errors from x11grab.

λ hacksaw
1220x1938+3830+-8
λ slop
1200x1920+3840+0
9ary commented 4 years ago

Yeah that's basically the same problem.