diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 920c0baa..9de3e870 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -49,9 +49,9 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - version: '6.5.3' + version: '6.8.1' modules: 'qtwebsockets qtserialport qtmultimedia' - aqtversion: ==3.1.7 + aqtversion: '==3.1.20' - name: Install prerequisites run: | @@ -84,7 +84,7 @@ jobs: run: | git fetch --tags --force sed -i 's/--long --dirty/--long/g' ./tools/generate_info.sh - sed -i 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.5.3\/gcc_64/g' build_deb.sh + sed -i 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.8.1\/gcc_64/g' build_deb.sh sed -i 's/LIBSSH2_DIR=\/libssh2/LIBSSH2_DIR=\/usr\/local\/output/g' ./lib/qtssh/qtssh.pri mkdir prebuilt_plugins python3 ./.github/scripts/get_plugin.py ./.github/scripts/plugin_list.json ./prebuilt_plugins diff --git a/.github/workflows/linux_appimage.yml b/.github/workflows/linux_appimage.yml index 9db59727..935987e9 100644 --- a/.github/workflows/linux_appimage.yml +++ b/.github/workflows/linux_appimage.yml @@ -49,9 +49,9 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - version: '6.5.3' + version: '6.8.1' modules: 'qtwebsockets qtserialport qtmultimedia' - aqtversion: ==3.1.7 + aqtversion: '==3.1.20' - name: Install prerequisites run: | @@ -84,7 +84,7 @@ jobs: run: | git fetch --tags --force sed -i 's/--long --dirty/--long/g' ./tools/generate_info.sh - sed -i 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.5.3\/gcc_64/g' build_AppImage.sh + sed -i 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.8.1\/gcc_64/g' build_AppImage.sh sed -i 's/LIBSSH2_DIR=\/libssh2/LIBSSH2_DIR=\/usr\/local\/output/g' ./lib/qtssh/qtssh.pri mkdir prebuilt_plugins python3 ./.github/scripts/get_plugin.py ./.github/scripts/plugin_list.json ./prebuilt_plugins diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c86b896f..23f978f8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -49,9 +49,9 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - version: '6.5.3' + version: '6.8.1' modules: 'qtwebsockets qtserialport qtmultimedia' - aqtversion: ==3.1.7 + aqtversion: '==3.1.20' - name: Install prerequisites run: | @@ -76,7 +76,7 @@ jobs: run: | git fetch --tags --force sed -i'.original' -e 's/--long --dirty/--long/g' ./tools/generate_info.sh - sed -i'.original' -e 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.5.3\/macos/g' build_dmg.sh + sed -i'.original' -e 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.8.1\/macos/g' build_dmg.sh sed -i'.original' -e 's/LIBSSH2_DIR=\/libssh2/LIBSSH2_DIR=\/usr\/local\/output/g' ./lib/qtssh/qtssh.pri mkdir prebuilt_plugins python3 ./.github/scripts/get_plugin.py ./.github/scripts/plugin_list.json ./prebuilt_plugins diff --git a/.github/workflows/macos_arm64.yml b/.github/workflows/macos_arm64.yml index 796def16..adfee0cb 100644 --- a/.github/workflows/macos_arm64.yml +++ b/.github/workflows/macos_arm64.yml @@ -49,9 +49,9 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - version: '6.5.3' + version: '6.8.1' modules: 'qtwebsockets qtserialport qtmultimedia' - aqtversion: ==3.1.7 + aqtversion: '==3.1.20' - name: Install prerequisites run: | @@ -76,7 +76,7 @@ jobs: run: | git fetch --tags --force sed -i'.original' -e 's/--long --dirty/--long/g' ./tools/generate_info.sh - sed -i'.original' -e 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.5.3\/macos/g' build_dmg.sh + sed -i'.original' -e 's/QT_DIR=\/opt\/Qt6.2.0\/6.2.0\/gcc_64/QT_DIR=$(cd "$(dirname "$0")";pwd)\/..\/Qt\/6.8.1\/macos/g' build_dmg.sh sed -i'.original' -e 's/LIBSSH2_DIR=\/libssh2/LIBSSH2_DIR=\/usr\/local\/output/g' ./lib/qtssh/qtssh.pri mkdir prebuilt_plugins python3 ./.github/scripts/get_plugin.py ./.github/scripts/plugin_list.json ./prebuilt_plugins diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index dd20e80f..cfd36261 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -50,9 +50,9 @@ jobs: uses: jurplel/install-qt-action@v4 with: arch: win64_mingw - version: '6.5.3' + version: '6.8.1' modules: 'qtwebsockets qtserialport qtmultimedia' - aqtversion: ==3.1.7 + aqtversion: '==3.1.19' - name: Install cmake uses: crazy-max/ghaction-chocolatey@v3 diff --git a/.github/workflows/windows_msvc.yml b/.github/workflows/windows_msvc.yml index 7cf6ad99..4d59c245 100644 --- a/.github/workflows/windows_msvc.yml +++ b/.github/workflows/windows_msvc.yml @@ -40,7 +40,7 @@ on: workflow_dispatch: jobs: - windows_msvc2019: + windows_msvc2022: runs-on: windows-2022 steps: @@ -49,10 +49,10 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@v4 with: - arch: 'win64_msvc2019_64' - version: '6.5.3' + arch: 'win64_msvc2022_64' + version: '6.8.1' modules: 'qtwebsockets qtserialport qtmultimedia' - aqtversion: '==3.1.7' + aqtversion: '==3.1.19' - name: Install cmake uses: crazy-max/ghaction-chocolatey@v3 @@ -81,7 +81,6 @@ jobs: uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 - toolset: 14.29 - name: Install libssh2 run: | @@ -111,7 +110,7 @@ jobs: - name: Upload build asserts uses: actions/upload-artifact@v4 with: - name: quardCRT_windows_msvc2019 + name: quardCRT_windows_msvc2022 path: | ./output/*.exe diff --git a/depend/build_fcitx_qt6_linux.sh b/depend/build_fcitx_qt6_linux.sh index e06b1ede..b1e4670f 100755 --- a/depend/build_fcitx_qt6_linux.sh +++ b/depend/build_fcitx_qt6_linux.sh @@ -3,9 +3,9 @@ set -e # ubuntu20.04 need install # sudo apt install fcitx-libs-dev qtbase5-private-dev libxkbcommon-dev extra-cmake-modules -# export PATH="~/Qt/6.5.3/gcc_64/bin":$PATH +# export PATH="~/Qt/6.8.1/gcc_64/bin":$PATH # export PATH="~/Qt/Tools/CMake/bin":$PATH -# export Qt6GuiTools_DIR=/home/qqm/Qt/6.5.3/gcc_64 +# export Qt6GuiTools_DIR=/home/qqm/Qt/6.8.1/gcc_64 SHELL_FOLDER=$(cd "$(dirname "$0")";pwd) tar -xzvf fcitx-qt5-1.2.7.tar.gz cd $SHELL_FOLDER/fcitx-qt5-1.2.7 diff --git a/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.cpp b/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.cpp index 23b7c2aa..4987a8ad 100644 --- a/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.cpp +++ b/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.cpp @@ -657,7 +657,7 @@ void QGoodWindow::setup() #endif #ifdef Q_OS_LINUX - qputenv("XDG_SESSION_TYPE", "xcb"); + qputenv("XDG_SESSION_TYPE", "x11"); qputenv("QT_QPA_PLATFORM", "xcb"); int argc = 0; diff --git a/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.h b/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.h index 968d8157..37d6d257 100644 --- a/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.h +++ b/lib/QGoodWindow/QGoodWindow/src/qgoodwindow.h @@ -43,6 +43,7 @@ namespace QGoodWindowUtils { class NativeEventFilter; } +#include #endif #if defined Q_OS_WIN || defined Q_OS_LINUX diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 96050871..cd0e627d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -90,6 +90,13 @@ CentralWidget::CentralWidget(QString dir, StartupUIMode mode, QLocale lang, bool pyRun = new PyRun(this); #endif + m_mediaCaptureSession = new QMediaCaptureSession(this); + m_windowCapture = new QWindowCapture(this); + m_mediaRecorder = new QMediaRecorder(this); + m_mediaCaptureSession->setWindowCapture(m_windowCapture); + m_mediaCaptureSession->setRecorder(m_mediaRecorder); + m_mediaRecorder->setQuality(QMediaRecorder::HighQuality); + splitter = new QSplitter(Qt::Horizontal,this); splitter->setHandleWidth(1); ui->centralwidget->layout()->addWidget(splitter); @@ -1710,6 +1717,9 @@ void CentralWidget::menuAndToolBarRetranslateUi(void) { screenShotAction->setIcon(QFontIcon::icon(QChar(0xf03e))); screenShotAction->setStatusTip(tr("Screen shot current screen ")); screenShotAction->setShortcut(QKeySequence(Qt::ALT|Qt::Key_P)); + screenCapturableAction->setText(tr("Screen Capturable")); + screenCapturableAction->setStatusTip(tr("Screen capturable current screen")); + screenCapturableAction->setShortcut(QKeySequence(Qt::ALT|Qt::Key_G)); sessionExportAction->setText(tr("Session Export")); sessionExportAction->setIcon(QFontIcon::icon(QChar(0xf093))); sessionExportAction->setStatusTip(tr("Export current session to a file ")); @@ -2035,6 +2045,9 @@ void CentralWidget::menuAndToolBarInit(bool disable_plugin) { ui->toolBar->addAction(printScreenAction); screenShotAction = new QAction(this); editMenu->addAction(screenShotAction); + screenCapturableAction = new QAction(this); + screenCapturableAction->setCheckable(true); + editMenu->addAction(screenCapturableAction); sessionExportAction = new QAction(this); editMenu->addAction(sessionExportAction); editMenu->addSeparator(); @@ -2604,6 +2617,7 @@ void CentralWidget::setSessionClassActionEnable(bool enable) findAction->setEnabled(enable); printScreenAction->setEnabled(enable); screenShotAction->setEnabled(enable); + screenCapturableAction->setEnabled(enable); sessionExportAction->setEnabled(enable); clearScrollbackAction->setEnabled(enable); clearScreenAction->setEnabled(enable); @@ -2928,6 +2942,48 @@ void CentralWidget::menuAndToolBarConnectSignals(void) { settings.setValue("Global/Options/ScreenShotPath",QFileInfo(fileName).absolutePath()); ui->statusBar->showMessage(tr("Screenshot saved to %1").arg(fileName),3000); }); + connect(screenCapturableAction,&QAction::triggered,this,[=](){ + if(!screenCapturableAction->isChecked()) { + m_mediaRecorder->stop(); + m_windowCapture->stop(); + ui->statusBar->showMessage(tr("ScreenCapturable stop."),3000); + } else { + QWidget *widget = findCurrentFocusWidget(); + if(widget == nullptr) return; + + QList windowList = QWindowCapture::capturableWindows(); + bool find = false; + foreach(const QCapturableWindow &w, windowList) { + auto handle = QCapturableWindowPrivate::handle(w); + if(handle && handle->id == this->mainWindow->winId()) { + m_windowCapture->setWindow(w); + find = true; + break; + } + } + if(!find) { + screenCapturableAction->setChecked(false); + return; + } + + GlobalSetting settings; + QString screenCapturablePath = settings.value("Global/Options/ScreenCapturablePath",QDir::homePath()).toString(); + QString willsaveName = screenCapturablePath + "/quartCRT-" + QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + ".mp4"; + QString fileName = FileDialog::getSaveFileName(this,tr("Save Screenshot"),willsaveName,tr("Video Files (*.mp4)")); + if(fileName.isEmpty()) { + screenCapturableAction->setChecked(false); + return; + } + if(!fileName.endsWith(".mp4")) fileName.append(".mp4"); + + m_mediaRecorder->setOutputLocation(QUrl::fromLocalFile(fileName)); + m_windowCapture->start(); + m_mediaRecorder->record(); + + settings.setValue("Global/Options/ScreenCapturablePath",QFileInfo(fileName).absolutePath()); + ui->statusBar->showMessage(tr("ScreenCapturable saved to %1").arg(fileName),3000); + } + }); connect(sessionExportAction,&QAction::triggered,this,[=](){ QWidget *widget = findCurrentFocusWidget(); if(widget == nullptr) return; diff --git a/src/mainwindow.h b/src/mainwindow.h index d96e3cd5..31cf51ab 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -34,6 +34,9 @@ #include #include #include +#include +#include +#include #include "mainwidgetgroup.h" #include "sessiontab.h" @@ -337,6 +340,7 @@ private slots: QAction *findAction; QAction *printScreenAction; QAction *screenShotAction; + QAction *screenCapturableAction; QAction *sessionExportAction; QAction *clearScrollbackAction; QAction *clearScreenAction; @@ -443,6 +447,10 @@ private slots: QShortcut *shortcutConnectAddressEdit; QShortcut *shortcutExitFullScreen; + QMediaCaptureSession *m_mediaCaptureSession; + QWindowCapture *m_windowCapture; + QMediaRecorder *m_mediaRecorder; + QLabel *statusBarMessage; StatusBarWidget *statusBarWidget; QTimer *statusBarWidgetRefreshTimer; @@ -529,4 +537,19 @@ class MainWindow : public QGoodWindow CentralWidget *m_central_widget; }; +class QCapturableWindowPrivate : public QSharedData { +public: + using Id = size_t; + + QString description; + Id id = 0; + + static const QCapturableWindowPrivate *handle(const QCapturableWindow &window) + { + return window.d.get(); + } + + QCapturableWindow create() { return QCapturableWindow(this); } +}; + #endif // MAINWINDOW_H