mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Fixes regressions introduced with GIF support (#43589)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Fixes regressions introduced with GIF support: - Switches default recording format back to MP4 - Fixes framerate issues between the two formats - Fixes file path names <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [x ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Switches default recording format back to MP4 - Fixes framerate issues between the two formats - Fixes file path names - <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Manual testing
This commit is contained in:
@@ -39,6 +39,10 @@ type_pEnableThemeDialogTexture pEnableThemeDialogTexture;
|
|||||||
#define WIN7_VERSION 0x106
|
#define WIN7_VERSION 0x106
|
||||||
#define WIN10_VERSION 0x206
|
#define WIN10_VERSION 0x206
|
||||||
|
|
||||||
|
// Default recording format frame rates
|
||||||
|
#define RECORDING_FORMAT_GIF_DEFAULT_FRAMERATE 15
|
||||||
|
#define RECORDING_FORMAT_MP4_DEFAULT_FRAMERATE 30
|
||||||
|
|
||||||
// Time that we'll cache live zoom window to avoid flicker
|
// Time that we'll cache live zoom window to avoid flicker
|
||||||
// of live zooming on Vista/ws2k8
|
// of live zooming on Vista/ws2k8
|
||||||
#define LIVEZOOM_WINDOW_TIMEOUT 2*3600*1000
|
#define LIVEZOOM_WINDOW_TIMEOUT 2*3600*1000
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ LOGFONT g_LogFont;
|
|||||||
BOOLEAN g_DemoTypeUserDriven = false;
|
BOOLEAN g_DemoTypeUserDriven = false;
|
||||||
TCHAR g_DemoTypeFile[MAX_PATH] = {0};
|
TCHAR g_DemoTypeFile[MAX_PATH] = {0};
|
||||||
DWORD g_DemoTypeSpeedSlider = static_cast<int>(((MIN_TYPING_SPEED - MAX_TYPING_SPEED) / 2) + MAX_TYPING_SPEED);
|
DWORD g_DemoTypeSpeedSlider = static_cast<int>(((MIN_TYPING_SPEED - MAX_TYPING_SPEED) / 2) + MAX_TYPING_SPEED);
|
||||||
DWORD g_RecordFrameRate = 30;
|
DWORD g_RecordFrameRate = 30; // We default to 30 here, but g_RecordFrameRate can be different depending on recording format and gets set accordingly
|
||||||
DWORD g_RecordScaling = 100;
|
DWORD g_RecordScaling = 100;
|
||||||
DWORD g_RecordScalingGIF = 50;
|
DWORD g_RecordScalingGIF = 50;
|
||||||
DWORD g_RecordScalingMP4 = 100;
|
DWORD g_RecordScalingMP4 = 100;
|
||||||
RecordingFormat g_RecordingFormat = RecordingFormat::GIF;
|
RecordingFormat g_RecordingFormat = RecordingFormat::MP4;
|
||||||
BOOLEAN g_CaptureAudio = FALSE;
|
BOOLEAN g_CaptureAudio = FALSE;
|
||||||
TCHAR g_MicrophoneDeviceId[MAX_PATH] = {0};
|
TCHAR g_MicrophoneDeviceId[MAX_PATH] = {0};
|
||||||
|
|
||||||
@@ -87,8 +87,7 @@ REG_SETTING RegSettings[] = {
|
|||||||
{ L"SnapToGrid", SETTING_TYPE_BOOLEAN, 0, &g_SnapToGrid, static_cast<DOUBLE>(g_SnapToGrid) },
|
{ L"SnapToGrid", SETTING_TYPE_BOOLEAN, 0, &g_SnapToGrid, static_cast<DOUBLE>(g_SnapToGrid) },
|
||||||
{ L"ZoominSliderLevel", SETTING_TYPE_DWORD, 0, &g_SliderZoomLevel, static_cast<DOUBLE>(g_SliderZoomLevel) },
|
{ L"ZoominSliderLevel", SETTING_TYPE_DWORD, 0, &g_SliderZoomLevel, static_cast<DOUBLE>(g_SliderZoomLevel) },
|
||||||
{ L"Font", SETTING_TYPE_BINARY, sizeof g_LogFont, &g_LogFont, static_cast<DOUBLE>(0) },
|
{ L"Font", SETTING_TYPE_BINARY, sizeof g_LogFont, &g_LogFont, static_cast<DOUBLE>(0) },
|
||||||
{ L"RecordFrameRate", SETTING_TYPE_DWORD, 0, &g_RecordFrameRate, static_cast<DOUBLE>(g_RecordFrameRate) },
|
{ L"RecordingFormat", SETTING_TYPE_DWORD, 0, &g_RecordingFormat, static_cast<DOUBLE>(g_RecordingFormat) },
|
||||||
{ L"RecordingFormat", SETTING_TYPE_DWORD, 0, &g_RecordingFormat, static_cast<DOUBLE>(0) },
|
|
||||||
{ L"RecordScalingGIF", SETTING_TYPE_DWORD, 0, &g_RecordScalingGIF, static_cast<DOUBLE>(g_RecordScalingGIF) },
|
{ L"RecordScalingGIF", SETTING_TYPE_DWORD, 0, &g_RecordScalingGIF, static_cast<DOUBLE>(g_RecordScalingGIF) },
|
||||||
{ L"RecordScalingMP4", SETTING_TYPE_DWORD, 0, &g_RecordScalingMP4, static_cast<DOUBLE>(g_RecordScalingMP4) },
|
{ L"RecordScalingMP4", SETTING_TYPE_DWORD, 0, &g_RecordScalingMP4, static_cast<DOUBLE>(g_RecordScalingMP4) },
|
||||||
{ L"CaptureAudio", SETTING_TYPE_BOOLEAN, 0, &g_CaptureAudio, static_cast<DOUBLE>(g_CaptureAudio) },
|
{ L"CaptureAudio", SETTING_TYPE_BOOLEAN, 0, &g_CaptureAudio, static_cast<DOUBLE>(g_CaptureAudio) },
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ BOOL g_RecordToggle = FALSE;
|
|||||||
BOOL g_RecordCropping = FALSE;
|
BOOL g_RecordCropping = FALSE;
|
||||||
SelectRectangle g_SelectRectangle;
|
SelectRectangle g_SelectRectangle;
|
||||||
std::wstring g_RecordingSaveLocation;
|
std::wstring g_RecordingSaveLocation;
|
||||||
|
std::wstring g_RecordingSaveLocationGIF;
|
||||||
winrt::IDirect3DDevice g_RecordDevice{ nullptr };
|
winrt::IDirect3DDevice g_RecordDevice{ nullptr };
|
||||||
std::shared_ptr<VideoRecordingSession> g_RecordingSession = nullptr;
|
std::shared_ptr<VideoRecordingSession> g_RecordingSession = nullptr;
|
||||||
std::shared_ptr<GifRecordingSession> g_GifRecordingSession = nullptr;
|
std::shared_ptr<GifRecordingSession> g_GifRecordingSession = nullptr;
|
||||||
@@ -2173,7 +2174,10 @@ INT_PTR CALLBACK OptionsProc( HWND hDlg, UINT message,
|
|||||||
CheckDlgButton( g_OptionsTabs[RECORD_PAGE].hPage, IDC_CAPTURE_AUDIO,
|
CheckDlgButton( g_OptionsTabs[RECORD_PAGE].hPage, IDC_CAPTURE_AUDIO,
|
||||||
g_CaptureAudio ? BST_CHECKED: BST_UNCHECKED );
|
g_CaptureAudio ? BST_CHECKED: BST_UNCHECKED );
|
||||||
|
|
||||||
for (int i = 0; i < _countof(g_FramerateOptions); i++) {
|
//
|
||||||
|
// The framerate drop down list is not used in the current version (might be added in the future)
|
||||||
|
//
|
||||||
|
/*for (int i = 0; i < _countof(g_FramerateOptions); i++) {
|
||||||
|
|
||||||
_stprintf(text, L"%d", g_FramerateOptions[i]);
|
_stprintf(text, L"%d", g_FramerateOptions[i]);
|
||||||
SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast<UINT>(CB_ADDSTRING),
|
SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast<UINT>(CB_ADDSTRING),
|
||||||
@@ -2182,7 +2186,7 @@ INT_PTR CALLBACK OptionsProc( HWND hDlg, UINT message,
|
|||||||
|
|
||||||
SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), CB_SETCURSEL, static_cast<WPARAM>(i), static_cast<LPARAM>(0));
|
SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), CB_SETCURSEL, static_cast<WPARAM>(i), static_cast<LPARAM>(0));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Add the recording format to the combo box and set the current selection
|
// Add the recording format to the combo box and set the current selection
|
||||||
size_t selection = 0;
|
size_t selection = 0;
|
||||||
@@ -2345,17 +2349,8 @@ INT_PTR CALLBACK OptionsProc( HWND hDlg, UINT message,
|
|||||||
text[2] = 0;
|
text[2] = 0;
|
||||||
newTimeout = _tstoi( text );
|
newTimeout = _tstoi( text );
|
||||||
|
|
||||||
if( g_RecordingFormat == RecordingFormat::GIF )
|
|
||||||
{
|
|
||||||
// Hardcode lower frame rate for GIFs
|
|
||||||
g_RecordFrameRate = 15;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_RecordFrameRate = g_FramerateOptions[SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0))];
|
|
||||||
}
|
|
||||||
|
|
||||||
g_RecordingFormat = static_cast<RecordingFormat>(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FORMAT), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0)));
|
g_RecordingFormat = static_cast<RecordingFormat>(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FORMAT), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0)));
|
||||||
|
g_RecordFrameRate = (g_RecordingFormat == RecordingFormat::GIF) ? RECORDING_FORMAT_GIF_DEFAULT_FRAMERATE : RECORDING_FORMAT_MP4_DEFAULT_FRAMERATE;
|
||||||
g_RecordScaling = static_cast<int>(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0)) * 10 + 10);
|
g_RecordScaling = static_cast<int>(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0)) * 10 + 10);
|
||||||
|
|
||||||
// Get the selected microphone
|
// Get the selected microphone
|
||||||
@@ -3536,7 +3531,16 @@ void StopRecording()
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
auto GetUniqueRecordingFilename()
|
auto GetUniqueRecordingFilename()
|
||||||
{
|
{
|
||||||
std::filesystem::path path{ g_RecordingSaveLocation };
|
std::filesystem::path path;
|
||||||
|
|
||||||
|
if (g_RecordingFormat == RecordingFormat::GIF)
|
||||||
|
{
|
||||||
|
path = g_RecordingSaveLocationGIF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = g_RecordingSaveLocation;
|
||||||
|
}
|
||||||
|
|
||||||
// Chop off index if it's there
|
// Chop off index if it's there
|
||||||
auto base = std::regex_replace( path.stem().wstring(), std::wregex( L" [(][0-9]+[)]$" ), L"" );
|
auto base = std::regex_replace( path.stem().wstring(), std::wregex( L" [(][0-9]+[)]$" ), L"" );
|
||||||
@@ -3591,6 +3595,7 @@ winrt::fire_and_forget StartRecordingAsync( HWND hWnd, LPRECT rcCrop, HWND hWndR
|
|||||||
auto stream = co_await file.OpenAsync( winrt::FileAccessMode::ReadWrite );
|
auto stream = co_await file.OpenAsync( winrt::FileAccessMode::ReadWrite );
|
||||||
|
|
||||||
// Create the appropriate recording session based on format
|
// Create the appropriate recording session based on format
|
||||||
|
OutputDebugStringW((L"Starting recording session. Framerate: " + std::to_wstring(g_RecordFrameRate) + L" scaling: " + std::to_wstring(g_RecordScaling) + L" Format: " + (g_RecordingFormat == RecordingFormat::GIF ? L"GIF" : L"MP4") + L"\n").c_str());
|
||||||
if (g_RecordingFormat == RecordingFormat::GIF)
|
if (g_RecordingFormat == RecordingFormat::GIF)
|
||||||
{
|
{
|
||||||
g_GifRecordingSession = GifRecordingSession::Create(
|
g_GifRecordingSession = GifRecordingSession::Create(
|
||||||
@@ -3657,18 +3662,44 @@ winrt::fire_and_forget StartRecordingAsync( HWND hWnd, LPRECT rcCrop, HWND hWndR
|
|||||||
saveDialog->SetFileTypes( _countof( fileTypes ), fileTypes );
|
saveDialog->SetFileTypes( _countof( fileTypes ), fileTypes );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( g_RecordingSaveLocation.size() == 0) {
|
// Peek the folder Windows has chosen to display
|
||||||
|
static std::filesystem::path lastSaveFolder;
|
||||||
|
wil::unique_cotaskmem_string chosenFolderPath;
|
||||||
|
wil::com_ptr<IShellItem> currentSelectedFolder;
|
||||||
|
bool bFolderChanged = false;
|
||||||
|
if (SUCCEEDED(saveDialog->GetFolder(currentSelectedFolder.put())))
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(currentSelectedFolder->GetDisplayName(SIGDN_FILESYSPATH, chosenFolderPath.put())))
|
||||||
|
{
|
||||||
|
if (lastSaveFolder != chosenFolderPath.get())
|
||||||
|
{
|
||||||
|
lastSaveFolder = chosenFolderPath.get() ? chosenFolderPath.get() : std::filesystem::path{};
|
||||||
|
bFolderChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (g_RecordingFormat == RecordingFormat::GIF && g_RecordingSaveLocationGIF.size() == 0) || (g_RecordingFormat == RecordingFormat::MP4 && g_RecordingSaveLocation.size() == 0) || (bFolderChanged)) {
|
||||||
|
|
||||||
wil::com_ptr<IShellItem> shellItem;
|
wil::com_ptr<IShellItem> shellItem;
|
||||||
wil::unique_cotaskmem_string folderPath;
|
wil::unique_cotaskmem_string folderPath;
|
||||||
if (SUCCEEDED(saveDialog->GetFolder(shellItem.put())) && SUCCEEDED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, folderPath.put())))
|
if (SUCCEEDED(saveDialog->GetFolder(shellItem.put())) && SUCCEEDED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, folderPath.put()))) {
|
||||||
g_RecordingSaveLocation = folderPath.get();
|
if (g_RecordingFormat == RecordingFormat::GIF) {
|
||||||
|
g_RecordingSaveLocationGIF = folderPath.get();
|
||||||
|
std::filesystem::path currentPath{ g_RecordingSaveLocationGIF };
|
||||||
|
g_RecordingSaveLocationGIF = currentPath / DEFAULT_GIF_RECORDING_FILE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_RecordingSaveLocation = folderPath.get();
|
||||||
|
if (g_RecordingFormat == RecordingFormat::MP4) {
|
||||||
|
std::filesystem::path currentPath{ g_RecordingSaveLocation };
|
||||||
|
g_RecordingSaveLocation = currentPath / DEFAULT_RECORDING_FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use appropriate default filename based on current format
|
// Always use appropriate default filename based on current format
|
||||||
std::filesystem::path currentPath{ g_RecordingSaveLocation };
|
|
||||||
const wchar_t* defaultFile = (g_RecordingFormat == RecordingFormat::GIF) ? DEFAULT_GIF_RECORDING_FILE : DEFAULT_RECORDING_FILE;
|
|
||||||
g_RecordingSaveLocation = currentPath.parent_path() / defaultFile;
|
|
||||||
auto suggestedName = GetUniqueRecordingFilename();
|
auto suggestedName = GetUniqueRecordingFilename();
|
||||||
saveDialog->SetFileName( suggestedName.c_str() );
|
saveDialog->SetFileName( suggestedName.c_str() );
|
||||||
|
|
||||||
@@ -3696,9 +3727,15 @@ winrt::fire_and_forget StartRecordingAsync( HWND hWnd, LPRECT rcCrop, HWND hWndR
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
co_await file.MoveAndReplaceAsync( destFile );
|
co_await file.MoveAndReplaceAsync(destFile);
|
||||||
g_RecordingSaveLocation = file.Path();
|
if (g_RecordingFormat == RecordingFormat::GIF) {
|
||||||
SaveToClipboard(g_RecordingSaveLocation.c_str(), hWnd);
|
g_RecordingSaveLocationGIF = file.Path();
|
||||||
|
SaveToClipboard(g_RecordingSaveLocationGIF.c_str(), hWnd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_RecordingSaveLocation = file.Path();
|
||||||
|
SaveToClipboard(g_RecordingSaveLocation.c_str(), hWnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_bSaveInProgress = false;
|
g_bSaveInProgress = false;
|
||||||
|
|
||||||
@@ -4039,8 +4076,10 @@ LRESULT APIENTRY MainWndProc(
|
|||||||
// Set g_RecordScaling based on the current recording format
|
// Set g_RecordScaling based on the current recording format
|
||||||
if (g_RecordingFormat == RecordingFormat::GIF) {
|
if (g_RecordingFormat == RecordingFormat::GIF) {
|
||||||
g_RecordScaling = g_RecordScalingGIF;
|
g_RecordScaling = g_RecordScalingGIF;
|
||||||
|
g_RecordFrameRate = RECORDING_FORMAT_GIF_DEFAULT_FRAMERATE;
|
||||||
} else {
|
} else {
|
||||||
g_RecordScaling = g_RecordScalingMP4;
|
g_RecordScaling = g_RecordScalingMP4;
|
||||||
|
g_RecordFrameRate = RECORDING_FORMAT_MP4_DEFAULT_FRAMERATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to support migrating from
|
// to support migrating from
|
||||||
@@ -6332,6 +6371,17 @@ LRESULT APIENTRY MainWndProc(
|
|||||||
{
|
{
|
||||||
// Reload the settings. This message is called from PowerToys after a setting is changed by the user.
|
// Reload the settings. This message is called from PowerToys after a setting is changed by the user.
|
||||||
reg.ReadRegSettings(RegSettings);
|
reg.ReadRegSettings(RegSettings);
|
||||||
|
|
||||||
|
if (g_RecordingFormat == RecordingFormat::GIF)
|
||||||
|
{
|
||||||
|
g_RecordScaling = g_RecordScalingGIF;
|
||||||
|
g_RecordFrameRate = RECORDING_FORMAT_GIF_DEFAULT_FRAMERATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_RecordScaling = g_RecordScalingMP4;
|
||||||
|
g_RecordFrameRate = RECORDING_FORMAT_MP4_DEFAULT_FRAMERATE;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply tray icon setting
|
// Apply tray icon setting
|
||||||
EnableDisableTrayIcon(hWnd, g_ShowTrayIcon);
|
EnableDisableTrayIcon(hWnd, g_ShowTrayIcon);
|
||||||
|
|||||||
Reference in New Issue
Block a user