Changeset View
Changeset View
Standalone View
Standalone View
plugins/qpa/window.cpp
1 | /******************************************************************** | 1 | /******************************************************************** | ||
---|---|---|---|---|---|
2 | KWin - the KDE window manager | 2 | KWin - the KDE window manager | ||
3 | This file is part of the KDE project. | 3 | This file is part of the KDE project. | ||
4 | 4 | | |||
5 | Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org> | 5 | Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org> | ||
6 | Copyright (C) 2019 Vlad Zagorodniy <vladzzag@gmail.com> | ||||
6 | 7 | | |||
7 | This program is free software; you can redistribute it and/or modify | 8 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | 9 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | 10 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | 11 | (at your option) any later version. | ||
11 | 12 | | |||
12 | This program is distributed in the hope that it will be useful, | 13 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | 16 | GNU General Public License for more details. | ||
16 | 17 | | |||
17 | You should have received a copy of the GNU General Public License | 18 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 20 | *********************************************************************/ | ||
20 | #include "window.h" | 21 | #include "window.h" | ||
21 | #include "integration.h" | | |||
22 | #include "screens.h" | 22 | #include "screens.h" | ||
23 | #include "../../shell_client.h" | 23 | | ||
24 | #include "../../wayland_server.h" | 24 | #include "internal_client.h" | ||
25 | | ||||
25 | #include <logging.h> | 26 | #include <logging.h> | ||
26 | 27 | | |||
27 | #include <QOpenGLFramebufferObject> | 28 | #include <QOpenGLFramebufferObject> | ||
28 | #include <qpa/qwindowsysteminterface.h> | 29 | #include <qpa/qwindowsysteminterface.h> | ||
29 | 30 | | |||
30 | #include <KWayland/Client/buffer.h> | | |||
31 | #include <KWayland/Client/connection_thread.h> | | |||
32 | #include <KWayland/Client/shell.h> | | |||
33 | #include <KWayland/Client/surface.h> | | |||
34 | | ||||
35 | namespace KWin | 31 | namespace KWin | ||
36 | { | 32 | { | ||
37 | namespace QPA | 33 | namespace QPA | ||
38 | { | 34 | { | ||
39 | static quint32 s_windowId = 0; | 35 | static quint32 s_windowId = 0; | ||
40 | 36 | | |||
41 | Window::Window(QWindow *window, KWayland::Client::Surface *surface, KWayland::Client::ShellSurface *shellSurface, const Integration *integration) | 37 | Window::Window(QWindow *window) | ||
42 | : QPlatformWindow(window) | 38 | : QPlatformWindow(window) | ||
43 | , m_surface(surface) | | |||
44 | , m_shellSurface(shellSurface) | | |||
45 | , m_windowId(++s_windowId) | 39 | , m_windowId(++s_windowId) | ||
46 | , m_integration(integration) | | |||
47 | , m_scale(screens()->maxScale()) | 40 | , m_scale(screens()->maxScale()) | ||
48 | { | 41 | { | ||
49 | m_surface->setScale(m_scale); | | |||
50 | | ||||
51 | QObject::connect(m_surface, &QObject::destroyed, window, [this] { m_surface = nullptr;}); | | |||
52 | QObject::connect(m_shellSurface, &QObject::destroyed, window, [this] { m_shellSurface = nullptr;}); | | |||
53 | waylandServer()->internalClientConection()->flush(); | | |||
54 | } | 42 | } | ||
55 | 43 | | |||
56 | Window::~Window() | 44 | Window::~Window() | ||
57 | { | 45 | { | ||
58 | unmap(); | 46 | unmap(); | ||
59 | delete m_shellSurface; | | |||
60 | delete m_surface; | | |||
61 | } | | |||
62 | | ||||
63 | WId Window::winId() const | | |||
64 | { | | |||
65 | return m_windowId; | | |||
66 | } | 47 | } | ||
67 | 48 | | |||
68 | void Window::setVisible(bool visible) | 49 | void Window::setVisible(bool visible) | ||
69 | { | 50 | { | ||
70 | if (!visible) { | 51 | if (visible) { | ||
52 | map(); | ||||
53 | } else { | ||||
71 | unmap(); | 54 | unmap(); | ||
72 | } | 55 | } | ||
56 | | ||||
73 | QPlatformWindow::setVisible(visible); | 57 | QPlatformWindow::setVisible(visible); | ||
74 | } | 58 | } | ||
75 | 59 | | |||
76 | void Window::setGeometry(const QRect &rect) | 60 | void Window::setGeometry(const QRect &rect) | ||
77 | { | 61 | { | ||
78 | const QRect &oldRect = geometry(); | 62 | const QRect &oldRect = geometry(); | ||
79 | QPlatformWindow::setGeometry(rect); | 63 | QPlatformWindow::setGeometry(rect); | ||
80 | if (rect.x() != oldRect.x()) { | 64 | if (rect.x() != oldRect.x()) { | ||
Show All 14 Lines | |||||
95 | if (m_contentFBO) { | 79 | if (m_contentFBO) { | ||
96 | if (m_contentFBO->size() != nativeSize) { | 80 | if (m_contentFBO->size() != nativeSize) { | ||
97 | m_resized = true; | 81 | m_resized = true; | ||
98 | } | 82 | } | ||
99 | } | 83 | } | ||
100 | QWindowSystemInterface::handleGeometryChange(window(), geometry()); | 84 | QWindowSystemInterface::handleGeometryChange(window(), geometry()); | ||
101 | } | 85 | } | ||
102 | 86 | | |||
103 | void Window::unmap() | 87 | WId Window::winId() const | ||
104 | { | 88 | { | ||
105 | if (m_shellClient) { | 89 | return m_windowId; | ||
106 | m_shellClient->setInternalFramebufferObject(QSharedPointer<QOpenGLFramebufferObject>()); | | |||
107 | } | | |||
108 | if (m_surface) { | | |||
109 | m_surface->attachBuffer(KWayland::Client::Buffer::Ptr()); | | |||
110 | m_surface->commit(KWayland::Client::Surface::CommitFlag::None); | | |||
111 | } | | |||
112 | if (waylandServer()->internalClientConection()) { | | |||
113 | waylandServer()->internalClientConection()->flush(); | | |||
114 | } | 90 | } | ||
91 | | ||||
92 | qreal Window::devicePixelRatio() const | ||||
93 | { | ||||
94 | return m_scale; | ||||
115 | } | 95 | } | ||
116 | 96 | | |||
117 | void Window::bindContentFBO() | 97 | void Window::bindContentFBO() | ||
118 | { | 98 | { | ||
119 | if (m_resized || !m_contentFBO) { | 99 | if (m_resized || !m_contentFBO) { | ||
120 | createFBO(); | 100 | createFBO(); | ||
121 | } | 101 | } | ||
122 | m_contentFBO->bind(); | 102 | m_contentFBO->bind(); | ||
123 | } | 103 | } | ||
124 | 104 | | |||
105 | const QSharedPointer<QOpenGLFramebufferObject> &Window::contentFBO() const | ||||
106 | { | ||||
107 | return m_contentFBO; | ||||
108 | } | ||||
109 | | ||||
125 | QSharedPointer<QOpenGLFramebufferObject> Window::swapFBO() | 110 | QSharedPointer<QOpenGLFramebufferObject> Window::swapFBO() | ||
126 | { | 111 | { | ||
127 | auto fbo = m_contentFBO; | 112 | QSharedPointer<QOpenGLFramebufferObject> fbo = m_contentFBO; | ||
128 | m_contentFBO.clear(); | 113 | m_contentFBO.clear(); | ||
129 | m_surface->commit(KWayland::Client::Surface::CommitFlag::None); | | |||
130 | return fbo; | 114 | return fbo; | ||
131 | } | 115 | } | ||
132 | 116 | | |||
117 | InternalClient *Window::client() const | ||||
118 | { | ||||
119 | return m_handle; | ||||
120 | } | ||||
121 | | ||||
133 | void Window::createFBO() | 122 | void Window::createFBO() | ||
134 | { | 123 | { | ||
135 | const QRect &r = geometry(); | 124 | const QRect &r = geometry(); | ||
136 | if (m_contentFBO && r.size().isEmpty()) { | 125 | if (m_contentFBO && r.size().isEmpty()) { | ||
137 | return; | 126 | return; | ||
138 | } | 127 | } | ||
139 | const QSize nativeSize = r.size() * m_scale; | 128 | const QSize nativeSize = r.size() * m_scale; | ||
140 | m_contentFBO.reset(new QOpenGLFramebufferObject(nativeSize.width(), nativeSize.height(), QOpenGLFramebufferObject::CombinedDepthStencil)); | 129 | m_contentFBO.reset(new QOpenGLFramebufferObject(nativeSize.width(), nativeSize.height(), QOpenGLFramebufferObject::CombinedDepthStencil)); | ||
141 | if (!m_contentFBO->isValid()) { | 130 | if (!m_contentFBO->isValid()) { | ||
142 | qCWarning(KWIN_QPA) << "Content FBO is not valid"; | 131 | qCWarning(KWIN_QPA) << "Content FBO is not valid"; | ||
143 | } | 132 | } | ||
144 | m_resized = false; | 133 | m_resized = false; | ||
145 | } | 134 | } | ||
146 | 135 | | |||
147 | ShellClient *Window::shellClient() | 136 | void Window::map() | ||
148 | { | 137 | { | ||
149 | if (!m_shellClient) { | 138 | if (m_handle) { | ||
150 | waylandServer()->dispatch(); | 139 | return; | ||
151 | m_shellClient = waylandServer()->findClient(window()); | | |||
152 | } | 140 | } | ||
153 | return m_shellClient; | 141 | | ||
142 | m_handle = new InternalClient(window()); | ||||
154 | } | 143 | } | ||
155 | 144 | | |||
156 | int Window::scale() const | 145 | void Window::unmap() | ||
157 | { | 146 | { | ||
158 | return m_scale; | 147 | if (!m_handle) { | ||
148 | return; | ||||
159 | } | 149 | } | ||
160 | 150 | | |||
161 | qreal Window::devicePixelRatio() const | 151 | m_handle->destroyClient(); | ||
162 | { | 152 | m_handle = nullptr; | ||
163 | return m_scale; | 153 | | ||
154 | m_contentFBO = nullptr; | ||||
164 | } | 155 | } | ||
165 | 156 | | |||
166 | } | 157 | } | ||
167 | } | 158 | } |