Capture reliably with compositing off regardless of screen size
ClosedPublic

Authored by rkflx on Feb 28 2018, 9:15 PM.

Details

Summary

D10672 enabled taking screenshots of windows touching or going beyond
the border of the screen when compositing was disabled, i.e. KWin's DBus
screenshot mode was not in use. However, for some screen sizes Spectacle
would still only capture a null image. This could be observed in
particular for VMs with certain screen sizes.

The problem stems from using ints for dimensions, while
devicePixelRatio is a qReal. For setSize, QSize::operator*=() is
called, which uses qRound() and thus could also round up. This
resulted in dimensions passed to xcb_image_get() which were 1px too
large, resulting in the observed error.

The fix involves splitting setSize into setHeight and setWidth to
be able to control the rounding behaviour to always round down.
Specifying qFloor is not strictly necessary, but added for
explicitness.

Depends on D10672

Test Plan
  • QT_SCALE_FACTOR=1.5 spectacle, turn off compositing via +Alt+F12.
  • Move window to capture so it touches the bottom border of the screen, i.e. below the panel.
  • Take screenshot in Active Window mode.
  • Resize VM display vertically and repeat until a null image is captured.
  • Apply patch and observe that now the correct image is captured.

Diff Detail

Repository
R166 Spectacle
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
rkflx requested review of this revision.Feb 28 2018, 9:15 PM
rkflx created this revision.
rkflx added a comment.Mar 5 2018, 9:42 AM

Ping – 17.12.3 tagging is today.

Following your Test Plan with this patch, it it expected that the panel is included in the screenshot?

rkflx added a comment.Mar 6 2018, 12:23 PM

Thanks for testing ;)

Following your Test Plan with this patch, it it expected that the panel is included in the screenshot?

Yes, that's how capturing on X11 without KWin's help (i.e. when compositing is off) works, i.e. we only get what's on the screen. When there is overlap of any sort, it will be in the shot. With compositing it's different, because we can get at what the window painted itself (to an off-screen buffer) and don't have to rely on the final (composited) image on the screen.

IOW, that phenomenon is not related to those patches at all.

rkflx edited the test plan for this revision. (Show Details)Mar 6 2018, 12:24 PM
ngraham accepted this revision.Mar 6 2018, 12:25 PM

Gotcha. We can probably live with that for this extreme corner case. Works for me! Tested with your test case at various screen resolutions in a VM and could not get it to break.

This revision is now accepted and ready to land.Mar 6 2018, 12:25 PM
This revision was automatically updated to reflect the committed changes.