Changeset View
Changeset View
Standalone View
Standalone View
plugins/qpa/window.cpp
Show All 14 Lines | |||||
15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU General Public License | 17 | 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/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #define WL_EGL_PLATFORM 1 | 20 | #define WL_EGL_PLATFORM 1 | ||
21 | #include "integration.h" | 21 | #include "integration.h" | ||
22 | #include "window.h" | 22 | #include "window.h" | ||
23 | #include "screens.h" | ||||
23 | #include "../../shell_client.h" | 24 | #include "../../shell_client.h" | ||
24 | #include "../../wayland_server.h" | 25 | #include "../../wayland_server.h" | ||
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/buffer.h> | ||
31 | #include <KWayland/Client/connection_thread.h> | 32 | #include <KWayland/Client/connection_thread.h> | ||
32 | #include <KWayland/Client/shell.h> | 33 | #include <KWayland/Client/shell.h> | ||
33 | #include <KWayland/Client/surface.h> | 34 | #include <KWayland/Client/surface.h> | ||
34 | 35 | | |||
35 | namespace KWin | 36 | namespace KWin | ||
36 | { | 37 | { | ||
37 | namespace QPA | 38 | namespace QPA | ||
38 | { | 39 | { | ||
39 | static quint32 s_windowId = 0; | 40 | static quint32 s_windowId = 0; | ||
40 | 41 | | |||
41 | Window::Window(QWindow *window, KWayland::Client::Surface *surface, KWayland::Client::ShellSurface *shellSurface, const Integration *integration) | 42 | Window::Window(QWindow *window, KWayland::Client::Surface *surface, KWayland::Client::ShellSurface *shellSurface, const Integration *integration) | ||
42 | : QPlatformWindow(window) | 43 | : QPlatformWindow(window) | ||
43 | , m_surface(surface) | 44 | , m_surface(surface) | ||
44 | , m_shellSurface(shellSurface) | 45 | , m_shellSurface(shellSurface) | ||
45 | , m_windowId(++s_windowId) | 46 | , m_windowId(++s_windowId) | ||
46 | , m_integration(integration) | 47 | , m_integration(integration) | ||
48 | , m_scale(screens()->maxScale()) | ||||
47 | { | 49 | { | ||
50 | m_surface->setScale(m_scale); | ||||
51 | | ||||
48 | QObject::connect(m_surface, &QObject::destroyed, window, [this] { m_surface = nullptr;}); | 52 | QObject::connect(m_surface, &QObject::destroyed, window, [this] { m_surface = nullptr;}); | ||
49 | QObject::connect(m_shellSurface, &QObject::destroyed, window, [this] { m_shellSurface = nullptr;}); | 53 | QObject::connect(m_shellSurface, &QObject::destroyed, window, [this] { m_shellSurface = nullptr;}); | ||
50 | waylandServer()->internalClientConection()->flush(); | 54 | waylandServer()->internalClientConection()->flush(); | ||
55 | | ||||
51 | } | 56 | } | ||
52 | 57 | | |||
53 | Window::~Window() | 58 | Window::~Window() | ||
54 | { | 59 | { | ||
55 | unmap(); | 60 | unmap(); | ||
56 | if (m_eglSurface != EGL_NO_SURFACE) { | 61 | if (m_eglSurface != EGL_NO_SURFACE) { | ||
57 | eglDestroySurface(m_integration->eglDisplay(), m_eglSurface); | 62 | eglDestroySurface(m_integration->eglDisplay(), m_eglSurface); | ||
58 | } | 63 | } | ||
Show All 17 Lines | 80 | if (!visible) { | |||
76 | unmap(); | 81 | unmap(); | ||
77 | } | 82 | } | ||
78 | QPlatformWindow::setVisible(visible); | 83 | QPlatformWindow::setVisible(visible); | ||
79 | } | 84 | } | ||
80 | 85 | | |||
81 | void Window::setGeometry(const QRect &rect) | 86 | void Window::setGeometry(const QRect &rect) | ||
82 | { | 87 | { | ||
83 | const QRect &oldRect = geometry(); | 88 | const QRect &oldRect = geometry(); | ||
89 | | ||||
84 | QPlatformWindow::setGeometry(rect); | 90 | QPlatformWindow::setGeometry(rect); | ||
85 | if (rect.x() != oldRect.x()) { | 91 | if (rect.x() != oldRect.x()) { | ||
86 | emit window()->xChanged(rect.x()); | 92 | emit window()->xChanged(rect.x()); | ||
87 | } | 93 | } | ||
88 | if (rect.y() != oldRect.y()) { | 94 | if (rect.y() != oldRect.y()) { | ||
89 | emit window()->yChanged(rect.y()); | 95 | emit window()->yChanged(rect.y()); | ||
90 | } | 96 | } | ||
91 | if (rect.width() != oldRect.width()) { | 97 | if (rect.width() != oldRect.width()) { | ||
92 | emit window()->widthChanged(rect.width()); | 98 | emit window()->widthChanged(rect.width()); | ||
93 | } | 99 | } | ||
94 | if (rect.height() != oldRect.height()) { | 100 | if (rect.height() != oldRect.height()) { | ||
95 | emit window()->heightChanged(rect.height()); | 101 | emit window()->heightChanged(rect.height()); | ||
96 | } | 102 | } | ||
103 | | ||||
104 | const QSize nativeSize = rect.size() * m_scale; | ||||
105 | | ||||
97 | if (m_contentFBO) { | 106 | if (m_contentFBO) { | ||
98 | if (m_contentFBO->width() != geometry().width() || m_contentFBO->height() != geometry().height()) { | 107 | if (m_contentFBO->size() != nativeSize) { | ||
zzag: Should it be floored or rounded? | |||||
davidedmundson: Everything is an int | |||||
Oh, shoot, I always think of scale as qreal, sorry. More simpler version: if (m_contentFBO->size() != geometry().size() * m_scale) { zzag: Oh, shoot, I always think of scale as qreal, sorry. More simpler version:
```lang=cpp
if… | |||||
99 | m_resized = true; | 108 | m_resized = true; | ||
100 | } | 109 | } | ||
101 | } | 110 | } | ||
102 | #if HAVE_WAYLAND_EGL | 111 | #if HAVE_WAYLAND_EGL | ||
103 | if (m_eglWaylandWindow) { | 112 | if (m_eglWaylandWindow) { | ||
104 | wl_egl_window_resize(m_eglWaylandWindow, geometry().width(), geometry().height(), 0, 0); | 113 | wl_egl_window_resize(m_eglWaylandWindow, nativeSize.width(), nativeSize.height(), 0, 0); | ||
105 | } | 114 | } | ||
106 | #endif | 115 | #endif | ||
107 | QWindowSystemInterface::handleGeometryChange(window(), geometry()); | 116 | QWindowSystemInterface::handleGeometryChange(window(), geometry()); | ||
108 | } | 117 | } | ||
109 | 118 | | |||
110 | void Window::unmap() | 119 | void Window::unmap() | ||
111 | { | 120 | { | ||
112 | if (m_shellClient) { | 121 | if (m_shellClient) { | ||
113 | m_shellClient->setInternalFramebufferObject(QSharedPointer<QOpenGLFramebufferObject>()); | 122 | m_shellClient->setInternalFramebufferObject(QSharedPointer<QOpenGLFramebufferObject>()); | ||
114 | } | 123 | } | ||
115 | if (m_surface) { | 124 | if (m_surface) { | ||
116 | m_surface->attachBuffer(KWayland::Client::Buffer::Ptr()); | 125 | m_surface->attachBuffer(KWayland::Client::Buffer::Ptr()); | ||
117 | m_surface->commit(KWayland::Client::Surface::CommitFlag::None); | 126 | m_surface->commit(KWayland::Client::Surface::CommitFlag::None); | ||
118 | } | 127 | } | ||
119 | if (waylandServer()->internalClientConection()) { | 128 | if (waylandServer()->internalClientConection()) { | ||
120 | waylandServer()->internalClientConection()->flush(); | 129 | waylandServer()->internalClientConection()->flush(); | ||
121 | } | 130 | } | ||
122 | } | 131 | } | ||
123 | 132 | | |||
124 | void Window::createEglSurface(EGLDisplay dpy, EGLConfig config) | 133 | void Window::createEglSurface(EGLDisplay dpy, EGLConfig config) | ||
125 | { | 134 | { | ||
126 | #if HAVE_WAYLAND_EGL | 135 | #if HAVE_WAYLAND_EGL | ||
127 | const QSize size = window()->size(); | 136 | const QSize size = window()->size() * m_scale; | ||
128 | m_eglWaylandWindow = wl_egl_window_create(*m_surface, size.width(), size.height()); | 137 | m_eglWaylandWindow = wl_egl_window_create(*m_surface, size.width(), size.height()); | ||
129 | if (!m_eglWaylandWindow) { | 138 | if (!m_eglWaylandWindow) { | ||
130 | return; | 139 | return; | ||
131 | } | 140 | } | ||
132 | m_eglSurface = eglCreateWindowSurface(dpy, config, m_eglWaylandWindow, nullptr); | 141 | m_eglSurface = eglCreateWindowSurface(dpy, config, m_eglWaylandWindow, nullptr); | ||
133 | #else | 142 | #else | ||
134 | Q_UNUSED(dpy) | 143 | Q_UNUSED(dpy) | ||
135 | Q_UNUSED(config) | 144 | Q_UNUSED(config) | ||
Show All 17 Lines | |||||
153 | } | 162 | } | ||
154 | 163 | | |||
155 | void Window::createFBO() | 164 | void Window::createFBO() | ||
156 | { | 165 | { | ||
157 | const QRect &r = geometry(); | 166 | const QRect &r = geometry(); | ||
158 | if (m_contentFBO && r.size().isEmpty()) { | 167 | if (m_contentFBO && r.size().isEmpty()) { | ||
159 | return; | 168 | return; | ||
160 | } | 169 | } | ||
161 | m_contentFBO.reset(new QOpenGLFramebufferObject(r.width(), r.height(), QOpenGLFramebufferObject::CombinedDepthStencil)); | 170 | const QSize nativeSize = r.size() * m_scale; | ||
171 | m_contentFBO.reset(new QOpenGLFramebufferObject(nativeSize.width(), nativeSize.height(), QOpenGLFramebufferObject::CombinedDepthStencil)); | ||||
162 | if (!m_contentFBO->isValid()) { | 172 | if (!m_contentFBO->isValid()) { | ||
163 | qCWarning(KWIN_QPA) << "Content FBO is not valid"; | 173 | qCWarning(KWIN_QPA) << "Content FBO is not valid"; | ||
164 | } | 174 | } | ||
165 | m_resized = false; | 175 | m_resized = false; | ||
166 | } | 176 | } | ||
167 | 177 | | |||
168 | ShellClient *Window::shellClient() | 178 | ShellClient *Window::shellClient() | ||
169 | { | 179 | { | ||
170 | if (!m_shellClient) { | 180 | if (!m_shellClient) { | ||
171 | waylandServer()->dispatch(); | 181 | waylandServer()->dispatch(); | ||
172 | m_shellClient = waylandServer()->findClient(window()); | 182 | m_shellClient = waylandServer()->findClient(window()); | ||
173 | } | 183 | } | ||
174 | return m_shellClient; | 184 | return m_shellClient; | ||
175 | } | 185 | } | ||
176 | 186 | | |||
187 | int Window::scale() const | ||||
188 | { | ||||
189 | return m_scale; | ||||
190 | } | ||||
191 | | ||||
192 | qreal Window::devicePixelRatio() const | ||||
193 | { | ||||
194 | return m_scale; | ||||
195 | } | ||||
196 | | ||||
177 | } | 197 | } | ||
178 | } | 198 | } |
Should it be floored or rounded?