2
* Copyright (C) 2014-2016 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1
/****************************************************************************
3
** Copyright (C) 2014-2016 Canonical, Ltd.
4
** Contact: https://www.qt.io/licensing/
6
** This file is part of the plugins of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
38
****************************************************************************/
18
#include "integration.h"
19
#include "backingstore.h"
20
#include "clipboard.h"
21
#include "desktopwindow.h"
22
#include "debugextension.h"
23
#include "glcontext.h"
26
#include "nativeinterface.h"
42
#include "qmirclientintegration.h"
43
#include "qmirclientbackingstore.h"
44
#include "qmirclientclipboard.h"
45
#include "qmirclientdebugextension.h"
46
#include "qmirclientdesktopwindow.h"
47
#include "qmirclientglcontext.h"
48
#include "qmirclientinput.h"
49
#include "qmirclientlogging.h"
50
#include "qmirclientnativeinterface.h"
51
#include "qmirclientscreen.h"
52
#include "qmirclientwindow.h"
31
55
#include <QFileInfo>
32
56
#include <QGuiApplication>
33
#include <private/qeglpbuffer_p.h>
34
57
#include <qpa/qplatformnativeinterface.h>
35
58
#include <qpa/qplatforminputcontextfactory_p.h>
36
59
#include <qpa/qplatforminputcontext.h>
72
95
static void resumedCallback(const UApplicationOptions */*options*/, void *context)
74
auto integration = static_cast<UbuntuClientIntegration*>(context);
97
auto integration = static_cast<QMirClientClientIntegration*>(context);
75
98
integration->appStateController()->setResumed();
78
101
static void aboutToStopCallback(UApplicationArchive */*archive*/, void *context)
80
auto integration = static_cast<UbuntuClientIntegration*>(context);
103
auto integration = static_cast<QMirClientClientIntegration*>(context);
81
104
auto inputContext = integration->inputContext();
82
105
if (inputContext) {
83
106
inputContext->hideInputPanel();
85
qCWarning(ubuntumirclient) << "aboutToStopCallback(): no input context";
108
qCWarning(mirclient) << "aboutToStopCallback(): no input context";
87
110
integration->appStateController()->setSuspended();
91
UbuntuClientIntegration::UbuntuClientIntegration(int argc, char **argv)
114
QMirClientClientIntegration::QMirClientClientIntegration(int argc, char **argv)
92
115
: QPlatformIntegration()
93
, mNativeInterface(new UbuntuNativeInterface(this))
116
, mNativeInterface(new QMirClientNativeInterface(this))
94
117
, mFontDb(new QGenericUnixFontDatabase)
95
, mServices(new UbuntuPlatformServices)
96
, mAppStateController(new UbuntuAppStateController)
118
, mServices(new QMirClientPlatformServices)
119
, mAppStateController(new QMirClientAppStateController)
97
120
, mScaleFactor(1.0)
99
122
QByteArray sessionName;
142
165
if (testability) {
143
mDebugExtension.reset(new UbuntuDebugExtension);
166
mDebugExtension.reset(new QMirClientDebugExtension);
144
167
if (!mDebugExtension->isEnabled()) {
145
168
mDebugExtension.reset();
150
void UbuntuClientIntegration::initialize()
173
void QMirClientClientIntegration::initialize()
152
175
// Init the ScreenObserver
153
mScreenObserver.reset(new UbuntuScreenObserver(mMirConnection));
154
connect(mScreenObserver.data(), &UbuntuScreenObserver::screenAdded,
155
[this](UbuntuScreen *screen) { this->screenAdded(screen); });
156
connect(mScreenObserver.data(), &UbuntuScreenObserver::screenRemoved,
157
this, &UbuntuClientIntegration::destroyScreen);
176
mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection));
177
connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded,
178
[this](QMirClientScreen *screen) { this->screenAdded(screen); });
179
connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved,
180
this, &QMirClientClientIntegration::destroyScreen);
159
Q_FOREACH(auto screen, mScreenObserver->screens()) {
182
Q_FOREACH (auto screen, mScreenObserver->screens()) {
160
183
screenAdded(screen);
163
186
// Initialize input.
164
mInput = new UbuntuInput(this);
187
mInput = new QMirClientInput(this);
165
188
mInputContext = QPlatformInputContextFactory::create();
167
190
// compute the scale factor
249
272
return "qmlscene";
252
QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const
275
QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
254
277
if (window->type() == Qt::Desktop) {
255
278
// Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should).
256
return new UbuntuDesktopWindow(window);
279
return new QMirClientDesktopWindow(window);
258
return new UbuntuWindow(window, mInput, mNativeInterface, mAppStateController.data(),
259
mEglDisplay, mMirConnection, mDebugExtension.data());
281
return new QMirClientWindow(window, mInput, mNativeInterface, mAppStateController.data(),
282
mEglDisplay, mMirConnection, mDebugExtension.data());
263
bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
286
bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
266
289
case ThreadedOpenGL:
267
290
if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) {
270
qCDebug(ubuntumirclient, "disabled threaded OpenGL");
293
qCDebug(mirclient, "disabled threaded OpenGL");
289
QAbstractEventDispatcher *UbuntuClientIntegration::createEventDispatcher() const
312
QAbstractEventDispatcher *QMirClientClientIntegration::createEventDispatcher() const
291
314
return createUnixEventDispatcher();
294
QPlatformBackingStore* UbuntuClientIntegration::createPlatformBackingStore(QWindow* window) const
317
QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(QWindow* window) const
296
return new UbuntuBackingStore(window);
319
return new QMirClientBackingStore(window);
299
QPlatformOpenGLContext* UbuntuClientIntegration::createPlatformOpenGLContext(
322
QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
300
323
QOpenGLContext* context) const
302
325
QSurfaceFormat format(context->format());
304
auto platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay);
327
auto platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay);
305
328
if (!platformContext->isValid()) {
306
329
// Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
307
330
// QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
308
// 1.4 context, but the XCB EGL backend tries to honour it, and fails. The 1.4 context appears to
331
// 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to
309
332
// have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
310
333
// requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
311
334
static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
313
qCDebug(ubuntumirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
336
qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
314
337
format.setMajorVersion(1);
315
338
format.setMinorVersion(4);
316
339
delete platformContext;
317
platformContext = new UbuntuOpenGLContext(format, context->shareHandle(), mEglDisplay);
340
platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay);
320
343
return platformContext;
323
QStringList UbuntuClientIntegration::themeNames() const
346
QStringList QMirClientClientIntegration::themeNames() const
325
348
return QStringList(QStringLiteral("ubuntuappmenu"));
328
QPlatformTheme* UbuntuClientIntegration::createPlatformTheme(const QString& name) const
351
QPlatformTheme* QMirClientClientIntegration::createPlatformTheme(const QString& name) const
331
354
return new UbuntuIconTheme;
334
QVariant UbuntuClientIntegration::styleHint(StyleHint hint) const
357
QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const
337
360
case QPlatformIntegration::StartDragDistance: {
348
371
return QPlatformIntegration::styleHint(hint);
351
QPlatformClipboard* UbuntuClientIntegration::clipboard() const
374
QPlatformClipboard* QMirClientClientIntegration::clipboard() const
353
376
static QPlatformClipboard *clipboard = nullptr;
354
377
if (!clipboard) {
355
clipboard = new UbuntuClipboard;
378
clipboard = new QMirClientClipboard;
357
380
return clipboard;
360
QPlatformNativeInterface* UbuntuClientIntegration::nativeInterface() const
383
QPlatformNativeInterface* QMirClientClientIntegration::nativeInterface() const
362
385
return mNativeInterface;
365
QPlatformOffscreenSurface *UbuntuClientIntegration::createPlatformOffscreenSurface(
388
QPlatformOffscreenSurface *QMirClientClientIntegration::createPlatformOffscreenSurface(
366
389
QOffscreenSurface *surface) const
368
391
return new QEGLPbuffer(mEglDisplay, surface->requestedFormat(), surface);
371
void UbuntuClientIntegration::destroyScreen(UbuntuScreen *screen)
394
void QMirClientClientIntegration::destroyScreen(QMirClientScreen *screen)
373
396
// FIXME: on deleting a screen while a Window is on it, Qt will automatically
374
397
// move the window to the primaryScreen(). This will trigger a screenChanged