Loading...
Searching...
No Matches
Window.cpp
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "Window.h"
// lomiri-api
#include <lomiri/shell/application/MirSurfaceInterface.h>
#include <QQmlEngine>
#include <QTextStream>
namespace lomiriapi = lomiri::shell::application;
Q_LOGGING_CATEGORY(LOMIRI_WINDOW, "lomiri.window", QtWarningMsg)
#define DEBUG_MSG qCDebug(LOMIRI_WINDOW).nospace() << qPrintable(toString()) << "::" << __func__
#define WARNING_MSG qCWarning(LOMIRI_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 << "("<<value<<")";
m_allowClientResize = value;
if (m_surface) {
m_surface->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;
}
lomiriapi::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(lomiriapi::MirSurfaceInterface *surface)
{
DEBUG_MSG << "(" << surface << ")";
if (m_surface) {
disconnect(m_surface, 0, this, 0);
}
m_surface = surface;
if (m_surface) {
connect(surface, &lomiriapi::MirSurfaceInterface::focusRequested, this, [this]() {
Q_EMIT focusRequested();
});
connect(surface, &lomiriapi::MirSurfaceInterface::closeRequested, this, &Window::closeRequested);
connect(surface, &lomiriapi::MirSurfaceInterface::positionChanged, this, [this]() {
updatePosition();
});
connect(surface, &lomiriapi::MirSurfaceInterface::stateChanged, this, [this]() {
updateState();
});
connect(surface, &lomiriapi::MirSurfaceInterface::focusedChanged, this, [this]() {
updateFocused();
});
connect(surface, &lomiriapi::MirSurfaceInterface::allowClientResizeChanged, this, [this]() {
if (m_surface->allowClientResize() != m_allowClientResize) {
m_allowClientResize = m_surface->allowClientResize();
Q_EMIT allowClientResizeChanged(m_allowClientResize);
}
});
connect(surface, &lomiriapi::MirSurfaceInterface::liveChanged, this, &Window::liveChanged);
connect(surface, &QObject::destroyed, this, [this]() {
setSurface(nullptr);
});
// Surface should never be focused at this point!
if (m_surface->focused()) {
WARNING_MSG << "Initial surface is focused!";
}
// bring it up to speed
if (m_focused) {
m_surface->activate();
}
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="<<id()<<", ";
if (surface()) {
stream << "MirSurface["<<(void*)surface()<<",\""<<surface()->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;
}
Window
A slightly higher concept than MirSurface.
Definition Window.h:48
Window::allowClientResize
bool allowClientResize
Whether to comply to resize requests coming from the client side.
Definition Window.h:99
Window::requestState
void requestState(Mir::State state)
Requests a change to the specified state.
Definition Window.cpp:117
Window::id
int id
A unique identifier for this window. Useful for telling windows apart in a list model as they get mov...
Definition Window.h:84
Window::focusRequested
void focusRequested()
Emitted when focus for this window is requested by an external party.
Window::close
void close()
Sends a close request.
Definition Window.cpp:128
Window::surface
lomiri::shell::application::MirSurfaceInterface * surface
Surface backing up this window It might be null if a surface hasn't been created yet (application is ...
Definition Window.h:92
Window::requestedPosition
QPoint requestedPosition
Requested position of the current surface buffer, in pixels.
Definition Window.h:59
Window::confinesMousePointer
bool confinesMousePointer
Whether the surface wants to confine the mouse pointer within its boundaries.
Definition Window.h:78
Window::position
QPoint position
Position of the current surface buffer, in pixels.
Definition Window.h:54
Window::focused
bool focused
Whether the surface is focused.
Definition Window.h:71
Window::activate
void activate()
Focuses and raises the window.
Definition Window.cpp:137
Window::state
Mir::State state
State of the surface.
Definition Window.h:64