13
13
#include < wx/image.h>
14
14
#include < wx/dataobj.h>
15
15
#include < wx/clipbrd.h>
16
+ #include < wx/log.h>
16
17
17
18
std::unique_ptr<Renderer> g_renderer;
18
19
@@ -81,7 +82,7 @@ uint8 Renderer::RGBComponentToSRGB(uint8 cli)
81
82
return (uint8)(cs * 255 .0f );
82
83
}
83
84
84
- fs::path _GenerateScreenshotFilename (bool isDRC)
85
+ static std::optional< fs::path> GenerateScreenshotFilename (bool isDRC)
85
86
{
86
87
fs::path screendir = ActiveSettings::GetUserDataPath (" screenshots" );
87
88
// build screenshot name with format Screenshot_YYYY-MM-DD_HH-MM-SS[_GamePad].png
@@ -101,60 +102,87 @@ fs::path _GenerateScreenshotFilename(bool isDRC)
101
102
screenshotPath.append (fmt::format (" {}.png" , screenshotFileName));
102
103
else
103
104
screenshotPath.append (fmt::format (" {}_{}.png" , screenshotFileName, i + 1 ));
105
+
104
106
std::error_code ec;
105
- if (!fs::exists (screenshotPath))
107
+ bool exists = fs::exists (screenshotPath, ec);
108
+
109
+ if (!ec && !exists)
106
110
return screenshotPath;
107
111
}
108
- return screenshotPath; // if all exist checks fail, return the last path we tried
112
+ return std::nullopt;
109
113
}
110
114
111
115
std::mutex s_clipboardMutex;
112
116
113
- void Renderer::SaveScreenshot (const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow) const
117
+ static bool SaveScreenshotToClipboard (const wxImage &image)
118
+ {
119
+ bool success = false ;
120
+
121
+ s_clipboardMutex.lock ();
122
+ if (wxTheClipboard->Open ())
123
+ {
124
+ wxTheClipboard->SetData (new wxImageDataObject (image));
125
+ wxTheClipboard->Close ();
126
+ success = true ;
127
+ }
128
+ s_clipboardMutex.unlock ();
129
+
130
+ return success;
131
+ }
132
+
133
+ static bool SaveScreenshotToFile (const wxImage &image, bool mainWindow)
134
+ {
135
+ auto path = GenerateScreenshotFilename (!mainWindow);
136
+ if (!path) return false ;
137
+
138
+ std::error_code ec;
139
+ fs::create_directories (path->parent_path (), ec);
140
+ if (ec) return false ;
141
+
142
+ // suspend wxWidgets logging for the lifetime this object, to prevent a message box if wxImage::SaveFile fails
143
+ wxLogNull _logNo;
144
+ return image.SaveFile (path->wstring ());
145
+ }
146
+
147
+ static void ScreenshotThread (std::vector<uint8> data, bool save_screenshot, int width, int height, bool mainWindow)
114
148
{
115
- const bool save_screenshot = GetConfig ().save_screenshot ;
116
- std::thread ([](std::vector<uint8> data, bool save_screenshot, int width, int height, bool mainWindow)
117
- {
118
149
#if BOOST_OS_WINDOWS
119
- // on Windows wxWidgets uses OLE API for the clipboard
120
- // to make this work we need to call OleInitialize() on the same thread
121
- OleInitialize (nullptr );
150
+ // on Windows wxWidgets uses OLE API for the clipboard
151
+ // to make this work we need to call OleInitialize() on the same thread
152
+ OleInitialize (nullptr );
122
153
#endif
154
+
155
+ wxImage image (width, height, data.data (), true );
123
156
124
- wxImage image (width, height, data. data (), true );
125
-
126
- if (mainWindow )
157
+ if (mainWindow)
158
+ {
159
+ if ( SaveScreenshotToClipboard (image) )
127
160
{
128
- s_clipboardMutex.lock ();
129
- if (wxTheClipboard->Open ())
130
- {
131
- wxTheClipboard->SetData (new wxImageDataObject (image));
132
- wxTheClipboard->Close ();
133
- if (!save_screenshot && mainWindow)
134
- LatteOverlay_pushNotification (" Screenshot saved to clipboard" , 2500 );
135
- }
136
- else
137
- {
138
- LatteOverlay_pushNotification (" Failed to open clipboard" , 2500 );
139
- }
140
- s_clipboardMutex.unlock ();
161
+ if (!save_screenshot)
162
+ LatteOverlay_pushNotification (" Screenshot saved to clipboard" , 2500 );
141
163
}
164
+ else
165
+ {
166
+ LatteOverlay_pushNotification (" Failed to open clipboard" , 2500 );
167
+ }
168
+ }
142
169
143
- // save to png file
144
- if (save_screenshot)
170
+ if (save_screenshot)
171
+ {
172
+ if (SaveScreenshotToFile (image, mainWindow))
145
173
{
146
- fs::path screendir = _GenerateScreenshotFilename (!mainWindow);
147
- if (!fs::exists (screendir.parent_path ()))
148
- fs::create_directories (screendir.parent_path ());
149
- if (image.SaveFile (screendir.wstring ()))
150
- {
151
- if (mainWindow)
152
- LatteOverlay_pushNotification (" Screenshot saved" , 2500 );
153
- }
154
- else
155
- {
156
- LatteOverlay_pushNotification (" Failed to save screenshot to file" , 2500 );
157
- }
174
+ if (mainWindow)
175
+ LatteOverlay_pushNotification (" Screenshot saved" , 2500 );
158
176
}
159
- }, rgb_data, save_screenshot, width, height, mainWindow).detach ();
177
+ else
178
+ {
179
+ LatteOverlay_pushNotification (" Failed to save screenshot to file" , 2500 );
180
+ }
181
+ }
182
+ }
183
+
184
+ void Renderer::SaveScreenshot (const std::vector<uint8>& rgb_data, int width, int height, bool mainWindow) const
185
+ {
186
+ const bool save_screenshot = GetConfig ().save_screenshot ;
187
+ std::thread (ScreenshotThread, rgb_data, save_screenshot, width, height, mainWindow).detach ();
160
188
}
0 commit comments