/* * Copyright (C) 2017 Canonical, Ltd. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3, as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "ScreenAttached.h" #include "ScreenWindow.h" #include "Screens.h" #include #include ScreenAttached::ScreenAttached(QObject *owner) : Screen(owner) , m_window(nullptr) { if (auto item = qobject_cast(owner)) { connect(item, &QQuickItem::windowChanged, this, &ScreenAttached::windowChanged); windowChanged(item->window()); } else if (auto window = qobject_cast(owner)) { windowChanged(window); } } WorkspaceModel *ScreenAttached::workspaces() const { if (!m_screen) return nullptr; return m_screen->workspaces(); } Workspace *ScreenAttached::currentWorkspace() const { if (!m_screen) return nullptr; return m_screen->currentWorkspace(); } void ScreenAttached::setCurrentWorkspace(Workspace *workspace) { if (!m_screen) return; return m_screen->setCurrentWorkspace(workspace); } void ScreenAttached::windowChanged(QQuickWindow *window) { if (m_window) { disconnect(m_window, &QWindow::screenChanged, this, &ScreenAttached::screenChanged); } m_window = window; auto screenWindow = qobject_cast(window); if (screenWindow) { screenChanged2(screenWindow->screenWrapper()); connect(screenWindow, &ScreenWindow::screenWrapperChanged, this, &ScreenAttached::screenChanged2); } else { screenChanged(window ? window->screen() : NULL); if (window) { connect(window, &QWindow::screenChanged, this, &ScreenAttached::screenChanged); } } } void ScreenAttached::screenChanged(QScreen *qscreen) { // Find a screen that matches. // Should only get here in mocks if we don't have a ScreenWindow Screen* screen{nullptr}; Q_FOREACH(auto s, ConcreteScreens::self()->list()) { if (s->qscreen() == qscreen) { screen = s; } } screenChanged2(screen); } void ScreenAttached::screenChanged2(Screen* screen) { if (screen == m_screen) return; Screen* oldScreen = m_screen; m_screen = screen; if (oldScreen) oldScreen->disconnect(this); if (!screen) return; //Don't bother emitting signals, because the new values are garbage anyways if (!oldScreen || screen->isActive() != oldScreen->isActive()) Q_EMIT activeChanged(screen->isActive()); if (!oldScreen || screen->used() != oldScreen->used()) Q_EMIT usedChanged(); if (!oldScreen || screen->name() != oldScreen->name()) Q_EMIT nameChanged(); if (!oldScreen || screen->outputType() != oldScreen->outputType()) Q_EMIT outputTypeChanged(); if (!oldScreen || screen->scale() != oldScreen->scale()) Q_EMIT scaleChanged(); if (!oldScreen || screen->formFactor() != oldScreen->formFactor()) Q_EMIT formFactorChanged(); if (!oldScreen || screen->powerMode() != oldScreen->powerMode()) Q_EMIT powerModeChanged(); if (!oldScreen || screen->orientation() != oldScreen->orientation()) Q_EMIT orientationChanged(); if (!oldScreen || screen->position() != oldScreen->position()) Q_EMIT positionChanged(); if (!oldScreen || screen->currentModeIndex() != oldScreen->currentModeIndex()) Q_EMIT currentModeIndexChanged(); if (!oldScreen || screen->physicalSize() != oldScreen->physicalSize()) Q_EMIT physicalSizeChanged(); if (!oldScreen || screen->currentWorkspace() != oldScreen->currentWorkspace()) Q_EMIT currentWorkspaceChanged(currentWorkspace()); if (oldScreen) { QVector oldModes; auto oldModesQmlList = oldScreen->availableModes(); for (int i = 0; i < oldModesQmlList.count(&oldModesQmlList); i++) { oldModes << oldModesQmlList.at(&oldModesQmlList, i); } QVector newModes; auto newModesQmlList = screen->availableModes(); for (int i = 0; i < newModesQmlList.count(&newModesQmlList); i++) { newModes << newModesQmlList.at(&newModesQmlList, i); } if (newModes != newModes) { Q_EMIT availableModesChanged(); } } else { Q_EMIT availableModesChanged(); } connectToScreen(screen); } ScreenAttached *WMScreen::qmlAttachedProperties(QObject *owner) { return new ScreenAttached(owner); }