Lomiri
Loading...
Searching...
No Matches
Window.cpp
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 */
16
17#include "Window.h"
18
19// lomiri-api
20#include <lomiri/shell/application/MirSurfaceInterface.h>
21
22#include <QQmlEngine>
23#include <QTextStream>
24
25namespace lomiriapi = lomiri::shell::application;
26
27Q_LOGGING_CATEGORY(LOMIRI_WINDOW, "lomiri.window", QtWarningMsg)
28
29#define DEBUG_MSG qCDebug(LOMIRI_WINDOW).nospace() << qPrintable(toString()) << "::" << __func__
30#define WARNING_MSG qCWarning(LOMIRI_WINDOW).nospace() << qPrintable(toString()) << "::" << __func__
31
32Window::Window(int id, QObject *parent)
33 : QObject(parent)
34 , m_id(id)
35{
36 DEBUG_MSG << "()";
37 QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
38}
39
40Window::~Window()
41{
42 DEBUG_MSG << "()";
43}
44
45QPoint Window::position() const
46{
47 return m_position;
48}
49
50QPoint Window::requestedPosition() const
51{
52 return m_requestedPosition;
53}
54
55void Window::setRequestedPosition(const QPoint &value)
56{
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 }
69}
70
72{
73 return m_allowClientResize;
74}
75
76void Window::setAllowClientResize(bool value)
77{
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 }
86}
87
88Mir::State Window::state() const
89{
90 return m_state;
91}
92
93bool Window::focused() const
94{
95 return m_focused;
96}
97
99{
100 if (m_surface) {
101 return m_surface->confinesMousePointer();
102 } else {
103 return false;
104 }
105}
106
107int Window::id() const
108{
109 return m_id;
110}
111
112lomiriapi::MirSurfaceInterface* Window::surface() const
113{
114 return m_surface;
115}
116
117void Window::requestState(Mir::State state)
118{
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 }
126}
127
129{
130 if (m_surface) {
131 m_surface->close();
132 } else {
133 Q_EMIT closeRequested();
134 }
135}
136
138{
139 DEBUG_MSG << "()";
140 if (m_surface) {
141 m_surface->activate();
142 } else {
143 Q_EMIT emptyWindowActivated();
144 }
145}
146
147void Window::setSurface(lomiriapi::MirSurfaceInterface *surface)
148{
149 DEBUG_MSG << "(" << surface << ")";
150 if (m_surface) {
151 disconnect(m_surface, 0, this, 0);
152 }
153
154 m_surface = surface;
155
156 if (m_surface) {
157 connect(surface, &lomiriapi::MirSurfaceInterface::focusRequested, this, [this]() {
158 Q_EMIT focusRequested();
159 });
160
161 connect(surface, &lomiriapi::MirSurfaceInterface::closeRequested, this, &Window::closeRequested);
162
163 connect(surface, &lomiriapi::MirSurfaceInterface::positionChanged, this, [this]() {
164 updatePosition();
165 });
166
167 connect(surface, &lomiriapi::MirSurfaceInterface::stateChanged, this, [this]() {
168 updateState();
169 });
170
171 connect(surface, &lomiriapi::MirSurfaceInterface::focusedChanged, this, [this]() {
172 updateFocused();
173 });
174
175 connect(surface, &lomiriapi::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 });
181
182 connect(surface, &lomiriapi::MirSurfaceInterface::liveChanged, this, &Window::liveChanged);
183
184 connect(surface, &QObject::destroyed, this, [this]() {
185 setSurface(nullptr);
186 });
187
188 // Surface should never be focused at this point!
189 if (m_surface->focused()) {
190 WARNING_MSG << "Initial surface is focused!";
191 }
192
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);
204
205 // and sync with surface
206 updatePosition();
207 updateState();
208 updateFocused();
209 }
210
211 Q_EMIT surfaceChanged(surface);
212}
213
214void Window::updatePosition()
215{
216 if (m_surface->position() != m_position) {
217 m_position = m_surface->position();
218 Q_EMIT positionChanged(m_position);
219 }
220}
221
222void Window::updateState()
223{
224 if (m_surface->state() != m_state) {
225 m_state = m_surface->state();
226 Q_EMIT stateChanged(m_state);
227 }
228}
229
230void Window::updateFocused()
231{
232 if (m_surface->focused() != m_focused) {
233 m_focused = m_surface->focused();
234 Q_EMIT focusedChanged(m_focused);
235 }
236}
237
238void Window::setFocused(bool value)
239{
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 }
247}
248
249QString Window::toString() const
250{
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;
263}
264
265QDebug operator<<(QDebug dbg, const Window *window)
266{
267 QDebugStateSaver saver(dbg);
268 dbg.nospace();
269
270 if (window) {
271 dbg << qPrintable(window->toString());
272 } else {
273 dbg << (void*)(window);
274 }
275
276 return dbg;
277}
A slightly higher concept than MirSurface.
Definition Window.h:48
bool allowClientResize
Whether to comply to resize requests coming from the client side.
Definition Window.h:99
void requestState(Mir::State state)
Requests a change to the specified state.
Definition Window.cpp:117
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
void focusRequested()
Emitted when focus for this window is requested by an external party.
void close()
Sends a close request.
Definition Window.cpp:128
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
QPoint requestedPosition
Requested position of the current surface buffer, in pixels.
Definition Window.h:59
bool confinesMousePointer
Whether the surface wants to confine the mouse pointer within its boundaries.
Definition Window.h:78
QPoint position
Position of the current surface buffer, in pixels.
Definition Window.h:54
bool focused
Whether the surface is focused.
Definition Window.h:71
void activate()
Focuses and raises the window.
Definition Window.cpp:137
Mir::State state
State of the surface.
Definition Window.h:64