Skip to content

Commit

Permalink
Feature/notify when screenshot being taken (#286)
Browse files Browse the repository at this point in the history
* Notify when screenshot is being taken
  • Loading branch information
Eeems authored Jan 26, 2023
1 parent a42a6b9 commit 3c9da61
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 71 deletions.
59 changes: 4 additions & 55 deletions applications/system-service/notification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void Notification::display(){
return;
}
notificationAPI->lock();
dispatchToMainThread([=]{
Oxide::dispatchToMainThread([=]{
qDebug() << "Displaying notification" << identifier();
auto path = appsAPI->currentApplicationNoSecurityCheck();
Application* resumeApp = nullptr;
Expand All @@ -52,61 +52,10 @@ void Notification::remove(){
emit removed();
}

void Notification::dispatchToMainThread(std::function<void()> callback){
if(this->thread() == qApp->thread()){
callback();
return;
}
// any thread
QTimer* timer = new QTimer();
timer->moveToThread(qApp->thread());
timer->setSingleShot(true);
QObject::connect(timer, &QTimer::timeout, [=](){
// main thread
callback();
timer->deleteLater();
});
QMetaObject::invokeMethod(timer, "start", Qt::BlockingQueuedConnection, Q_ARG(int, 0));
}
void Notification::paintNotification(Application* resumeApp){
auto frameBuffer = EPFrameBuffer::framebuffer();
qDebug() << "Waiting for other painting to finish...";
while(frameBuffer->paintingActive()){
EPFrameBuffer::waitForLastUpdate();
}
qDebug() << "Painting notification" << identifier();
screenBackup = frameBuffer->copy();
qDebug() << "Painting to framebuffer...";
QPainter painter(frameBuffer);
auto size = frameBuffer->size();
auto fm = painter.fontMetrics();
auto padding = 10;
auto radius = 10;
QImage icon(m_icon);
auto iconSize = icon.isNull() ? 0 : 50;
auto width = fm.horizontalAdvance(text()) + iconSize + (padding * 3);
auto height = max(fm.height(), iconSize) + (padding * 2);
auto left = size.width() - width;
auto top = size.height() - height;
updateRect = QRect(left, top, width, height);
painter.fillRect(updateRect, Qt::black);
painter.setPen(Qt::black);
painter.drawRoundedRect(updateRect, radius, radius);
painter.setPen(Qt::white);
QRect textRect(left + padding, top + padding, width - iconSize - (padding * 2), height - padding);
painter.drawText(textRect, Qt::AlignCenter, text());
painter.end();
qDebug() << "Updating screen " << updateRect << "...";
EPFrameBuffer::sendUpdate(updateRect, EPFrameBuffer::Mono, EPFrameBuffer::PartialUpdate, true);
if(!icon.isNull()){
QPainter painter2(frameBuffer);
QRect iconRect(size.width() - iconSize - padding, top + padding, iconSize, iconSize);
painter2.fillRect(iconRect, Qt::white);
painter2.drawImage(iconRect, icon);
painter2.end();
EPFrameBuffer::sendUpdate(iconRect, EPFrameBuffer::Mono, EPFrameBuffer::PartialUpdate, true);
}
EPFrameBuffer::waitForLastUpdate();
screenBackup = screenAPI->copy();
updateRect = notificationAPI->paintNotification(text(), m_icon);
qDebug() << "Painted notification" << identifier();
emit displayed();
QTimer::singleShot(2000, [this, resumeApp]{
Expand All @@ -117,7 +66,7 @@ void Notification::paintNotification(Application* resumeApp){
qDebug() << "Finished displaying notification" << identifier();
EPFrameBuffer::waitForLastUpdate();
if(!notificationAPI->notificationDisplayQueue.isEmpty()){
dispatchToMainThread([resumeApp] {
Oxide::dispatchToMainThread([resumeApp] {
notificationAPI->notificationDisplayQueue.takeFirst()->paintNotification(resumeApp);
});
return;
Expand Down
1 change: 0 additions & 1 deletion applications/system-service/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ class Notification : public QObject{
QImage screenBackup;
QRect updateRect;

void dispatchToMainThread(std::function<void()> callback);
bool hasPermission(QString permission, const char* sender = __builtin_FUNCTION());
};

Expand Down
35 changes: 35 additions & 0 deletions applications/system-service/notificationapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,41 @@ class NotificationAPI : public APIBase {
}
return m_notifications.value(identifier);
}
QRect paintNotification(const QString& text, const QString& iconPath){
qDebug() << "Painting to framebuffer...";
auto frameBuffer = EPFrameBuffer::framebuffer();
QPainter painter(frameBuffer);
auto size = frameBuffer->size();
auto fm = painter.fontMetrics();
auto padding = 10;
auto radius = 10;
QImage icon(iconPath);
auto iconSize = icon.isNull() ? 0 : 50;
auto width = fm.horizontalAdvance(text) + iconSize + (padding * 3);
auto height = max(fm.height(), iconSize) + (padding * 2);
auto left = size.width() - width;
auto top = size.height() - height;
QRect updateRect(left, top, width, height);
painter.fillRect(updateRect, Qt::black);
painter.setPen(Qt::black);
painter.drawRoundedRect(updateRect, radius, radius);
painter.setPen(Qt::white);
QRect textRect(left + padding, top + padding, width - iconSize - (padding * 2), height - padding);
painter.drawText(textRect, Qt::AlignCenter, text);
painter.end();
qDebug() << "Updating screen " << updateRect << "...";
EPFrameBuffer::sendUpdate(updateRect, EPFrameBuffer::Mono, EPFrameBuffer::PartialUpdate, true);
if(!icon.isNull()){
QPainter painter2(frameBuffer);
QRect iconRect(size.width() - iconSize - padding, top + padding, iconSize, iconSize);
painter2.fillRect(iconRect, Qt::white);
painter2.drawImage(iconRect, icon);
painter2.end();
EPFrameBuffer::sendUpdate(iconRect, EPFrameBuffer::Mono, EPFrameBuffer::PartialUpdate, true);
}
EPFrameBuffer::waitForLastUpdate();
return updateRect;
}

public slots:
QDBusObjectPath add(const QString& identifier, const QString& application, const QString& text, const QString& icon, QDBusMessage message){
Expand Down
27 changes: 27 additions & 0 deletions applications/system-service/screenapi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "screenapi.h"
#include "notificationapi.h"

QDBusObjectPath ScreenAPI::screenshot(){
if(!hasPermission("screen")){
return QDBusObjectPath("/");
}
qDebug() << "Taking screenshot";
auto filePath = getNextPath();
#ifdef DEBUG
qDebug() << "Using path" << filePath;
#endif
QImage screen = copy();
QRect rect = notificationAPI->paintNotification("Taking Screenshot...", "");
EPFrameBuffer::sendUpdate(rect, EPFrameBuffer::Mono, EPFrameBuffer::PartialUpdate, true);
QDBusObjectPath path("/");
if(!screen.save(filePath)){
qDebug() << "Failed to take screenshot";
}else{
path = addScreenshot(filePath)->qPath();
}
QPainter painter(EPFrameBuffer::framebuffer());
painter.drawImage(rect, screen, rect);
painter.end();
EPFrameBuffer::sendUpdate(rect, EPFrameBuffer::HighQualityGrayscale, EPFrameBuffer::PartialUpdate, true);
return path;
}
23 changes: 8 additions & 15 deletions applications/system-service/screenapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ class ScreenAPI : public APIBase {
}
Oxide::Sentry::sentry_transaction("screen", "drawFullscrenImage", [img, path](Oxide::Sentry::Transaction* t){
Q_UNUSED(t);
auto size = EPFrameBuffer::framebuffer()->size();
QRect rect(0, 0, size.width(), size.height());
QRect rect = EPFrameBuffer::framebuffer()->rect();
QPainter painter(EPFrameBuffer::framebuffer());
painter.drawImage(rect, img);
painter.end();
Expand All @@ -114,20 +113,14 @@ class ScreenAPI : public APIBase {
return true;
}

Q_INVOKABLE QDBusObjectPath screenshot(){
if(!hasPermission("screen")){
return QDBusObjectPath("/");
}
qDebug() << "Taking screenshot";
auto filePath = getNextPath();
#ifdef DEBUG
qDebug() << "Using path" << filePath;
#endif
if(!EPFrameBuffer::framebuffer()->save(filePath)){
qDebug() << "Failed to take screenshot";
return QDBusObjectPath("/");
Q_INVOKABLE QDBusObjectPath screenshot();
QImage copy(){
auto frameBuffer = EPFrameBuffer::framebuffer();
qDebug() << "Waiting for other painting to finish...";
while(frameBuffer->paintingActive()){
EPFrameBuffer::waitForLastUpdate();
}
return addScreenshot(filePath)->qPath();
return frameBuffer->copy();
}

public slots:
Expand Down
1 change: 1 addition & 0 deletions applications/system-service/tarnish.pro
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SOURCES += \
event_device.cpp \
network.cpp \
notification.cpp \
screenapi.cpp \
screenshot.cpp \
systemapi.cpp \
wlan.cpp \
Expand Down

0 comments on commit 3c9da61

Please sign in to comment.