diff --git a/.github/workflows/Linux-pack.yml b/.github/workflows/Linux-pack.yml index 9c202274eb..c3ad399a62 100644 --- a/.github/workflows/Linux-pack.yml +++ b/.github/workflows/Linux-pack.yml @@ -253,138 +253,119 @@ jobs: ${{ github.workspace }}/build/${{ env.PRODUCT }}-*-lp${{ matrix.dist.symbol }}.${{ matrix.dist.arch }}.rpm.sha256sum overwrite: true -# appimage-pack: -# name: Build appimage on ${{ matrix.config.name }} -# runs-on: ubuntu-latest -# strategy: -# fail-fast: false -# matrix: -# config: -# - { -# name: ubuntu-22.04, -# os: ubuntu, -# symbol: jammy, -# arch: amd64, -# image_repo: quay.io/flameshot-org/ci-building -# } -# container: -# image: ${{ matrix.config.image_repo }}:${{ matrix.config.os }}-${{ matrix.config.symbol }} -# options: --cap-add SYS_ADMIN --device /dev/fuse --security-opt apparmor:unconfined -# steps: -# - name: -# shell: bash -# run: | -# git config --global --add safe.directory "$GITHUB_WORKSPACE" -# -# - name: Checkout Source code -# if: github.event_name == 'push' -# uses: actions/checkout@v4 -# with: -# fetch-depth: 0 -# ref: master -# - name: Checkout Source code -# if: github.event_name == 'pull_request' -# uses: actions/checkout@v4 -# with: -# fetch-depth: 0 -# ref: ${{ github.event.pull_request.head.sha }} -# - name: Set env & Print flameshot version -# shell: bash -# run: | -# last_committed_tag=$(git tag -l --sort=-v:refname | head -1) -# git_revno=$(git rev-list $(git describe --tags --abbrev=0)..HEAD --count) -# git_hash=$(git rev-parse --short HEAD) -# ver_info=${last_committed_tag}+git${git_revno}.${git_hash} -# echo "=======FLAMESHOT VERSION========" -# echo ${last_committed_tag:1} -# echo "Details: ${ver_info}" -# echo "================================" -# echo "VERSION=${last_committed_tag:1}" >> $GITHUB_ENV -# echo "VER_INFO=${ver_info}" >> $GITHUB_ENV -# - name: Install Dependencies -# run: | -# sudo apt-get -y -qq update -# sudo apt-get -y --no-install-recommends install \ -# python3 \ -# python3-pip \ -# fuse \ -# patchelf \ -# cmake \ -# extra-cmake-modules \ -# build-essential \ -# qt5-qmake \ -# qtbase5-dev \ -# qtbase5-dev-tools \ -# qttools5-dev-tools \ -# qttools5-dev \ -# libqt5dbus5 \ -# libqt5network5 \ -# libqt5core5a \ -# libqt5widgets5 \ -# libqt5gui5 \ -# libqt5svg5-dev \ -# appstream \ -# hicolor-icon-theme \ -# fcitx-frontend-qt5 \ -# openssl \ -# ca-certificates \ -# jq -# -# - name: Get go-appimage tool -# # Will not use linuxdeployqt anymore, because it suopprts currently still-supported mainstream distribution, -# # which is glibc 2.23. For more information, please see https://github.com/probonopd/linuxdeployqt/issues/340. -# # Will try new tool https://github.com/probonopd/go-appimage written in golang by probonopd. -# run: | -# wget $(curl https://api.github.com/repos/probonopd/go-appimage/releases | jq -r '.[] | select(.tag_name == "continuous") | .assets[] | select((.name | endswith("x86_64.AppImage")) and (.name | contains("appimagetool"))) | .browser_download_url') -O appimagetool -# -# chmod +x appimagetool -# env: -# APPIMAGETOOL_ARCH: x86_64 -# - name: Packaging appimage -# run: | -# set -x -# APPIMAGE_DST_PATH=$GITHUB_WORKSPACE/${PRODUCT}.AppDir -# mkdir -p ${APPIMAGE_DST_PATH} -# -# cd $GITHUB_WORKSPACE -# cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr -DUSE_LAUNCHER_ABSOLUTE_PATH:BOOL=OFF -# make -j$(nproc) DESTDIR=${APPIMAGE_DST_PATH} install -# -# $GITHUB_WORKSPACE/appimagetool -s deploy "${APPIMAGE_DST_PATH}/usr/share/applications/org.flameshot.Flameshot.desktop" -# -# mkdir -p ${APPIMAGE_DST_PATH}/usr/plugins/platforminputcontexts -# cp \ -# /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so \ -# ${APPIMAGE_DST_PATH}/usr/plugins/platforminputcontexts/ -# -# cp \ -# $GITHUB_WORKSPACE/data/img/app/org.flameshot.Flameshot.png \ -# ${APPIMAGE_DST_PATH}/ -# -# if [ -f "${APPIMAGE_DST_PATH}/lib/x86_64-linux-gnu/libxcb-glx.so.0" ]; then -# rm ${APPIMAGE_DST_PATH}/lib/x86_64-linux-gnu/libxcb-glx.so.0 -# fi -# -# chmod +x ${APPIMAGE_DST_PATH}/usr/lib64/ld-*.so.* -# -# -# VERSION=${VERSION} $GITHUB_WORKSPACE/appimagetool "${APPIMAGE_DST_PATH}" -# mv $GITHUB_WORKSPACE/Flameshot-${VERSION}-x86_64.AppImage $GITHUB_WORKSPACE/Flameshot-${VERSION}.x86_64.AppImage -# -# -# - name: SHA256Sum of appimage package -# run: | -# cd "$GITHUB_WORKSPACE/" || { >&2 echo "Cannot cd to '$GITHUB_WORKSPACE/'!"; exit 11 ; } -# sha256sum Flameshot-${VERSION}.x86_64.AppImage | tee Flameshot-${VERSION}.x86_64.AppImage.sha256sum -# - name: Artifact Upload -# uses: actions/upload-artifact@v4 -# with: -# name: ${{ env.PRODUCT }}-${{ env.VER_INFO }}-artifact-appimage-x86_64 -# path: | -# ${{ github.workspace }}/Flameshot-*.x86_64.AppImage -# ${{ github.workspace }}/Flameshot-*.x86_64.AppImage.sha256sum -# overwrite: true -# + appimage-pack: + name: Build appimage on ${{ matrix.config.name }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + config: + - { + name: ubuntu-22.04, + os: ubuntu, + symbol: jammy, + arch: amd64, + image_repo: quay.io/flameshot-org/ci-building + } + container: + image: ${{ matrix.config.image_repo }}:${{ matrix.config.os }}-${{ matrix.config.symbol }} + options: --cap-add SYS_ADMIN --device /dev/fuse --security-opt apparmor:unconfined + steps: + - name: Configure git safe directory + shell: bash + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Checkout Source code + if: github.event_name == 'push' + uses: actions/checkout@v4 + with: + fetch-depth: 0 +# ref: master + + - name: Checkout Source code + if: github.event_name == 'pull_request' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Checkout Source code + if: github.event_name == 'workflow_dispatch' + uses: actions/checkout@v4 + with: + ref: ${{ github.sha }} + + - name: Set env & Print flameshot version + shell: bash + run: | + last_committed_tag=$(git tag -l --sort=-v:refname | head -1) + git_revno=$(git rev-list $(git describe --tags --abbrev=0)..HEAD --count) + git_hash=$(git rev-parse --short HEAD) + ver_info=${last_committed_tag}+git${git_revno}.${git_hash} + echo "=======FLAMESHOT VERSION========" + echo ${last_committed_tag:1} + echo "Details: ${ver_info}" + echo "================================" + # This will allow to build pre-preleases without git tag + # echo "VERSION=${last_committed_tag:1}" >> $GITHUB_ENV + echo "VERSION=$(cat CMakeLists.txt |grep 'set.*(.*FLAMESHOT_VERSION' | sed 's/[^0-9.]*//' |sed 's/)//g')" >> $GITHUB_ENV + echo "VER_INFO=${ver_info}" >> $GITHUB_ENV + + - name: Install Dependencies + run: | + sudo apt-get -y -qq update + sudo apt-get -y --no-install-recommends install fuse cmake extra-cmake-modules build-essential qt6-base-dev qt6-tools-dev qt6-tools-dev-tools libqt6svg6-dev qt6-l10n-tools qt6-wayland libgl-dev appstream hicolor-icon-theme openssl ca-certificates jq + + - name: Download linuxdeploy + run: | + wget -c -nv "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" + chmod a+x linuxdeploy-x86_64.AppImage + LINUXDEPLOY_BIN=${PWD}/linuxdeploy-x86_64.AppImage + + - name: Download linuxdeployqt-plugin-appimage + run: | + wget -c -nv "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage" + chmod a+x linuxdeploy-plugin-appimage-x86_64.AppImage + + - name: Download linuxdeployqt-plugin-qt + run: | + wget -c -nv "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage" + chmod a+x linuxdeploy-plugin-qt-x86_64.AppImage + + - name: Packaging appimage + run: | + set -x + APPIMAGE_DST_PATH=$GITHUB_WORKSPACE/${PRODUCT}.AppDir + mkdir -p ${APPIMAGE_DST_PATH} + + cd $GITHUB_WORKSPACE + cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr -DUSE_LAUNCHER_ABSOLUTE_PATH:BOOL=OFF + make -j$(nproc) DESTDIR=${APPIMAGE_DST_PATH} install + rm -rf ${APPIMAGE_DST_PATH}/usr/include + rm -rf ${APPIMAGE_DST_PATH}/usr/lib + + export EXTRA_PLATFORM_PLUGINS="libqwayland-generic.so" + export EXTRA_QT_MODULES="waylandcompositor" + export QMAKE=/usr/lib/qt6/bin/qmake + ${PWD}/linuxdeploy-x86_64.AppImage --appdir ${APPIMAGE_DST_PATH} --plugin qt --output appimage + + mv $GITHUB_WORKSPACE/Flameshot-${VERSION}-x86_64.AppImage $GITHUB_WORKSPACE/Flameshot-${VERSION}.x86_64.AppImage + + - name: SHA256Sum of appimage package + run: | + cd "$GITHUB_WORKSPACE/" || { >&2 echo "Cannot cd to '$GITHUB_WORKSPACE/'!"; exit 11 ; } + sha256sum Flameshot-${VERSION}.x86_64.AppImage | tee Flameshot-${VERSION}.x86_64.AppImage.sha256sum + + - name: Artifact Upload + uses: actions/upload-artifact@v4 + with: + name: ${{ env.PRODUCT }}-${{ env.VER_INFO }}-artifact-appimage-x86_64 + path: | + ${{ github.workspace }}/Flameshot-*.x86_64.AppImage + ${{ github.workspace }}/Flameshot-*.x86_64.AppImage.sha256sum + overwrite: true + flatpak-pack: name: Build flatpak on ubuntu 24.04 runs-on: ubuntu-24.04 diff --git a/src/utils/screengrabber.cpp b/src/utils/screengrabber.cpp index ba8b86c922..cdbc598497 100644 --- a/src/utils/screengrabber.cpp +++ b/src/utils/screengrabber.cpp @@ -205,11 +205,30 @@ QPixmap ScreenGrabber::grabEntireDesktop(bool& ok) #endif #if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) || defined(Q_OS_WIN) QRect geometry = desktopGeometry(); - QPixmap p(QApplication::primaryScreen()->grabWindow( - wid, geometry.x(), geometry.y(), geometry.width(), geometry.height())); - QScreen* screen = qApp->screenAt(QCursor::pos()); - p.setDevicePixelRatio(screen->devicePixelRatio()); - return p; + + // Qt6 fix: Create a composite image from all screens to handle + // multi-monitor setups where screens have different positions/heights. + // This fixes the dual monitor offset bug and handles edge cases where + // the desktop bounding box includes virtual space. + QPixmap desktop(geometry.size()); + desktop.fill(Qt::black); // Fill with black background + + QPainter painter(&desktop); + for (QScreen* screen : QGuiApplication::screens()) { + QRect screenGeom = screen->geometry(); + QPixmap screenCapture = screen->grabWindow( + wid, 0, 0, screenGeom.width(), screenGeom.height()); + + // Calculate position relative to desktop top-left + QPoint relativePos = screenGeom.topLeft() - geometry.topLeft(); + painter.drawPixmap(relativePos, screenCapture); + } + painter.end(); + + // Set device pixel ratio based on the primary screen + desktop.setDevicePixelRatio( + QApplication::primaryScreen()->devicePixelRatio()); + return desktop; #endif } @@ -259,8 +278,9 @@ QRect ScreenGrabber::desktopGeometry() for (QScreen* const screen : QGuiApplication::screens()) { QRect scrRect = screen->geometry(); - scrRect.moveTo(scrRect.x() / screen->devicePixelRatio(), - scrRect.y() / screen->devicePixelRatio()); + // Qt6 fix: Don't divide by devicePixelRatio for multi-monitor setups + // This was causing coordinate offset issues in dual monitor + // configurations geometry = geometry.united(scrRect); } return geometry; diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index c765801865..3426bb9716 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -155,7 +155,11 @@ CaptureWidget::CaptureWidget(const CaptureRequest& req, #if !defined(FLAMESHOT_DEBUG_CAPTURE) setWindowFlags(Qt::BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool); - resize(pixmap().size()); + // Fix for Qt6 dual monitor offset: position widget to cover entire + // desktop + QRect desktopGeom = ScreenGrabber().desktopGeometry(); + move(desktopGeom.topLeft()); + resize(desktopGeom.size()); #endif #endif }