Loading...
Searching...
No Matches
ScreenAttached.cpp
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "ScreenAttached.h"
#include "ScreenWindow.h"
#include "Screens.h"
#include <QQuickItem>
#include <QScreen>
namespace
{
QQuickItem* itemForOwner(QObject* obj) {
QObject* parent = obj;
while(parent) {
auto item = qobject_cast<QQuickItem*>(parent);
if (item) return item;
parent = parent->parent();
}
return nullptr;
}
} // namesapce
ScreenAttached::ScreenAttached(QObject *owner)
: Screen(owner)
, m_window(nullptr)
{
if (auto item = itemForOwner(owner)) {
connect(item, &QQuickItem::windowChanged, this, &ScreenAttached::windowChanged);
windowChanged(item->window());
} else if (auto window = qobject_cast<QQuickWindow*>(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<ScreenWindow*>(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<qtmir::ScreenMode*> oldModes;
auto oldModesQmlList = oldScreen->availableModes();
for (int i = 0; i < oldModesQmlList.count(&oldModesQmlList); i++) {
oldModes << oldModesQmlList.at(&oldModesQmlList, i);
}
QVector<qtmir::ScreenMode*> 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);
}