on master help sign in
268 lines 6.5 kB history raw
1/*
2 * Copyright (C) 2016-2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17#include "Window.h"
19// unity-api
20#include <unity/shell/application/MirSurfaceInterface.h>
22#include <QQmlEngine>
23#include <QTextStream>
25namespace unityapi = unity::shell::application;
27Q_LOGGING_CATEGORY(UNITY_WINDOW, "unity.window", QtWarningMsg)
29#define DEBUG_MSG qCDebug(UNITY_WINDOW).nospace() << qPrintable(toString()) << "::" << __func__
31Window::Window(int id, QObject *parent)
32 : QObject(parent)
33 , m_id(id)
35 DEBUG_MSG << "()";
36 QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
39Window::~Window()
41 DEBUG_MSG << "()";
44QPoint Window::position() const
46 return m_position;
49QPoint Window::requestedPosition() const
51 return m_requestedPosition;
54void Window::setRequestedPosition(const QPoint &value)
56 m_positionRequested = true;
57 if (value != m_requestedPosition) {
58 m_requestedPosition = value;
59 Q_EMIT requestedPositionChanged(m_requestedPosition);
60 if (m_surface) {
61 m_surface->setRequestedPosition(value);
62 } else {
63 // fake-miral: always comply
64 m_position = m_requestedPosition;
65 Q_EMIT positionChanged(m_position);
66 }
67 }
70bool Window::allowClientResize() const
72 return m_allowClientResize;
75void Window::setAllowClientResize(bool value)
77 if (value != m_allowClientResize) {
78 DEBUG_MSG << "("<<value<<")";
79 m_allowClientResize = value;
80 if (m_surface) {
81 m_surface->setAllowClientResize(value);
82 }
83 Q_EMIT allowClientResizeChanged(m_allowClientResize);
84 }
87Mir::State Window::state() const
89 return m_state;
92bool Window::focused() const
94 return m_focused;
97bool Window::confinesMousePointer() const
99 if (m_surface) {
100 return m_surface->confinesMousePointer();
101 } else {
102 return false;
103 }
106int Window::id() const
108 return m_id;
111unityapi::MirSurfaceInterface* Window::surface() const
113 return m_surface;
116void Window::requestState(Mir::State state)
118 m_stateRequested = true;
119 if (m_surface) {
120 m_surface->requestState(state);
121 } else if (m_state != state) {
122 m_state = state;
123 Q_EMIT stateChanged(m_state);
124 }
127void Window::close()
129 if (m_surface) {
130 m_surface->close();
131 } else {
132 Q_EMIT closeRequested();
133 }
136void Window::activate()
138 DEBUG_MSG << "()";
139 if (m_surface) {
140 m_surface->activate();
141 } else {
142 Q_EMIT emptyWindowActivated();
143 }
146void Window::setSurface(unityapi::MirSurfaceInterface *surface)
148 DEBUG_MSG << "(" << surface << ")";
149 if (m_surface) {
150 disconnect(m_surface, 0, this, 0);
151 }
153 m_surface = surface;
155 if (m_surface) {
156 connect(surface, &unityapi::MirSurfaceInterface::focusRequested, this, [this]() {
157 Q_EMIT focusRequested();
158 });
160 connect(surface, &unityapi::MirSurfaceInterface::closeRequested, this, &Window::closeRequested);
162 connect(surface, &unityapi::MirSurfaceInterface::positionChanged, this, [this]() {
163 updatePosition();
164 });
166 connect(surface, &unityapi::MirSurfaceInterface::stateChanged, this, [this]() {
167 updateState();
168 });
170 connect(surface, &unityapi::MirSurfaceInterface::focusedChanged, this, [this]() {
171 updateFocused();
172 });
174 connect(surface, &unityapi::MirSurfaceInterface::allowClientResizeChanged, this, [this]() {
175 if (m_surface->allowClientResize() != m_allowClientResize) {
176 m_allowClientResize = m_surface->allowClientResize();
177 Q_EMIT allowClientResizeChanged(m_allowClientResize);
178 }
179 });
181 connect(surface, &unityapi::MirSurfaceInterface::liveChanged, this, &Window::liveChanged);
183 connect(surface, &QObject::destroyed, this, [this]() {
184 setSurface(nullptr);
185 });
187 // bring it up to speed
188 if (m_positionRequested) {
189 m_surface->setRequestedPosition(m_requestedPosition);
190 }
191 if (m_stateRequested && m_surface->state() == Mir::RestoredState) {
192 m_surface->requestState(m_state);
193 }
194 m_surface->setAllowClientResize(m_allowClientResize);
196 // and sync with surface
197 updatePosition();
198 updateState();
199 updateFocused();
200 }
202 Q_EMIT surfaceChanged(surface);
205void Window::updatePosition()
207 if (m_surface->position() != m_position) {
208 m_position = m_surface->position();
209 Q_EMIT positionChanged(m_position);
210 }
213void Window::updateState()
215 if (m_surface->state() != m_state) {
216 m_state = m_surface->state();
217 Q_EMIT stateChanged(m_state);
218 }
221void Window::updateFocused()
223 if (m_surface->focused() != m_focused) {
224 m_focused = m_surface->focused();
225 Q_EMIT focusedChanged(m_focused);
226 }
229void Window::setFocused(bool value)
231 if (value != m_focused) {
232 DEBUG_MSG << "(" << value << ")";
233 m_focused = value;
234 Q_EMIT focusedChanged(m_focused);
235 // when we have a surface we get focus changes from updateFocused() instead
236 Q_ASSERT(!m_surface);
237 }
240QString Window::toString() const
242 QString result;
243 {
244 QTextStream stream(&result);
245 stream << "Window["<<(void*)this<<", id="<<id()<<", ";
246 if (surface()) {
247 stream << "MirSurface["<<(void*)surface()<<",\""<<surface()->name()<<"\"]";
248 } else {
249 stream << "null";
250 }
251 stream << "]";
252 }
253 return result;
256QDebug operator<<(QDebug dbg, const Window *window)
258 QDebugStateSaver saver(dbg);
259 dbg.nospace();
261 if (window) {
262 dbg << qPrintable(window->toString());
263 } else {
264 dbg << (void*)(window);
265 }
267 return dbg;