2
* Copyright 2006-2008 Aaron Seigo <aseigo@kde.org>
3
* Copyright 2009 Marco Martin <notmart@gmail.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details
15
* You should have received a copy of the GNU Library General Public
16
* License along with this program; if not, write to the
17
* Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
#include "plasmaapp.h"
22
#include "plasmakeyboardshelladaptor.h"
23
#include "keyboardcorona.h"
27
#include <QApplication>
28
#include <QPixmapCache>
30
#include <QVBoxLayout>
31
#include <QtDBus/QtDBus>
32
#include <QDesktopWidget>
36
#include <KColorUtils>
38
#include <KStandardAction>
39
#include <KWindowSystem>
40
#include <KSharedConfig>
42
#include <Plasma/Containment>
43
#include <Plasma/Theme>
44
#include <Plasma/PopupApplet>
45
#include <Plasma/Wallpaper>
46
#include <Plasma/WindowEffects>
49
#include "keyboarddialog.h"
52
PlasmaApp* PlasmaApp::self()
55
return new PlasmaApp();
58
return qobject_cast<PlasmaApp*>(kapp);
61
PlasmaApp::PlasmaApp()
62
: KUniqueApplication(),
65
m_delayedHideTimer(new QTimer(this)),
66
m_clearIgnoreNextWindowHideTimer(new QTimer(this)),
67
m_ignoreNextWindowHide(false)
69
m_delayedHideTimer->setInterval(50);
70
m_delayedHideTimer->setSingleShot(true);
71
connect(m_delayedHideTimer, SIGNAL(timeout()), this, SLOT(hideKeyboard()));
73
// this is a bit of a hack to work around the unreliable ordering of events
74
// between being shown and active windows changing; we put in a small delay
75
// before hiding the window on active window change when show() is called
76
m_clearIgnoreNextWindowHideTimer->setInterval(100);
77
m_clearIgnoreNextWindowHideTimer->setSingleShot(true);
78
connect(m_clearIgnoreNextWindowHideTimer, SIGNAL(timeout()), this,
79
SLOT(clearIgnoreNextWindowHide()));
81
KGlobal::locale()->insertCatalog("plasma-keyboardcontainer");
82
KCrash::setFlags(KCrash::AutoRestart);
84
KConfigGroup cg(KGlobal::config(), "General");
85
Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", font()));
87
cg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme-plasma-mobile");
88
const QString themeName = cg.readEntry("name", "air-mobile");
89
Plasma::Theme::defaultTheme()->setUseGlobalSettings(false);
90
Plasma::Theme::defaultTheme()->setThemeName(themeName);
93
m_containment = m_corona->addContainment("null");
95
new VirtualKeyboardAdaptor(this);
96
QDBusConnection::sessionBus().registerService("org.kde.plasma.VirtualKeyboard");
97
QDBusConnection::sessionBus().registerObject("/", this);
99
connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));
102
PlasmaApp::~PlasmaApp()
106
KConfigGroup PlasmaApp::storedConfig()
108
KConfigGroup cg(KGlobal::config(), "KeyboardConfig");
112
int PlasmaApp::newInstance()
118
const QString pluginName = "plasmaboard";
120
KConfigGroup config = storedConfig();
121
KConfigGroup actualConfig(m_containment->config());
122
actualConfig = KConfigGroup(&actualConfig, "Applets");
124
if (config.isValid() && !config.groupList().isEmpty()) {
125
config.copyTo(&actualConfig);
127
config.deleteGroup();
129
KConfigGroup appletConfigGroup = KConfigGroup(&actualConfig, QString::number(1));
130
appletConfigGroup = KConfigGroup(&appletConfigGroup, "Configuration");
131
if (!appletConfigGroup.hasKey("layout")) {
132
//FIXME: hardcoding to Tablet for now
133
appletConfigGroup.writeEntry("layout", "plasmaboard/tablet.xml");
136
m_dialog = new KeyboardDialog(m_corona, m_containment, pluginName, 1, QVariantList());
137
m_dialog->installEventFilter(this);
138
connect(m_dialog, SIGNAL(storeApplet(Plasma::Applet*)), this, SLOT(storeApplet(Plasma::Applet*)));
140
m_dialog->setWindowFlags(Qt::FramelessWindowHint);
141
KWindowSystem::setType(m_dialog->winId(), NET::Dock);
142
Plasma::WindowEffects::overrideShadow(m_dialog->winId(), true);
143
m_dialog->applet()->setBackgroundHints(Plasma::Applet::NoBackground);
145
//hide the keyboard when the active window switches
146
//the situation that brought up the keyboard isn't valid anymore
147
connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)),
148
this, SLOT(windowChangeHide()));
150
// Set window to exist on all desktops
151
KWindowSystem::setOnAllDesktops(m_dialog->winId(), true);
159
void PlasmaApp::cleanup()
162
m_corona->saveLayout();
170
//TODO: This manual sync() should not be necessary?
174
void PlasmaApp::storeApplet(Plasma::Applet *applet)
176
KConfigGroup storage = storedConfig();
177
KConfigGroup cg(applet->containment()->config());
178
cg = KConfigGroup(&cg, "Applets");
179
cg = KConfigGroup(&cg, QString::number(applet->id()));
181
// kDebug() << "storing" << applet->name() << applet->id() << "to" << storage.name() << ", applet config is" << cg.name();
182
cg.reparent(&storage);
186
void PlasmaApp::syncConfig()
188
KGlobal::config()->sync();
191
Plasma::Corona* PlasmaApp::corona()
194
m_corona = new KeyboardCorona(this);
195
connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig()));
197
m_corona->setItemIndexMethod(QGraphicsScene::NoIndex);
203
bool PlasmaApp::hasComposite()
205
return KWindowSystem::compositingActive();
209
void PlasmaApp::setLocation(const QString &location)
211
Plasma::Location loc = Plasma::BottomEdge;
212
if (location.compare("top", Qt::CaseInsensitive) == 0) {
213
loc = Plasma::TopEdge;
214
} else if (location.compare("left", Qt::CaseInsensitive) == 0) {
215
loc = Plasma::LeftEdge;
216
} else if (location.compare("Right", Qt::CaseInsensitive) == 0) {
217
loc = Plasma::RightEdge;
220
m_dialog->setLocation(loc);
223
void PlasmaApp::requestLayout(const QString &layout)
225
Plasma::Applet *applet = m_dialog->applet();
230
QMetaObject::invokeMethod(applet, "showLayout", Q_ARG(QString, layout));
233
void PlasmaApp::resetLayout()
235
Plasma::Applet *applet = m_dialog->applet();
240
QMetaObject::invokeMethod(applet, "resetLayout");
243
void PlasmaApp::show()
245
m_delayedHideTimer->stop();
246
m_ignoreNextWindowHide = true;
247
m_clearIgnoreNextWindowHideTimer->start();
249
if (!m_dialog->isVisible()) {
250
m_dialog->setWindowFlags(Qt::X11BypassWindowManagerHint);
251
Plasma::WindowEffects::slideWindow(m_dialog, m_dialog->location());
255
QTimer::singleShot(200, this, SLOT(delayedMouseReposition()));
258
void PlasmaApp::delayedMouseReposition()
260
//if the cursor is outside the keyboard at the first touch event,
261
//the current window loses focus and the keyboard will hide
262
QCursor::setPos(m_dialog->geometry().center());
265
void PlasmaApp::windowChangeHide()
267
if (m_ignoreNextWindowHide) {
268
clearIgnoreNextWindowHide();
275
void PlasmaApp::clearIgnoreNextWindowHide()
277
m_ignoreNextWindowHide = false;
280
void PlasmaApp::hide()
282
if (m_dialog->isVisible()) {
283
m_delayedHideTimer->start();
287
void PlasmaApp::hideKeyboard()
289
Plasma::WindowEffects::slideWindow(m_dialog, m_dialog->location());
293
#include "plasmaapp.moc"