1
/* * This file is part of Maliit framework *
3
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
6
* Contact: maliit-discuss@lists.maliit.org
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License version 2.1 as published by the Free Software Foundation
11
* and appearing in the file LICENSE.LGPL included in the packaging
15
#include "mimxserverlogic.h"
17
#include "mpassthruwindow.h"
18
#include "mimremotewindow.h"
19
#include "mimxextension.h"
20
#include "mimrotationanimation.h"
22
#include "mimxapplication.h"
23
#include "mimpluginsproxywidget.h"
24
#include "mimrotationanimation.h"
25
#include "mimserveroptions.h"
27
#include "windowedsurfacegroup.h"
35
class ConfigureForCompositing {
38
ConfigureForCompositing(const MImServerXOptions &newOptions)
43
bool operator()(QWidget *w)
49
w->setAttribute(Qt::WA_OpaquePaintEvent);
50
w->setAttribute(Qt::WA_NoSystemBackground);
51
w->setAutoFillBackground(false);
52
// Be aware that one cannot verify whether the background role *is*
53
// QPalette::NoRole - see QTBUG-17924.
54
w->setBackgroundRole(QPalette::NoRole);
56
if (!options.selfComposited) {
57
// Careful: This flag can trigger a call to
58
// qt_x11_recreateNativeWidgetsRecursive
59
// - which will crash when it tries to get the effective WId
60
// (as none of widgets have been mapped yet).
61
w->setAttribute(Qt::WA_TranslucentBackground);
68
const MImServerXOptions &options;
75
MImXServerLogic::MImXServerLogic(const MImServerXOptions &options, QObject *parent) :
76
MImAbstractServerLogic(parent),
78
mBackgroundSuppressed(false),
79
mCompositeExtension(),
83
mSurfaceGroupFactory(new Maliit::Server::WindowedSurfaceGroupFactory)
85
mPassThruWindow.reset(new MPassThruWindow(this, xOptions));
86
mPluginsProxyWidget.reset(new MImPluginsProxyWidget(mPassThruWindow.data()));
87
mRotationAnimation = new MImRotationAnimation(mPluginsProxyWidget.data(), passThruWindow(),
90
configureWidgetsForCompositing();
93
MImXServerLogic::~MImXServerLogic()
97
void MImXServerLogic::finalize()
99
// Cannot destroy QWidgets or QPixmaps during MIMApplication destruction.
100
// Hence the finalize handler that runs before the d'tor.
101
mPluginsProxyWidget.reset();
102
mPassThruWindow.reset();
103
mRemoteWindow.reset();
106
bool MImXServerLogic::selfCompositionSupported()
108
return mCompositeExtension.supported(0, 2) && mDamageExtension.supported();
111
void MImXServerLogic::x11EventFilter(XEvent *ev)
113
handleTransientEvents(ev);
114
handleRemoteWindowEvents(ev);
115
handlePassThruMapEvent(ev);
118
void MImXServerLogic::handleTransientEvents(XEvent *ev)
120
if (not mRemoteWindow.data()) {
124
if (mRemoteWindow->wasIconified(ev) || mRemoteWindow->wasUnmapped(ev)) {
125
qDebug() << "MImX11ServerLogic" << __PRETTY_FUNCTION__
126
<< "Remote window was destroyed or iconified - hiding.";
128
Q_EMIT remoteWindowChanged(0);
129
Q_EMIT applicationWindowGone();
130
mRemoteWindow.reset();
134
void MImXServerLogic::handleRemoteWindowEvents(XEvent *event)
136
if (not mRemoteWindow.data()) {
140
mRemoteWindow->handleEvent(event);
143
void MImXServerLogic::handlePassThruMapEvent(XEvent *ev)
145
if (ev->type != MapNotify)
148
if (ev->xmap.window != mPassThruWindow->effectiveWinId())
151
if (not mRemoteWindow.data()) {
152
qWarning() << __PRETTY_FUNCTION__
153
<< "No remote window found, but passthru window was mapped.";
157
mRemoteWindow->resetPixmap();
160
void MImXServerLogic::applicationFocusChanged(WId newRemoteWinId)
162
if (0 == newRemoteWinId) {
166
if (mRemoteWindow.data() && mRemoteWindow->id() == newRemoteWinId) {
170
const bool wasRedirected(mRemoteWindow.data() && mRemoteWindow->isRedirected());
172
mRemoteWindow.reset(new MImRemoteWindow(newRemoteWinId, this, xOptions));
174
QSharedPointer<Maliit::Server::WindowedSurfaceGroupFactory> windowedSurfaceGroupFactory
175
= qSharedPointerDynamicCast<Maliit::Server::WindowedSurfaceGroupFactory>(mSurfaceGroupFactory);
176
if (windowedSurfaceGroupFactory)
177
windowedSurfaceGroupFactory->applicationFocusChanged(newRemoteWinId);
179
connect(mRemoteWindow.data(), SIGNAL(contentUpdated(QRegion)),
180
this, SLOT(updatePassThruWindow(QRegion)));
183
mRemoteWindow->redirect();
186
Q_EMIT remoteWindowChanged(mRemoteWindow.data());
189
void MImXServerLogic::setSuppressBackground(bool suppress)
191
mBackgroundSuppressed = suppress;
194
QWidget *MImXServerLogic::passThruWindow() const
196
return mPassThruWindow.data();
199
QSharedPointer<Maliit::Server::AbstractSurfaceGroupFactory> MImXServerLogic::surfaceGroupFactory() const
201
return mSurfaceGroupFactory;
204
const QPixmap &MImXServerLogic::remoteWindowPixmap()
206
if (not mRemoteWindow.data()
207
|| mBackgroundSuppressed
208
|| not xOptions.selfComposited) {
209
static const QPixmap empty;
213
return mRemoteWindow->windowPixmap();
216
void MImXServerLogic::updatePassThruWindow(const QRegion ®ion)
218
if (region.isEmpty() || remoteWindowPixmap().isNull()) {
219
qDebug() << "Skipping update request for passthru window.";
223
mPassThruWindow->updateFromRemoteWindow(region);
226
void MImXServerLogic::pluginLoaded()
228
configureWidgetsForCompositing();
231
void MImXServerLogic::configureWidgetsForCompositing()
233
ConfigureForCompositing visitor(xOptions);
234
visitWidgetHierarchy(visitor, mPassThruWindow.data());
237
void MImXServerLogic::appOrientationAboutToChange(int toAngle) {
238
mRotationAnimation->appOrientationAboutToChange(toAngle);
241
void MImXServerLogic::appOrientationChangeFinished(int toAngle) {
242
mRotationAnimation->appOrientationChangeFinished(toAngle);
245
MImRemoteWindow *MImXServerLogic::remoteWindow() const
247
return mRemoteWindow.data();
250
void MImXServerLogic::inputPassthrough(const QRegion ®ion)
252
mPassThruWindow->inputPassthrough(region);
255
const MImXCompositeExtension& MImXServerLogic::compositeExtension()
257
return mCompositeExtension;
260
const MImXDamageExtension& MImXServerLogic::damageExtension()
262
return mDamageExtension;