/* * Copyright (C) 2016-2017 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "Window.h" // unity-api #include #include #include namespace unityapi = unity::shell::application; Q_LOGGING_CATEGORY(UNITY_WINDOW, "unity.window", QtWarningMsg) #define DEBUG_MSG qCDebug(UNITY_WINDOW).nospace() << qPrintable(toString()) << "::" << __func__ Window::Window(int id, QObject *parent) : QObject(parent) , m_id(id) { DEBUG_MSG << "()"; QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); } Window::~Window() { DEBUG_MSG << "()"; } QPoint Window::position() const { return m_position; } QPoint Window::requestedPosition() const { return m_requestedPosition; } void Window::setRequestedPosition(const QPoint &value) { m_positionRequested = true; if (value != m_requestedPosition) { m_requestedPosition = value; Q_EMIT requestedPositionChanged(m_requestedPosition); if (m_surface) { m_surface->setRequestedPosition(value); } else { // fake-miral: always comply m_position = m_requestedPosition; Q_EMIT positionChanged(m_position); } } } bool Window::allowClientResize() const { return m_allowClientResize; } void Window::setAllowClientResize(bool value) { if (value != m_allowClientResize) { DEBUG_MSG << "("<setAllowClientResize(value); } Q_EMIT allowClientResizeChanged(m_allowClientResize); } } Mir::State Window::state() const { return m_state; } bool Window::focused() const { return m_focused; } bool Window::confinesMousePointer() const { if (m_surface) { return m_surface->confinesMousePointer(); } else { return false; } } int Window::id() const { return m_id; } unityapi::MirSurfaceInterface* Window::surface() const { return m_surface; } void Window::requestState(Mir::State state) { m_stateRequested = true; if (m_surface) { m_surface->requestState(state); } else if (m_state != state) { m_state = state; Q_EMIT stateChanged(m_state); } } void Window::close() { if (m_surface) { m_surface->close(); } else { Q_EMIT closeRequested(); } } void Window::activate() { DEBUG_MSG << "()"; if (m_surface) { m_surface->activate(); } else { Q_EMIT emptyWindowActivated(); } } void Window::setSurface(unityapi::MirSurfaceInterface *surface) { DEBUG_MSG << "(" << surface << ")"; if (m_surface) { disconnect(m_surface, 0, this, 0); } m_surface = surface; if (m_surface) { connect(surface, &unityapi::MirSurfaceInterface::focusRequested, this, [this]() { Q_EMIT focusRequested(); }); connect(surface, &unityapi::MirSurfaceInterface::closeRequested, this, &Window::closeRequested); connect(surface, &unityapi::MirSurfaceInterface::positionChanged, this, [this]() { updatePosition(); }); connect(surface, &unityapi::MirSurfaceInterface::stateChanged, this, [this]() { updateState(); }); connect(surface, &unityapi::MirSurfaceInterface::focusedChanged, this, [this]() { updateFocused(); }); connect(surface, &unityapi::MirSurfaceInterface::allowClientResizeChanged, this, [this]() { if (m_surface->allowClientResize() != m_allowClientResize) { m_allowClientResize = m_surface->allowClientResize(); Q_EMIT allowClientResizeChanged(m_allowClientResize); } }); connect(surface, &unityapi::MirSurfaceInterface::liveChanged, this, &Window::liveChanged); connect(surface, &QObject::destroyed, this, [this]() { setSurface(nullptr); }); // bring it up to speed if (m_positionRequested) { m_surface->setRequestedPosition(m_requestedPosition); } if (m_stateRequested && m_surface->state() == Mir::RestoredState) { m_surface->requestState(m_state); } m_surface->setAllowClientResize(m_allowClientResize); // and sync with surface updatePosition(); updateState(); updateFocused(); } Q_EMIT surfaceChanged(surface); } void Window::updatePosition() { if (m_surface->position() != m_position) { m_position = m_surface->position(); Q_EMIT positionChanged(m_position); } } void Window::updateState() { if (m_surface->state() != m_state) { m_state = m_surface->state(); Q_EMIT stateChanged(m_state); } } void Window::updateFocused() { if (m_surface->focused() != m_focused) { m_focused = m_surface->focused(); Q_EMIT focusedChanged(m_focused); } } void Window::setFocused(bool value) { if (value != m_focused) { DEBUG_MSG << "(" << value << ")"; m_focused = value; Q_EMIT focusedChanged(m_focused); // when we have a surface we get focus changes from updateFocused() instead Q_ASSERT(!m_surface); } } QString Window::toString() const { QString result; { QTextStream stream(&result); stream << "Window["<<(void*)this<<", id="<name()<<"\"]"; } else { stream << "null"; } stream << "]"; } return result; } QDebug operator<<(QDebug dbg, const Window *window) { QDebugStateSaver saver(dbg); dbg.nospace(); if (window) { dbg << qPrintable(window->toString()); } else { dbg << (void*)(window); } return dbg; }