From 3ef401cd9a6e0b9e8dfdc7cdef952fc9e1804437 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 22 Sep 2023 00:43:30 +0200 Subject: [PATCH] ScreenRecorder: Decouple capture type from host OS On Linux, we want to support more screen capture options than just x11grab. Also, on Windows, we might want to support alternatives to ddagrab. This change replaces host OS specific control flow with a setting based one. If there are multiple capture types available for an OS (not the case with this initial change), a combobox in the settings page allows the user to select one. Change-Id: Ic57be4a47d14f09f53635e53167aa20a5d74669b Reviewed-by: Cristian Adam --- src/plugins/screenrecorder/record.cpp | 10 +++---- .../screenrecorder/screenrecordersettings.cpp | 30 ++++++++++++++++++- .../screenrecorder/screenrecordersettings.h | 7 +++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/plugins/screenrecorder/record.cpp b/src/plugins/screenrecorder/record.cpp index e1360ffd109..76013b09311 100644 --- a/src/plugins/screenrecorder/record.cpp +++ b/src/plugins/screenrecorder/record.cpp @@ -324,9 +324,9 @@ QStringList RecordWidget::ffmpegParameters(const ClipInfo &clipInfo) const const QString screenIdStr = QString::number(rS.screenId); const QString captureCursorStr = Internal::settings().captureCursor() ? "1" : "0"; QStringList videoGrabParams; - // see http://trac.ffmpeg.org/wiki/Capture/Desktop - switch (HostOsInfo::hostOs()) { - case OsTypeLinux: { + + switch (Internal::settings().captureType()) { + case Internal::CaptureType::X11grab: { const QScreen *screen = QGuiApplication::screens()[rS.screenId]; const QPoint screenTopLeft = screen->geometry().topLeft(); const QRect cropRect = rS.cropRect.translated(screenTopLeft); @@ -342,7 +342,7 @@ QStringList RecordWidget::ffmpegParameters(const ClipInfo &clipInfo) const .arg(cropRect.x()).arg(cropRect.y())}); break; } - case OsTypeWindows: { + case Internal::CaptureType::Ddagrab: { QString filter = "ddagrab=output_idx=" + screenIdStr; if (!rS.cropRect.isNull()) { filter.append(":video_size=" + sizeStr(rS.cropRect.size())); @@ -359,7 +359,7 @@ QStringList RecordWidget::ffmpegParameters(const ClipInfo &clipInfo) const }; break; } - case OsTypeMac: { + case Internal::CaptureType::AVFoundation: { videoGrabParams = { "-f", "avfoundation", "-capture_cursor", captureCursorStr, diff --git a/src/plugins/screenrecorder/screenrecordersettings.cpp b/src/plugins/screenrecorder/screenrecordersettings.cpp index 2dec4000873..ef914616a96 100644 --- a/src/plugins/screenrecorder/screenrecordersettings.cpp +++ b/src/plugins/screenrecorder/screenrecordersettings.cpp @@ -76,7 +76,30 @@ ScreenRecorderSettings::ScreenRecorderSettings() captureMouseClicks.setDefaultValue(false); captureMouseClicks.setLabel(Tr::tr("Capture the screen mouse clicks")); captureMouseClicks.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox); - captureMouseClicks.setVisible(HostOsInfo::isMacHost()); // only available with AVFoundation + + captureType.setSettingsKey("CaptureType"); + captureType.setLabelText(Tr::tr("Capture device/filter:")); + captureType.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox); + captureType.setVisible(false); + switch (HostOsInfo::hostOs()) { + case OsTypeLinux: + captureType.addOption({"x11grab", {}, CaptureType::X11grab}); + captureType.setDefaultValue(CaptureType::X11grab); + break; + case OsTypeWindows: + captureType.addOption({"ddagrab", {}, CaptureType::Ddagrab}); + captureType.setDefaultValue(CaptureType::Ddagrab); + break; + case OsTypeMac: + captureType.addOption({"AVFoundation", {}, CaptureType::AVFoundation}); + captureType.setDefaultValue(CaptureType::AVFoundation); + break; + } + auto setCaptureMouseClicksVisible = [this] { + const QVariant value = captureType.itemValueForIndex(captureType.volatileValue()); + const bool visible = value.toInt() == CaptureType::AVFoundation; + captureMouseClicks.setVisible(visible); + }; enableFileSizeLimit.setSettingsKey("EnableFileSizeLimit"); enableFileSizeLimit.setDefaultValue(true); @@ -161,6 +184,7 @@ ScreenRecorderSettings::ScreenRecorderSettings() Column { captureCursor, captureMouseClicks, + Row { captureType, st }, Row { enableFileSizeLimit, fileSizeLimit, st }, Row { enableRtBuffer, rtBufferSize, st }, }, @@ -178,6 +202,10 @@ ScreenRecorderSettings::ScreenRecorderSettings() }); readSettings(); + + setCaptureMouseClicksVisible(); + connect(&captureType, &SelectionAspect::volatileValueChanged, this, + setCaptureMouseClicksVisible); } bool ScreenRecorderSettings::toolsRegistered() const diff --git a/src/plugins/screenrecorder/screenrecordersettings.h b/src/plugins/screenrecorder/screenrecordersettings.h index 18611ce5830..dbdda8311c9 100644 --- a/src/plugins/screenrecorder/screenrecordersettings.h +++ b/src/plugins/screenrecorder/screenrecordersettings.h @@ -7,6 +7,12 @@ namespace ScreenRecorder::Internal { +enum CaptureType { + X11grab, + Ddagrab, + AVFoundation, +}; + class ScreenRecorderSettings : public Utils::AspectContainer { public: @@ -26,6 +32,7 @@ public: // Visible in Settings page Utils::FilePathAspect ffmpegTool{this}; Utils::FilePathAspect ffprobeTool{this}; + Utils::SelectionAspect captureType{this}; Utils::BoolAspect captureCursor{this}; Utils::BoolAspect captureMouseClicks{this}; Utils::BoolAspect enableFileSizeLimit{this};