on 620a196 help sign in
277 lines 6.8 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__
30#define WARNING_MSG qCWarning(UNITY_WINDOW).nospace() << qPrintable(toString()) << "::" << __func__
32Window::Window(int id, QObject *parent)
33 : QObject(parent)
34 , m_id(id)
36 DEBUG_MSG << "()";
37 QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
40Window::~Window()
42 DEBUG_MSG << "()";
45QPoint Window::position() const
47 return m_position;
50QPoint Window::requestedPosition() const
52 return m_requestedPosition;
55void Window::setRequestedPosition(const QPoint &value)
57 m_positionRequested = true;
58 if (value != m_requestedPosition) {
59 m_requestedPosition = value;
60 Q_EMIT requestedPositionChanged(m_requestedPosition);
61 if (m_surface) {
62 m_surface->setRequestedPosition(value);
63 } else {
64 // fake-miral: always comply
65 m_position = m_requestedPosition;
66 Q_EMIT positionChanged(m_position);
67 }
68 }
71bool Window::allowClientResize() const
73 return m_allowClientResize;
76void Window::setAllowClientResize(bool value)
78 if (value != m_allowClientResize) {
79 DEBUG_MSG << "("<<value<<")";
80 m_allowClientResize = value;
81 if (m_surface) {
82 m_surface->setAllowClientResize(value);
83 }
84 Q_EMIT allowClientResizeChanged(m_allowClientResize);
85 }
88Mir::State Window::state() const
90 return m_state;
93bool Window::focused() const
95 return m_focused;
98bool Window::confinesMousePointer() const
100 if (m_surface) {
101 return m_surface->confinesMousePointer();
102 } else {
103 return false;
104 }
107int Window::id() const
109 return m_id;
112unityapi::MirSurfaceInterface* Window::surface() const
114 return m_surface;
117void Window::requestState(Mir::State state)
119 m_stateRequested = true;
120 if (m_surface) {
121 m_surface->requestState(state);
122 } else if (m_state != state) {
123 m_state = state;
124 Q_EMIT stateChanged(m_state);
125 }
128void Window::close()
130 if (m_surface) {
131 m_surface->close();
132 } else {
133 Q_EMIT closeRequested();
134 }
137void Window::activate()
139 DEBUG_MSG << "()";
140 if (m_surface) {
141 m_surface->activate();
142 } else {
143 Q_EMIT emptyWindowActivated();
144 }
147void Window::setSurface(unityapi::MirSurfaceInterface *surface)
149 DEBUG_MSG << "(" << surface << ")";
150 if (m_surface) {
151 disconnect(m_surface, 0, this, 0);
152 }
154 m_surface = surface;
156 if (m_surface) {
157 connect(surface, &unityapi::MirSurfaceInterface::focusRequested, this, [this]() {
158 Q_EMIT focusRequested();
159 });
161 connect(surface, &unityapi::MirSurfaceInterface::closeRequested, this, &Window::closeRequested);
163 connect(surface, &unityapi::MirSurfaceInterface::positionChanged, this, [this]() {
164 updatePosition();
165 });
167 connect(surface, &unityapi::MirSurfaceInterface::stateChanged, this, [this]() {
168 updateState();
169 });
171 connect(surface, &unityapi::MirSurfaceInterface::focusedChanged, this, [this]() {
172 updateFocused();
173 });
175 connect(surface, &unityapi::MirSurfaceInterface::allowClientResizeChanged, this, [this]() {
176 if (m_surface->allowClientResize() != m_allowClientResize) {
177 m_allowClientResize = m_surface->allowClientResize();
178 Q_EMIT allowClientResizeChanged(m_allowClientResize);
179 }
180 });
182 connect(surface, &unityapi::MirSurfaceInterface::liveChanged, this, &Window::liveChanged);
184 connect(surface, &QObject::destroyed, this, [this]() {
185 setSurface(nullptr);
186 });
188 // Surface should never be focused at this point!
189 if (m_surface->focused()) {
190 WARNING_MSG << "Inital surface is focused!";
191 }
193 // bring it up to speed
194 if (m_focused) {
195 m_surface->activate();
196 }
197 if (m_positionRequested) {
198 m_surface->setRequestedPosition(m_requestedPosition);
199 }
200 if (m_stateRequested && m_surface->state() == Mir::RestoredState) {
201 m_surface->requestState(m_state);
202 }
203 m_surface->setAllowClientResize(m_allowClientResize);
205 // and sync with surface
206 updatePosition();
207 updateState();
208 updateFocused();
209 }
211 Q_EMIT surfaceChanged(surface);
214void Window::updatePosition()
216 if (m_surface->position() != m_position) {
217 m_position = m_surface->position();
218 Q_EMIT positionChanged(m_position);
219 }
222void Window::updateState()
224 if (m_surface->state() != m_state) {
225 m_state = m_surface->state();
226 Q_EMIT stateChanged(m_state);
227 }
230void Window::updateFocused()
232 if (m_surface->focused() != m_focused) {
233 m_focused = m_surface->focused();
234 Q_EMIT focusedChanged(m_focused);
235 }
238void Window::setFocused(bool value)
240 if (value != m_focused) {
241 DEBUG_MSG << "(" << value << ")";
242 m_focused = value;
243 Q_EMIT focusedChanged(m_focused);
244 // when we have a surface we get focus changes from updateFocused() instead
245 Q_ASSERT(!m_surface);
246 }
249QString Window::toString() const
251 QString result;
252 {
253 QTextStream stream(&result);
254 stream << "Window["<<(void*)this<<", id="<<id()<<", ";
255 if (surface()) {
256 stream << "MirSurface["<<(void*)surface()<<",\""<<surface()->name()<<"\"]";
257 } else {
258 stream << "null";
259 }
260 stream << "]";
261 }
262 return result;
265QDebug operator<<(QDebug dbg, const Window *window)
267 QDebugStateSaver saver(dbg);
268 dbg.nospace();
270 if (window) {
271 dbg << qPrintable(window->toString());
272 } else {
273 dbg << (void*)(window);
274 }
276 return dbg;