diff --git a/applications/system-service/application.cpp b/applications/system-service/application.cpp index 917fc5e62..1564c1dbf 100644 --- a/applications/system-service/application.cpp +++ b/applications/system-service/application.cpp @@ -29,6 +29,7 @@ #include "mxcfb.h" #include "guiapi.h" #include "screenapi.h" +#include "notificationapi.h" #include "appsapi.h" #include "systemapi.h" #include "guiapi.h" @@ -133,7 +134,9 @@ void Application::launchNoSecurityCheck(){ appsAPI->recordPreviousApplication(); O_INFO("Launching " << path().toStdString().c_str()); appsAPI->pauseAll(); - if(!flags().contains("nosplash")){ + if(flags().contains("nosplash")){ + notificationAPI->paintNotification("Loading " + displayName() + "...", icon()); + }else{ showSplashScreen(); } if(m_process->program() != bin()){ @@ -191,8 +194,10 @@ void Application::launchNoSecurityCheck(){ } m_process->start(); m_process->waitForStarted(); - if(!flags().contains("nosplash")){ - AppsAPI::_window()->_setVisible(false); + if(flags().contains("nosplash")){ + NotificationAPI::_window()->_setVisible(false, false); + }else{ + AppsAPI::_window()->_setVisible(false, false); } if(type() == Background){ startSpan("background", "Application is in the background"); @@ -1169,7 +1174,7 @@ void Application::showSplashScreen(){ painter.end(); }); if(!AppsAPI::_window()->_isVisible()){ - AppsAPI::_window()->_setVisible(true); + AppsAPI::_window()->_setVisible(true, false); }else{ AppsAPI::_window()->_repaint(AppsAPI::_window()->_geometry(), EPFrameBuffer::HighQualityGrayscale, 0, false); } @@ -1253,7 +1258,7 @@ void Application::recallScreen(){ if(AppsAPI::_window()->_isVisible()){ AppsAPI::_window()->_repaint(rect, EPFrameBuffer::HighQualityGrayscale, 0, false); }else{ - AppsAPI::_window()->_setVisible(true); + AppsAPI::_window()->_setVisible(true, false); } delete m_screenCapture; m_screenCapture = nullptr; diff --git a/applications/system-service/appsapi.cpp b/applications/system-service/appsapi.cpp index 253275bb3..83bea3ffc 100644 --- a/applications/system-service/appsapi.cpp +++ b/applications/system-service/appsapi.cpp @@ -22,7 +22,7 @@ Window* AppsAPI::_window(){ __window = guiAPI->_createWindow(deviceSettings.screenGeometry(), DEFAULT_IMAGE_FORMAT); __window->setZ(std::numeric_limits::max() - 1); __window->disableEventPipe(); - __window->_setVisible(false); + __window->_setVisible(false, true); __window->setSystemWindow(); __window->_raise(); } diff --git a/applications/system-service/notification.cpp b/applications/system-service/notification.cpp index b560ae2d4..fa34fd649 100644 --- a/applications/system-service/notification.cpp +++ b/applications/system-service/notification.cpp @@ -140,7 +140,7 @@ void Notification::paintNotification(){ notificationAPI->notificationDisplayQueue.takeFirst()->paintNotification(); return; } - NotificationAPI::_window()->_setVisible(false); + NotificationAPI::_window()->_setVisible(false, true); O_INFO("No more notifications to display"); notificationAPI->unlock(); }); diff --git a/applications/system-service/notificationapi.cpp b/applications/system-service/notificationapi.cpp index 1669e1ab2..de94df45d 100644 --- a/applications/system-service/notificationapi.cpp +++ b/applications/system-service/notificationapi.cpp @@ -18,7 +18,7 @@ Window* NotificationAPI::_window(){ __window->setZ(std::numeric_limits::max()); __window->disableEventPipe(); __window->setSystemWindow(); - __window->_setVisible(false); + __window->_setVisible(false, true); __window->_raise(); if(!__window->toImage().hasAlphaChannel()){ qFatal("Notification window doesn't have alpha channel"); @@ -121,8 +121,8 @@ void NotificationAPI::paintNotification(const QString& text, const QString& icon int y = screenRect.height() / 8; auto maxRect = QRect(x, y * 7, x, y); - QPainter painter; QImage icon(iconPath); + unsigned int radius = 10; unsigned int padding = 20; unsigned int minWidth = screenRect.width() / 4; auto margins = QMargins(padding, padding, padding, padding); @@ -131,6 +131,8 @@ void NotificationAPI::paintNotification(const QString& text, const QString& icon iconSize = 50; margins.setLeft(margins.left() + padding + iconSize); } + auto image = _window()->toImage(); + QPainter painter(&image); // Calculate size needed auto boundingRect = painter .fontMetrics() @@ -139,6 +141,7 @@ void NotificationAPI::paintNotification(const QString& text, const QString& icon Qt::TextWordWrap, text ); + painter.end(); // Calculate the update rectangle location auto updateRect = boundingRect.marginsAdded(margins); @@ -148,14 +151,17 @@ void NotificationAPI::paintNotification(const QString& text, const QString& icon updateRect.moveBottomRight(maxRect.bottomRight()); _window()->setGeometry(updateRect); - auto image = _window()->toImage(); + image = _window()->toImage(); image.fill(Qt::transparent); painter.begin(&image); + painter.setBackgroundMode(Qt::TransparentMode); - // Draw a white rectangle with a black border - painter.fillRect(image.rect(), Qt::white); + // Draw a rounded white rectangle with a black border + QPainterPath rectPath; + rectPath.addRoundedRect(image.rect(), radius, radius); painter.setPen(Qt::black); - painter.drawRect(image.rect()); + painter.fillPath(rectPath, Qt::white); + painter.drawPath(rectPath); // Add text painter.setPen(Qt::black); @@ -174,7 +180,7 @@ void NotificationAPI::paintNotification(const QString& text, const QString& icon if(_window()->_isVisible()){ _window()->_repaint(image.rect(), EPFrameBuffer::Mono, 0, false); }else{ - _window()->_setVisible(true); + _window()->_setVisible(true, false); } } diff --git a/applications/system-service/screenapi.cpp b/applications/system-service/screenapi.cpp index ff52c6660..10b0c19f9 100644 --- a/applications/system-service/screenapi.cpp +++ b/applications/system-service/screenapi.cpp @@ -88,7 +88,7 @@ bool ScreenAPI::drawFullscreenImage(QString path){ if(window->_isVisible()){ window->_repaint(rect, EPFrameBuffer::HighQualityGrayscale, 0, false); }else{ - window->_setVisible(true); + window->_setVisible(true, false); } }); return true; @@ -119,7 +119,7 @@ QString ScreenAPI::_screenshot(){ O_INFO("Failed to take screenshot"); return ""; } - NotificationAPI::_window()->_setVisible(false); + NotificationAPI::_window()->_setVisible(false, true); return filePath; } diff --git a/applications/system-service/window.cpp b/applications/system-service/window.cpp index 49dd56fdd..bc596b8a3 100644 --- a/applications/system-service/window.cpp +++ b/applications/system-service/window.cpp @@ -225,10 +225,10 @@ void Window::setVisible(bool visible){ return; } W_ALLOWED(); - _setVisible(visible); + _setVisible(visible, false); } -void Window::_setVisible(bool visible){ +void Window::_setVisible(bool visible, bool async){ auto wasVisible = _isVisible(); auto state = m_state; switch(m_state){ @@ -254,7 +254,7 @@ void Window::_setVisible(bool visible){ } emit stateChanged(m_state); if(visibilityChanged){ - guiAPI->dirty(nullptr, m_geometry, EPFrameBuffer::Initialize, 0, false); + guiAPI->dirty(nullptr, m_geometry, EPFrameBuffer::Initialize, 0, async); } } diff --git a/applications/system-service/window.h b/applications/system-service/window.h index e12f45f06..e43a4589d 100644 --- a/applications/system-service/window.h +++ b/applications/system-service/window.h @@ -57,7 +57,7 @@ class Window : public QObject{ bool isAppWindow(); bool isAppPaused(); Q_INVOKABLE void setVisible(bool visible); - void _setVisible(bool visible); + void _setVisible(bool visible, bool async = true); QImage toImage(); qulonglong sizeInBytes(); qulonglong bytesPerLine();