diff --git a/applications/settings-manager/main.cpp b/applications/settings-manager/main.cpp index e4a909ddc..76289d41e 100644 --- a/applications/settings-manager/main.cpp +++ b/applications/settings-manager/main.cpp @@ -299,11 +299,22 @@ int main(int argc, char *argv[]){ #endif api = new Gui(OXIDE_SERVICE, path, bus); if(parser.isSet("object")){ - qDebug() << "Paths are not valid for the system API"; + auto object = parser.value("object"); #ifdef SENTRY - sentry_breadcrumb("error", "invalid arguments"); + sentry_breadcrumb("object", object.toStdString().c_str()); #endif - return qExit(EXIT_FAILURE); + auto type = object.mid(0, object.indexOf(":")); + auto path = object.mid(object.indexOf(":") + 1); + path = OXIDE_SERVICE_PATH + QString("/" + path); + if(type == "Window"){ + api = new Window(OXIDE_SERVICE, path, bus); + }else{ + qDebug() << "Unknown object type" << type; +#ifdef SENTRY + sentry_breadcrumb("error", "Unknown object type"); +#endif + return qExit(EXIT_FAILURE); + } } }else{ qDebug() << "API not initialized? Please log a bug."; diff --git a/applications/system-service/application.cpp b/applications/system-service/application.cpp index 557330729..917fc5e62 100644 --- a/applications/system-service/application.cpp +++ b/applications/system-service/application.cpp @@ -39,21 +39,6 @@ using namespace Oxide::Applications; -static Window* __window = nullptr; -Window* Application::_window(){ - if(__window == nullptr){ - __window = guiAPI->_createWindow(deviceSettings.screenGeometry(), DEFAULT_IMAGE_FORMAT); - __window->disableEventPipe(); - } - return __window; -} -void Application::shutdown(){ - if(__window != nullptr){ - __window->_close(); - __window = nullptr; - } -} - const event_device touchScreen(deviceSettings.getTouchDevicePath(), O_WRONLY); Application::Application(QDBusObjectPath path, QObject* parent) : Application(path.path(), parent) {} @@ -207,7 +192,7 @@ void Application::launchNoSecurityCheck(){ m_process->start(); m_process->waitForStarted(); if(!flags().contains("nosplash")){ - _window()->_lower(); + AppsAPI::_window()->_setVisible(false); } if(type() == Background){ startSpan("background", "Application is in the background"); @@ -1145,10 +1130,10 @@ void Application::showSplashScreen(){ #endif O_INFO("Displaying splashscreen for" << name()); Oxide::Sentry::sentry_span(t, "paint", "Draw splash screen", [this](){ - auto image = _window()->toImage(); + auto image = AppsAPI::_window()->toImage(); QPainter painter(&image); auto fm = painter.fontMetrics(); - auto geometry = _window()->_geometry(); + auto geometry = AppsAPI::_window()->_geometry(); painter.fillRect(geometry, Qt::white); QString splashPath = splash(); if(splashPath.isEmpty() || !QFile::exists(splashPath)){ @@ -1183,10 +1168,10 @@ void Application::showSplashScreen(){ ); painter.end(); }); - if(!_window()->_isVisible()){ - _window()->_raise(false); + if(!AppsAPI::_window()->_isVisible()){ + AppsAPI::_window()->_setVisible(true); }else{ - _window()->_repaint(_window()->_geometry(), EPFrameBuffer::HighQualityGrayscale, 0, false); + AppsAPI::_window()->_repaint(AppsAPI::_window()->_geometry(), EPFrameBuffer::HighQualityGrayscale, 0, false); } }); O_INFO("Finished painting splash screen for" << name()); @@ -1260,15 +1245,15 @@ void Application::recallScreen(){ } qDebug() << "Recalling screen..."; Oxide::Sentry::sentry_span(t, "recall", "Recall the screen", [this, img]{ - auto rect = _window()->geometry(); - auto image = _window()->toImage(); + auto rect = AppsAPI::_window()->geometry(); + auto image = AppsAPI::_window()->toImage(); QPainter painter(&image); painter.drawImage(rect, img); painter.end(); - if(!_window()->_isVisible()){ - _window()->_raise(false); + if(AppsAPI::_window()->_isVisible()){ + AppsAPI::_window()->_repaint(rect, EPFrameBuffer::HighQualityGrayscale, 0, false); }else{ - _window()->_repaint(rect, EPFrameBuffer::HighQualityGrayscale, 0, false); + AppsAPI::_window()->_setVisible(true); } delete m_screenCapture; m_screenCapture = nullptr; diff --git a/applications/system-service/application.h b/applications/system-service/application.h index a4c203ba4..177e9b108 100644 --- a/applications/system-service/application.h +++ b/applications/system-service/application.h @@ -63,9 +63,6 @@ class Application : public QObject{ Q_PROPERTY(QByteArray screenCapture READ screenCapture) public: - static Window* _window(); - static void shutdown(); - Application(QDBusObjectPath path, QObject* parent); Application(QString path, QObject* parent); ~Application(); diff --git a/applications/system-service/appsapi.cpp b/applications/system-service/appsapi.cpp index 3e2e3ac7e..253275bb3 100644 --- a/applications/system-service/appsapi.cpp +++ b/applications/system-service/appsapi.cpp @@ -16,6 +16,19 @@ using namespace Oxide; +static Window* __window = nullptr; +Window* AppsAPI::_window(){ + if(__window == nullptr){ + __window = guiAPI->_createWindow(deviceSettings.screenGeometry(), DEFAULT_IMAGE_FORMAT); + __window->setZ(std::numeric_limits::max() - 1); + __window->disableEventPipe(); + __window->_setVisible(false); + __window->setSystemWindow(); + __window->_raise(); + } + return __window; +} + AppsAPI* AppsAPI::singleton(AppsAPI* self){ static AppsAPI* instance; if(self != nullptr){ @@ -169,7 +182,7 @@ void AppsAPI::startup(){ void AppsAPI::shutdown(){ O_INFO("Shutting down Apps API"); m_stopping = true; - auto window = Application::_window(); + auto window = _window(); auto image = window->toImage(); auto rect = image.rect(); QPainter painter(&image); @@ -230,7 +243,10 @@ void AppsAPI::shutdown(){ }else{ window->_raise(false); } - Application::shutdown(); + if(__window != nullptr){ + __window->_close(); + __window = nullptr; + } O_INFO("Apps API shutdown complete"); } diff --git a/applications/system-service/appsapi.h b/applications/system-service/appsapi.h index 11f701283..c556b57e5 100644 --- a/applications/system-service/appsapi.h +++ b/applications/system-service/appsapi.h @@ -29,6 +29,7 @@ class AppsAPI : public APIBase { Q_PROPERTY(QVariantMap pausedApplications READ pausedApplications) public: + static Window* _window(); static AppsAPI* singleton(AppsAPI* self = nullptr); AppsAPI(QObject* parent); ~AppsAPI(); diff --git a/applications/system-service/guiapi.cpp b/applications/system-service/guiapi.cpp index 4b2f15d84..9f95cdeaa 100644 --- a/applications/system-service/guiapi.cpp +++ b/applications/system-service/guiapi.cpp @@ -93,7 +93,7 @@ Window* GuiAPI::_createWindow(QRect geometry, QImage::Format format){ auto path = QString(OXIDE_SERVICE_PATH) + "/window/" + QUuid::createUuidV5(NS, id).toString(QUuid::Id128); auto pgid = getSenderPgid(); m_windowMutex.lock(); - auto window = new Window(id, path, pgid, geometry, m_windows.count(), format); + auto window = new Window(id, path, pgid, geometry, format); m_windows.insert(path, window); m_windowMutex.unlock(); sortWindows(); @@ -151,12 +151,15 @@ QDBusObjectPath GuiAPI::createWindow(int format){ } QList GuiAPI::windows(){ - auto pgid = getSenderPgid(); QList windows; - QMutexLocker locker(&m_windowMutex); - Q_UNUSED(locker) - for(auto window : m_windows){ - if(window->pgid() == pgid){ + if(!hasPermission()){ + W_DENIED(); + return windows; + } + W_ALLOWED(); + auto pgid = getSenderPgid(); + for(auto window : sortedWindows()){ + if(window->pgid() == pgid || qEnvironmentVariableIsSet("OXIDE_EXPOSE_ALL_WINDOWS")){ windows.append(window->path()); } } @@ -198,6 +201,9 @@ void GuiAPI::sortWindows(){ int raisedZ = 0; int loweredZ = -1; for(auto window : windows){ + if(window->systemWindow()){ + continue; + } switch(window->state()){ case Window::Raised: case Window::RaisedHidden: @@ -449,6 +455,9 @@ bool GuiAPI::hasPermission(){ if(DBusService::shuttingDown()){ return false; } + if(qEnvironmentVariableIsSet("OXIDE_EXPOSE_ALL_WINDOWS")){ + return true; + } pid_t pgid = getSenderPgid(); if(dbusService->isChildGroup(pgid)){ return true; diff --git a/applications/system-service/notification.cpp b/applications/system-service/notification.cpp index 9b9e7b4c6..d321c5679 100644 --- a/applications/system-service/notification.cpp +++ b/applications/system-service/notification.cpp @@ -2,6 +2,7 @@ #include "notificationapi.h" #include "appsapi.h" #include "screenapi.h" +#include "window.h" #include #include @@ -110,13 +111,7 @@ void Notification::display(){ notificationAPI->lock(); Oxide::dispatchToMainThread([this]{ O_INFO("Displaying notification" << identifier()); - auto path = appsAPI->currentApplicationNoSecurityCheck(); - Application* resumeApp = nullptr; - if(path.path() != "/"){ - resumeApp = appsAPI->getApplication(path); - resumeApp->interruptApplication(); - } - paintNotification(resumeApp); + paintNotification(); }); } @@ -135,32 +130,17 @@ void Notification::click(){ emit clicked(); } -void Notification::paintNotification(Application* resumeApp){ +void Notification::paintNotification(){ O_INFO("Painting notification" << identifier()); - dispatchToMainThread([this]{ - screenBackup = screenAPI->copy(); - }); - updateRect = notificationAPI->paintNotification(text(), m_icon); + notificationAPI->paintNotification(text(), m_icon); O_INFO("Painted notification" << identifier()); emit displayed(); - QTimer::singleShot(2000, [this, resumeApp]{ - dispatchToMainThread([this]{ - QPainter painter(EPFrameBuffer::framebuffer()); - painter.drawImage(updateRect, screenBackup, updateRect); - painter.end(); - EPFrameBuffer::sendUpdate(updateRect, EPFrameBuffer::Mono, EPFrameBuffer::FullUpdate, true); - O_INFO("Finished displaying notification" << identifier()); - EPFrameBuffer::waitForLastUpdate(); - }); + QTimer::singleShot(2000, [this]{ + NotificationAPI::_window()->_setVisible(false); if(!notificationAPI->notificationDisplayQueue.isEmpty()){ - Oxide::dispatchToMainThread([resumeApp] { - notificationAPI->notificationDisplayQueue.takeFirst()->paintNotification(resumeApp); - }); + notificationAPI->notificationDisplayQueue.takeFirst()->paintNotification(); return; } - if(resumeApp != nullptr){ - resumeApp->uninterruptApplication(); - } notificationAPI->unlock(); }); } diff --git a/applications/system-service/notification.h b/applications/system-service/notification.h index c2c8d9f22..fc0e92b36 100644 --- a/applications/system-service/notification.h +++ b/applications/system-service/notification.h @@ -41,7 +41,7 @@ class Notification : public QObject{ Q_INVOKABLE void display(); Q_INVOKABLE void remove(); Q_INVOKABLE void click(); - void paintNotification(Application* resumeApp); + void paintNotification(); signals: void changed(QVariantMap); @@ -57,8 +57,6 @@ class Notification : public QObject{ QString m_application; QString m_text; QString m_icon; - QImage screenBackup; - QRect updateRect; bool hasPermission(QString permission, const char* sender = __builtin_FUNCTION()); }; diff --git a/applications/system-service/notificationapi.cpp b/applications/system-service/notificationapi.cpp index 46f27bfdd..0d3dd72ea 100644 --- a/applications/system-service/notificationapi.cpp +++ b/applications/system-service/notificationapi.cpp @@ -1,9 +1,27 @@ #include "notificationapi.h" +#include "guiapi.h" +#include "window.h" #include using namespace Oxide; +static Window* __window = nullptr; +Window* NotificationAPI::_window(){ + if(__window == nullptr){ + auto screenRect = deviceSettings.screenGeometry(); + int x = screenRect.width() / 2; + int y = screenRect.height() / 8; + __window = guiAPI->_createWindow(QRect(x, y * 7, x, y), QImage::Format_RGBA8888_Premultiplied); + __window->setZ(std::numeric_limits::max()); + __window->disableEventPipe(); + __window->setSystemWindow(); + __window->_setVisible(false); + __window->_raise(); + } + return __window; +} + NotificationAPI* NotificationAPI::singleton(NotificationAPI* self){ static NotificationAPI* instance; if(self != nullptr){ @@ -92,57 +110,41 @@ Notification* NotificationAPI::getByIdentifier(const QString& identifier){ return m_notifications.value(identifier); } -QRect NotificationAPI::paintNotification(const QString& text, const QString& iconPath){ - return dispatchToMainThread([text, iconPath]{ - O_INFO("Painting to framebuffer..."); - auto frameBuffer = EPFrameBuffer::framebuffer(); - QPainter painter(frameBuffer); - auto size = frameBuffer->size(); - auto padding = 10; - auto radius = 10; - QImage icon(iconPath); - auto iconSize = icon.isNull() ? 0 : 50; - auto boundingRect = painter.fontMetrics().boundingRect(QRect(0, 0, size.width() / 2, size.height() / 8), Qt::AlignCenter | Qt::TextWordWrap, text); - auto width = boundingRect.width() + iconSize + (padding * 3); - auto height = std::max(boundingRect.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 | Qt::TextWordWrap, text); - painter.end(); - O_INFO("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; - }); +void NotificationAPI::paintNotification(const QString& text, const QString& iconPath){ + auto image = _window()->toImage(); + QPainter painter(&image); + auto padding = 10; + auto radius = 10; + QImage icon(iconPath); + auto iconSize = icon.isNull() ? 0 : 50; + auto boundingRect = painter.fontMetrics().boundingRect(image.rect(), Qt::AlignCenter | Qt::TextWordWrap, text); + auto width = boundingRect.width() + iconSize + (padding * 3); + auto height = std::max(boundingRect.height(), iconSize) + (padding * 2); + auto left = image.width() - width; + auto top = image.height() - height; + painter.fillRect(image.rect(), Qt::transparent); + 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 | Qt::TextWordWrap, text); + if(!icon.isNull()){ + QRect iconRect(image.width() - iconSize - padding, top + padding, iconSize, iconSize); + painter.fillRect(iconRect, Qt::white); + painter.drawImage(iconRect, icon); + } + painter.end(); + if(_window()->_isVisible()){ + _window()->_repaint(image.rect(), EPFrameBuffer::Mono, 0, false); + }else{ + _window()->_setVisible(true); + } } void NotificationAPI::errorNotification(const QString& text){ - dispatchToMainThread([]{ - auto frameBuffer = EPFrameBuffer::framebuffer(); - O_INFO("Waiting for other painting to finish..."); - while(frameBuffer->paintingActive()){ - EPFrameBuffer::waitForLastUpdate(); - } - O_INFO("Displaying error text"); - QPainter painter(frameBuffer); - painter.fillRect(frameBuffer->rect(), Qt::white); - painter.end(); - EPFrameBuffer::sendUpdate(frameBuffer->rect(), EPFrameBuffer::Mono, EPFrameBuffer::FullUpdate, true); - }); + // TODO - clear screen? notificationAPI->paintNotification(text, ""); } diff --git a/applications/system-service/notificationapi.h b/applications/system-service/notificationapi.h index f8ee4b20c..0194e8516 100644 --- a/applications/system-service/notificationapi.h +++ b/applications/system-service/notificationapi.h @@ -18,6 +18,7 @@ class NotificationAPI : public APIBase { Q_PROPERTY(QList unownedNotifications READ getUnownedNotifications) public: + static Window* _window(); static NotificationAPI* singleton(NotificationAPI* self = nullptr); NotificationAPI(QObject* parent); ~NotificationAPI(){} @@ -32,7 +33,7 @@ class NotificationAPI : public APIBase { Notification* add(const QString& identifier, const QString& owner, const QString& application, const QString& text, const QString& icon); Notification* getByIdentifier(const QString& identifier); - QRect paintNotification(const QString& text, const QString& iconPath); + void paintNotification(const QString& text, const QString& iconPath); void errorNotification(const QString& text); public slots: diff --git a/applications/system-service/screenapi.cpp b/applications/system-service/screenapi.cpp index 100a7a3b7..ff52c6660 100644 --- a/applications/system-service/screenapi.cpp +++ b/applications/system-service/screenapi.cpp @@ -1,4 +1,5 @@ #include "screenapi.h" +#include "appsapi.h" #include "notificationapi.h" #include "window.h" @@ -78,19 +79,17 @@ bool ScreenAPI::drawFullscreenImage(QString path){ } Sentry::sentry_transaction("screen", "drawFullscrenImage", [img, path](Sentry::Transaction* t){ Q_UNUSED(t); - Oxide::dispatchToMainThread([img]{ - auto window = Application::_window(); - auto image = window->toImage(); - QRect rect = image.rect(); - QPainter painter(&image); - painter.drawImage(rect, img); - painter.end(); - if(window->_isVisible()){ - window->_repaint(rect, EPFrameBuffer::HighQualityGrayscale, 0, false); - }else{ - window->_raise(false); - } - }); + auto window = AppsAPI::_window(); + auto image = window->toImage(); + QRect rect = image.rect(); + QPainter painter(&image); + painter.drawImage(rect, img); + painter.end(); + if(window->_isVisible()){ + window->_repaint(rect, EPFrameBuffer::HighQualityGrayscale, 0, false); + }else{ + window->_setVisible(true); + } }); return true; } @@ -99,39 +98,32 @@ QDBusObjectPath ScreenAPI::screenshot(){ if(!hasPermission("screen")){ return QDBusObjectPath("/"); } - O_INFO("Taking screenshot"); + auto filePath = _screenshot(); + QDBusObjectPath path("/"); + if(filePath.isEmpty()){ + O_INFO("Failed to take screenshot"); + }else{ + path = addScreenshot(filePath)->qPath(); + } + return path; +} + +QString ScreenAPI::_screenshot(){ auto filePath = getNextPath(); #ifdef DEBUG - O_INFO("Using path" << filePath); + O_INFO("Taking screenshot using path" << filePath); #endif - return dispatchToMainThread([this, filePath]{ - QImage screen = copy(); - QRect rect = notificationAPI->paintNotification("Taking Screenshot...", ""); - EPFrameBuffer::sendUpdate(rect, EPFrameBuffer::Mono, EPFrameBuffer::PartialUpdate, true); - QDBusObjectPath path("/"); - if(!screen.save(filePath)){ - O_INFO("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; - }); + QImage screen = copy(); + notificationAPI->paintNotification("Taking Screenshot...", ""); + if(!screen.save(filePath)){ + O_INFO("Failed to take screenshot"); + return ""; + } + NotificationAPI::_window()->_setVisible(false); + return filePath; } -QImage ScreenAPI::copy(){ - return Oxide::dispatchToMainThread([]{ - auto frameBuffer = EPFrameBuffer::framebuffer(); - O_INFO("Waiting for other painting to finish..."); - while(frameBuffer->paintingActive()){ - EPFrameBuffer::waitForLastUpdate(); - } - return frameBuffer->copy(); - }); -} +QImage ScreenAPI::copy(){ return EPFrameBuffer::framebuffer()->copy(); } QDBusObjectPath ScreenAPI::addScreenshot(QByteArray blob){ if(!hasPermission("screen")){ diff --git a/applications/system-service/screenapi.h b/applications/system-service/screenapi.h index e53a19399..cc92fca5e 100644 --- a/applications/system-service/screenapi.h +++ b/applications/system-service/screenapi.h @@ -27,6 +27,7 @@ class ScreenAPI : public APIBase { QList screenshots(); Q_INVOKABLE bool drawFullscreenImage(QString path); Q_INVOKABLE QDBusObjectPath screenshot(); + QString _screenshot(); QImage copy(); public slots: diff --git a/applications/system-service/systemapi.cpp b/applications/system-service/systemapi.cpp index 87307f6f4..23060fc0d 100644 --- a/applications/system-service/systemapi.cpp +++ b/applications/system-service/systemapi.cpp @@ -252,7 +252,6 @@ SystemAPI::SystemAPI(QObject* parent) connect(wacomHandler, &DigitizerHandler::inputEvent, this, &SystemAPI::penEvent); eventListener->append([this](QObject* object, QEvent* event){ Q_UNUSED(object) - O_DEBUG(event); switch(event->type()){ case QEvent::KeyPress:{ activity(); diff --git a/applications/system-service/window.cpp b/applications/system-service/window.cpp index 20a3248d5..055db6d11 100644 --- a/applications/system-service/window.cpp +++ b/applications/system-service/window.cpp @@ -18,19 +18,20 @@ using namespace Oxide::Tarnish; QMutexLocker locker(&m_mutex); \ Q_UNUSED(locker); -Window::Window(const QString& id, const QString& path, const pid_t& pgid, const QRect& geometry, int z, QImage::Format format) +Window::Window(const QString& id, const QString& path, const pid_t& pgid, const QRect& geometry, QImage::Format format) : QObject{guiAPI}, m_identifier{id}, m_enabled{false}, m_path{path}, m_pgid{pgid}, m_geometry{geometry}, - m_z{z}, + m_z{0}, m_file{this}, m_state{WindowState::LoweredHidden}, m_format{(QImage::Format)format}, m_eventPipe{true}, - m_pendingMarker{0} + m_pendingMarker{0}, + m_systemWindow{false} { LOCK_MUTEX; m_touchEventPipe.setEnabled(false); @@ -92,7 +93,7 @@ const QString& Window::identifier(){ return m_identifier; } int Window::z(){ return m_z; } void Window::setZ(int z){ - if(m_z == z){ + if(m_z == z || m_systemWindow){ return; } m_z = z; @@ -222,6 +223,10 @@ void Window::setVisible(bool visible){ return; } W_ALLOWED(); + _setVisible(visible); +} + +void Window::_setVisible(bool visible){ auto wasVisible = _isVisible(); auto state = m_state; switch(m_state){ @@ -323,7 +328,9 @@ void Window::_raise(bool async){ default: break; } - m_z = std::numeric_limits::max(); + if(!m_systemWindow){ + m_z = std::numeric_limits::max() - 2; + } guiAPI->sortWindows(); invalidateEventPipes(); guiAPI->dirty(this, m_geometry, EPFrameBuffer::Initialize, 0, async); @@ -352,7 +359,9 @@ void Window::_lower(bool async){ invalidateEventPipes(); guiAPI->dirty(this, m_geometry, EPFrameBuffer::Initialize, 0, async); } - m_z = std::numeric_limits::min(); + if(!m_systemWindow){ + m_z = std::numeric_limits::min(); + } guiAPI->sortWindows(); emit stateChanged(m_state); writeEvent(WindowEventType::Lower); @@ -466,6 +475,12 @@ void Window::writeEvent(TabletEventArgs args){ void Window::disableEventPipe(){ m_eventPipe.setEnabled(false); } +bool Window::systemWindow(){ return m_systemWindow; } + +void Window::setSystemWindow(){ + m_systemWindow = true; +} + bool Window::operator>(Window* other) const{ return m_z > other->z(); } bool Window::operator<(Window* other) const{ return m_z < other->z(); } @@ -614,7 +629,7 @@ void Window::pingDeadline(){ } } -bool Window::hasPermissions(){ return !DBusService::shuttingDown() && guiAPI->isThisPgId(m_pgid); } +bool Window::hasPermissions(){ return !DBusService::shuttingDown() && (guiAPI->isThisPgId(m_pgid) || qEnvironmentVariableIsSet("OXIDE_EXPOSE_ALL_WINDOWS")); } void Window::createFrameBuffer(const QRect& geometry){ // No mutex, as it should be handled by the calling function diff --git a/applications/system-service/window.h b/applications/system-service/window.h index e8fc82974..9ee4fd726 100644 --- a/applications/system-service/window.h +++ b/applications/system-service/window.h @@ -35,7 +35,7 @@ class Window : public QObject{ LoweredHidden, Closed } WindowState; - Window(const QString& identifier, const QString& path, const pid_t& pgid, const QRect& geometry, int z, QImage::Format format); + Window(const QString& identifier, const QString& path, const pid_t& pgid, const QRect& geometry, QImage::Format format); ~Window(); void setEnabled(bool enabled); @@ -56,6 +56,7 @@ class Window : public QObject{ bool isAppWindow(); bool isAppPaused(); Q_INVOKABLE void setVisible(bool visible); + void _setVisible(bool visible); QImage toImage(); qulonglong sizeInBytes(); qulonglong bytesPerLine(); @@ -77,6 +78,8 @@ class Window : public QObject{ void writeEvent(TouchEventArgs args); void writeEvent(TabletEventArgs args); void disableEventPipe(); + bool systemWindow(); + void setSystemWindow(); bool operator>(Window* other) const; bool operator<(Window* other) const; @@ -127,6 +130,7 @@ private slots: QTimer m_pingTimer; QTimer m_pingDeadlineTimer; unsigned int m_pendingMarker; + bool m_systemWindow; bool hasPermissions(); void createFrameBuffer(const QRect& geometry); diff --git a/shared/liboxide/json.cpp b/shared/liboxide/json.cpp index ab658024a..c50c7a6f5 100644 --- a/shared/liboxide/json.cpp +++ b/shared/liboxide/json.cpp @@ -118,6 +118,9 @@ namespace Oxide::JSON { } QVariant sanitizeForJson(QVariant value){ auto userType = value.userType(); + if(userType == QMetaType::type("QDBusUnixFileDescriptor")){ + return value.value().fileDescriptor(); + } if(userType == QMetaType::type("QDBusObjectPath")){ return value.value().path(); } @@ -151,6 +154,24 @@ namespace Oxide::JSON { } return list; } + if(userType == QMetaType::QRect){ + auto rect = value.toRect(); + QVariantMap map; + map.insert("x", rect.x()); + map.insert("y", rect.y()); + map.insert("width", rect.width()); + map.insert("height", rect.height()); + return map; + } + if(userType == QMetaType::QRectF){ + auto rect = value.toRectF(); + QVariantMap map; + map.insert("x", rect.x()); + map.insert("y", rect.y()); + map.insert("width", rect.width()); + map.insert("height", rect.height()); + return map; + } if(userType == QMetaType::QByteArray){ auto byteArray = value.toByteArray(); QVariantList list; diff --git a/shared/liboxide/tarnish.cpp b/shared/liboxide/tarnish.cpp index e294803a4..01298be05 100644 --- a/shared/liboxide/tarnish.cpp +++ b/shared/liboxide/tarnish.cpp @@ -899,7 +899,7 @@ namespace Oxide::Tarnish { } if(window == nullptr){ auto reply = api_gui->windows(); - if(!reply.isError()){ + if(reply.isValid()){ for(QDBusObjectPath qpath : reply.value()){ auto path = qpath.path(); if(path == "/"){