[qtwin] Fix crash on pasting screenshots
Workaround for an issue with the Windows Qt version where Celestia crashes when a copied screenshot is pasted into another application. This appears to be because the data sent to the clipboard still contains a reference to the data in the destructed Image object, despite the Qt documentation stating that QClipboard::setImage causes the clipboard to take ownership of the data. This does not occur if the QImage manages its own buffer.pull/1281/head
parent
4a9403ecf5
commit
7b762832a4
|
@ -4745,22 +4745,25 @@ View* CelestiaCore::getViewByObserver(const Observer *obs) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Image CelestiaCore::captureImage() const
|
||||
void CelestiaCore::getCaptureInfo(std::array<int, 4>& viewport, celestia::PixelFormat& format) const
|
||||
{
|
||||
// Get the dimensions of the current viewport
|
||||
array<int, 4> viewport;
|
||||
getRenderer()->getViewport(viewport);
|
||||
renderer->getViewport(viewport);
|
||||
format = renderer->getPreferredCaptureFormat();
|
||||
}
|
||||
|
||||
PixelFormat format = renderer->getPreferredCaptureFormat();
|
||||
|
||||
Image image(format, viewport[2], viewport[3]);
|
||||
if (!renderer->captureFrame(viewport[0], viewport[1],
|
||||
viewport[2], viewport[3],
|
||||
format, image.getPixels()))
|
||||
bool CelestiaCore::captureImage(std::uint8_t* buffer,
|
||||
const std::array<int, 4>& viewport,
|
||||
celestia::PixelFormat format) const
|
||||
{
|
||||
if (renderer->captureFrame(viewport[0], viewport[1],
|
||||
viewport[2], viewport[3],
|
||||
format, buffer))
|
||||
{
|
||||
GetLogger()->error(_("Unable to capture a frame!\n"));
|
||||
return true;
|
||||
}
|
||||
return image;
|
||||
|
||||
GetLogger()->error(_("Unable to capture a frame!\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CelestiaCore::saveScreenShot(const fs::path& filename, ContentType type) const
|
||||
|
@ -4774,8 +4777,11 @@ bool CelestiaCore::saveScreenShot(const fs::path& filename, ContentType type) co
|
|||
return false;
|
||||
}
|
||||
|
||||
Image image = captureImage();
|
||||
if (!image.isValid())
|
||||
std::array<int, 4> viewport;
|
||||
PixelFormat format;
|
||||
getCaptureInfo(viewport, format);
|
||||
Image image(format, viewport[2], viewport[3]);
|
||||
if (!captureImage(image.getPixels(), viewport, format))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef _CELESTIACORE_H_
|
||||
#define _CELESTIACORE_H_
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
@ -19,6 +20,7 @@
|
|||
// #include <celutil/watchable.h>
|
||||
#include <celengine/solarsys.h>
|
||||
#include <celengine/overlay.h>
|
||||
#include <celengine/pixelformat.h>
|
||||
#include <celengine/texture.h>
|
||||
#include <celengine/universe.h>
|
||||
#include <celengine/render.h>
|
||||
|
@ -384,7 +386,8 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
void setScriptHook(std::unique_ptr<celestia::scripts::IScriptHook> &&hook) { m_scriptHook = std::move(hook); }
|
||||
const std::shared_ptr<celestia::scripts::ScriptMaps>& scriptMaps() const { return m_scriptMaps; }
|
||||
|
||||
Image captureImage() const;
|
||||
void getCaptureInfo(std::array<int, 4>& viewport, celestia::PixelFormat& format) const;
|
||||
bool captureImage(std::uint8_t* buffer, const std::array<int, 4>& viewport, celestia::PixelFormat format) const;
|
||||
bool saveScreenShot(const fs::path&, ContentType = Content_Unknown) const;
|
||||
|
||||
void setMeasurementSystem(MeasurementSystem);
|
||||
|
|
|
@ -750,14 +750,16 @@ static QImage::Format toQFormat(PixelFormat format)
|
|||
void CelestiaAppWindow::slotCopyImage()
|
||||
{
|
||||
//glWidget->repaint();
|
||||
Image image = m_appCore->captureImage();
|
||||
QImage grabbedImage = QImage(image.getPixels(),
|
||||
image.getWidth(),
|
||||
image.getHeight(),
|
||||
image.getPitch(),
|
||||
toQFormat(image.getFormat()));
|
||||
QApplication::clipboard()->setImage(grabbedImage);
|
||||
m_appCore->flash(_("Captured screen shot to clipboard"));
|
||||
std::array<int, 4> viewport;
|
||||
celestia::PixelFormat format;
|
||||
m_appCore->getCaptureInfo(viewport, format);
|
||||
QImage grabbedImage = QImage(viewport[2], viewport[3],
|
||||
toQFormat(format));
|
||||
if (m_appCore->captureImage(grabbedImage.bits(), viewport, format))
|
||||
{
|
||||
QApplication::clipboard()->setImage(grabbedImage);
|
||||
m_appCore->flash(_("Captured screen shot to clipboard"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue