Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/core/UBApplicationController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,19 @@ void UBApplicationController::hideDesktop()
emit desktopMode(false);
}

void UBApplicationController::showGlassPane(bool show)
{
if (isShowingDesktop())
{
uninotesController()->drawingView()->setVisible(show);

if (show)
{
UBPlatformUtils::keepOnTop();
}
}
}

void UBApplicationController::setMirrorSourceWidget(QWidget* pWidget)
{
if (mMirror)
Expand Down
2 changes: 1 addition & 1 deletion src/core/UBApplicationController.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ class UBApplicationController : public QObject

// defaulting to false to match QAction triggered(bool checked = false)
void showDesktop(bool dontSwitchFrontProcess = false);

void hideDesktop();
void showGlassPane(bool show);

void useMultiScreen(bool use);

Expand Down
9 changes: 2 additions & 7 deletions src/core/UBDisplayManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,18 +672,13 @@ qreal UBDisplayManager::logicalDpi(ScreenRole role) const
return scr ? scr->logicalDotsPerInch() : 96.;
}

void UBDisplayManager::grab(ScreenRole role, std::function<void (QPixmap)> callback, QRect rect) const
void UBDisplayManager::grab(ScreenRole role, std::function<void (QPixmap)> callback, bool crop) const
{
QScreen* scr = screen(role);

if (scr)
{
if (!rect.isValid())
{
rect = QRect(QPoint(0, 0), scr->geometry().size());
}

UBPlatformUtils::grabScreen(scr, callback, rect);
UBPlatformUtils::grabScreen(scr, callback, crop);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/UBDisplayManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class UBDisplayManager : public QObject
qreal physicalDpi(ScreenRole role) const;
qreal logicalDpi(ScreenRole role) const;

void grab(ScreenRole role, std::function<void(QPixmap)> callback, QRect rect = {}) const;
void grab(ScreenRole role, std::function<void(QPixmap)> callback, bool crop = false) const;
QPixmap grabGlobal(QRect rect) const;

void initScreensByRole();
Expand Down
27 changes: 8 additions & 19 deletions src/desktop/UBDesktopAnnotationController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,13 +359,7 @@ void UBDesktopAnnotationController::showWindow()

UBDrawingController::drawingController()->setStylusTool(mDesktopStylusTool);

#ifndef Q_OS_LINUX
UBPlatformUtils::showFullScreen(mTransparentDrawingView);
#else
// this is necessary to avoid hiding the panels on Unity and Cinnamon
// if finer control is necessary, use qgetenv("XDG_CURRENT_DESKTOP")
mTransparentDrawingView->show();
#endif
UBPlatformUtils::hideMenuBarAndDock();

mDesktopPalette->appear();
Expand Down Expand Up @@ -470,7 +464,9 @@ void UBDesktopAnnotationController::customCapture()

mDesktopPalette->disappearForCapture();

getScreenPixmap([this](QPixmap pixmap){
const auto grabCanCrop = UBPlatformUtils::grabCanCrop();

getScreenPixmap([this, grabCanCrop](QPixmap pixmap){
auto finishCapture = [this](){
mDesktopPalette->appear();
mCustomCaptureClicked = false;
Expand All @@ -481,7 +477,7 @@ void UBDesktopAnnotationController::customCapture()
QPixmap screenshot = pixmap.isNull() ? clipboardScreenshot() : pixmap;

// On Wayland with xdg-desktop-portal, the user already chose the area.
if (UBPlatformUtils::sessionType() == UBPlatformUtils::WAYLAND && !screenshot.isNull())
if (grabCanCrop && !screenshot.isNull())
{
emit imageCaptured(screenshot, false);
finishCapture();
Expand All @@ -497,7 +493,7 @@ void UBDesktopAnnotationController::customCapture()
}

finishCapture();
});
}, grabCanCrop);
}
}

Expand All @@ -519,22 +515,15 @@ void UBDesktopAnnotationController::screenCapture()

QPixmap screenshot = pixmap.isNull() ? clipboardScreenshot() : pixmap;

if (UBPlatformUtils::sessionType() == UBPlatformUtils::WAYLAND && !screenshot.isNull())
{
emit imageCaptured(screenshot, false);
finishCapture();
return;
}

emit imageCaptured(screenshot, false);
finishCapture();
});
}, false);
}


void UBDesktopAnnotationController::getScreenPixmap(std::function<void(QPixmap)> callback)
void UBDesktopAnnotationController::getScreenPixmap(std::function<void(QPixmap)> callback, bool crop)
{
UBApplication::displayManager->grab(ScreenRole::Control, callback);
UBApplication::displayManager->grab(ScreenRole::Control, callback, crop);
}


Expand Down
2 changes: 1 addition & 1 deletion src/desktop/UBDesktopAnnotationController.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class UBDesktopAnnotationController : public QObject
void restoreUniboard();

protected:
void getScreenPixmap(std::function<void (QPixmap)> callback);
void getScreenPixmap(std::function<void (QPixmap)> callback, bool crop);

UBBoardView* mTransparentDrawingView;
std::shared_ptr<UBGraphicsScene> mTransparentDrawingScene;
Expand Down
12 changes: 8 additions & 4 deletions src/frameworks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ target_sources(openboard PRIVATE

if(CMAKE_SYSTEM_NAME STREQUAL Linux)
target_sources(openboard PRIVATE
UBDesktopPortal.cpp
UBDesktopPortal.h
UBPipewireSink.cpp
UBPipewireSink.h
linux/UBScreenCastDesktopPortalWrapper.cpp
linux/UBScreenCastDesktopPortalWrapper.h
linux/UBScreenshotDesktopPortalWrapper.cpp
linux/UBScreenshotDesktopPortalWrapper.h
linux/UBDesktopPortalTokenGenerator.cpp
linux/UBDesktopPortalTokenGenerator.h
linux/UBPipewireSink.cpp
linux/UBPipewireSink.h
UBPlatformUtils_linux.cpp
)
endif()
3 changes: 2 additions & 1 deletion src/frameworks/UBPlatformUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ class UBPlatformUtils
static void setFrontProcess();
static void showFullScreen(QWidget * pWidget);
static void showOSK(bool show);
static void grabScreen(QScreen* screen, std::function<void(QPixmap)> callback, QRect rect = {});
static void grabScreen(QScreen* screen, std::function<void(QPixmap)> callback, bool crop = false);
static bool grabCanCrop();

#ifdef Q_OS_OSX
static void SetMacLocaleByIdentifier(const QString& id);
Expand Down
55 changes: 48 additions & 7 deletions src/frameworks/UBPlatformUtils_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

#include <unistd.h>

#include "frameworks/UBDesktopPortal.h"
#include "frameworks/linux/UBScreenshotDesktopPortalWrapper.h"
#include "frameworks/UBFileSystemUtils.h"
#include "core/UBApplication.h"
#include "core/UBDisplayManager.h"
Expand All @@ -45,6 +45,40 @@

static OnboardListener* listener = nullptr;

// utility function to detect desktop environment
enum DesktopEnvironment
{
UNKNOWN,
GNOME,
KDE,
OTHER
};

static DesktopEnvironment desktopEnvironment()
{
static DesktopEnvironment desktop{UNKNOWN};

if (desktop == UNKNOWN)
{
const auto xdgCurrentDesktop{QProcessEnvironment::systemEnvironment().value("XDG_CURRENT_DESKTOP", "")};

if (xdgCurrentDesktop.compare("gnome", Qt::CaseInsensitive) == 0)
{
desktop = GNOME;
}
else if (xdgCurrentDesktop.compare("kde", Qt::CaseInsensitive) == 0)
{
desktop = KDE;
}
else
{
desktop = OTHER;
}
}

return desktop;
}

void UBPlatformUtils::init()
{
initializeKeyboardLayouts();
Expand Down Expand Up @@ -535,28 +569,33 @@ void UBPlatformUtils::showOSK(bool show)
}
}

void UBPlatformUtils::grabScreen(QScreen* screen, std::function<void (QPixmap)> callback, QRect rect)
void UBPlatformUtils::grabScreen(QScreen* screen, std::function<void (QPixmap)> callback, bool crop)
{
if (sessionType() == WAYLAND)
{
UBDesktopPortal* portal = new UBDesktopPortal;
auto* portal = new UBScreenshotDesktopPortalWrapper;

QObject::connect(portal, &UBDesktopPortal::screenGrabbed, portal, [portal,callback](QPixmap screenshot){
QObject::connect(portal, &UBScreenshotDesktopPortalWrapper::screenGrabbed, portal, [portal,callback](QPixmap screenshot){
callback(screenshot);
portal->deleteLater();
});

portal->grabScreen(screen, rect);
portal->grabScreen(screen, crop);
}
else
{
// see https://doc.qt.io/qt-6.2/qtwidgets-desktop-screenshot-example.html
// for using window id 0
QPixmap pixmap = screen->grabWindow(0, rect.x(), rect.y(), rect.width(), rect.height());
QPixmap pixmap = screen->grabWindow(0);
callback(pixmap);
}
}

bool UBPlatformUtils::grabCanCrop()
{
return sessionType() == WAYLAND && desktopEnvironment() == GNOME;
}

UBPlatformUtils::SessionType UBPlatformUtils::sessionType()
{
/*
Expand Down Expand Up @@ -596,7 +635,9 @@ void UBPlatformUtils::keepOnTop()
return;
}

auto path = "/" + result.arguments().first().toString();
const auto kdeSesionVersion = QProcessEnvironment::systemEnvironment().value("KDE_SESSION_VERSION", "0").toInt();
const auto prefix = kdeSesionVersion <= 5 ? "/" : "/Scripting/Script";
const auto path = prefix + result.arguments().first().toString();

QDBusInterface script("org.kde.KWin", path);
script.call("run");
Expand Down
10 changes: 8 additions & 2 deletions src/frameworks/UBPlatformUtils_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,14 @@ click menu item (nbItems - 4)\n\
}
}

void UBPlatformUtils::grabScreen(QScreen* screen, std::function<void (QPixmap)> callback, QRect rect)
void UBPlatformUtils::grabScreen(QScreen* screen, std::function<void (QPixmap)> callback, bool crop)
{
QPixmap pixmap = screen->grabWindow(0, rect.x(), rect.y(), rect.width(), rect.height());
Q_UNUSED(crop)
QPixmap pixmap = screen->grabWindow(0);
callback(pixmap);
}

bool UBPlatformUtils::grabCanCrop()
{
return false;
}
10 changes: 8 additions & 2 deletions src/frameworks/UBPlatformUtils_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,14 @@ void UBPlatformUtils::showOSK(bool show)
}
}

void UBPlatformUtils::grabScreen(QScreen* screen, std::function<void (QPixmap)> callback, QRect rect)
void UBPlatformUtils::grabScreen(QScreen* screen, std::function<void (QPixmap)> callback, bool crop)
{
QPixmap pixmap = screen->grabWindow(0, rect.x(), rect.y(), rect.width(), rect.height());
Q_UNUSED(crop)
QPixmap pixmap = screen->grabWindow(0);
callback(pixmap);
}

bool UBPlatformUtils::grabCanCrop()
{
return false;
}
18 changes: 10 additions & 8 deletions src/frameworks/frameworks.pri
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,24 @@ SOURCES += src/frameworks/UBGeometryUtils.cpp \
win32 {

SOURCES += src/frameworks/UBPlatformUtils_win.cpp
}
}


macx {
macx {

OBJECTIVE_SOURCES += src/frameworks/UBPlatformUtils_mac.mm
}

}


linux-g++* {
HEADERS += src/frameworks/UBDesktopPortal.h \
src/frameworks/UBPipewireSink.h
HEADERS += src/frameworks/linux/UBScreenCastDesktopPortalWrapper.h \
src/frameworks/linux/UBScreenshotDesktopPortalWrapper.h \
src/frameworks/linux/UBPipewireSink.h
SOURCES += src/frameworks/UBPlatformUtils_linux.cpp \
src/frameworks/UBDesktopPortal.cpp \
src/frameworks/UBPipewireSink.cpp
src/frameworks/linux/UBScreenCastDesktopPortalWrapper.cpp \
src/frameworks/linux/UBScreenshotDesktopPortalWrapper.cpp \
src/frameworks/linux/UBPipewireSink.cpp

CONFIG += link_pkgconfig
PKGCONFIG += libpipewire-0.3
Expand Down
32 changes: 32 additions & 0 deletions src/frameworks/linux/UBDesktopPortalTokenGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2015-2026 Département de l'Instruction Publique (DIP-SEM)
*
* This file is part of OpenBoard.
*
* OpenBoard is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
*/


#include "UBDesktopPortalTokenGenerator.h"

#include <QRandomGenerator>


QString UBDesktopPortalTokenGenerator::generateToken()
{
const auto randomValue = QRandomGenerator::global()->generate();
return "OB_" + QString::number(randomValue, 16);
}
Loading