2
* This file is part of signon-ui
4
* Copyright (C) 2012 Canonical Ltd.
6
* Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
8
* This program is free software: you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License version 3, as published
10
* by the Free Software Foundation.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranties of
14
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15
* PURPOSE. See the GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "embed-manager.h"
24
#include <QApplication>
26
#include <X11/Xatom.h>
29
using namespace SignOnUi;
31
static EmbedManager *staticInstance = 0;
35
class EmbedManagerPrivate
38
EmbedManagerPrivate();
39
~EmbedManagerPrivate();
42
friend class EmbedManager;
43
QMap<WId,QX11EmbedWidget*> m_embedWidgets;
48
/* Workaround for https://bugreports.qt-project.org/browse/QTBUG-3617
49
* Send XEMBED_REQUEST_FOCUS manually.
51
#define XEMBED_REQUEST_FOCUS 3
53
// Sends an XEmbed message.
54
static void sendXEmbedMessage(WId window, Display *display, long message,
55
long detail = 0, long data1 = 0, long data2 = 0)
57
XClientMessageEvent c;
58
memset(&c, 0, sizeof(c));
59
c.type = ClientMessage;
60
c.message_type = XInternAtom(display, "_XEMBED", false);
65
c.data.l[0] = QX11Info::appTime();
66
c.data.l[1] = message;
71
XSendEvent(display, window, false, NoEventMask, (XEvent *) &c);
74
static bool x11EventFilter(void *message, long *)
76
XEvent *event = reinterpret_cast<XEvent*>(message);
77
if (event->type == ButtonPress)
79
QWidget *w = QWidget::find(event->xbutton.window);
80
if (w && w->window()->objectName() == "request-widget") {
81
QX11EmbedWidget *embed = static_cast<QX11EmbedWidget*>(w->window());
82
QApplication::setActiveWindow(w->window());
83
sendXEmbedMessage(embed->containerWinId(),
84
w->x11Info().display(),
85
XEMBED_REQUEST_FOCUS);
91
EmbedManagerPrivate::EmbedManagerPrivate()
95
EmbedManagerPrivate::~EmbedManagerPrivate()
99
EmbedManager *EmbedManager::instance()
101
if (staticInstance == 0) {
102
staticInstance = new EmbedManager();
105
return staticInstance;
108
EmbedManager::EmbedManager(QObject *parent):
110
d_ptr(new EmbedManagerPrivate)
112
QCoreApplication::instance()->setEventFilter(x11EventFilter);
115
EmbedManager::~EmbedManager()
120
QX11EmbedWidget *EmbedManager::widgetFor(WId windowId)
124
if (!d->m_embedWidgets.contains(windowId)) {
125
/* Create a new embed widget */
126
QX11EmbedWidget *embed = new QX11EmbedWidget;
127
QObject::connect(embed, SIGNAL(containerClosed()),
128
embed, SLOT(deleteLater()));
129
embed->embedInto(windowId);
130
embed->setObjectName("request-widget");
131
d->m_embedWidgets[windowId] = embed;
134
return d->m_embedWidgets[windowId];