2
* Copyright 2007 Aaron Seigo <aseigo@kde.org>
3
* Copyright 2007 Matt Broadstone <mbroadst@gmail.com>
4
* Copyright (c) 2009 Chani Armitage <chani@kde.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Library General Public License version 2 as
8
* published by the Free Software Foundation
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 "desktopview.h"
24
#include <QWheelEvent>
25
#include <QCoreApplication>
27
#include <KAuthorized>
30
#include <KToggleAction>
31
#include <KWindowSystem>
32
#include <NETRootInfo>
34
#include <Plasma/Applet>
35
#include <Plasma/Corona>
36
#include <Plasma/Containment>
38
#include <Plasma/Wallpaper>
39
#include <Plasma/Theme>
41
#include <kephal/screens.h>
43
#include "dashboardview.h"
44
#include "desktopcorona.h"
45
#include "kactivitycontroller.h"
46
#include "plasmaapp.h"
47
#include "plasma-shell-desktop.h"
56
DesktopView::DesktopView(Plasma::Containment *containment, int id, QWidget *parent)
57
: Plasma::View(containment, id, parent),
59
m_dashboardFollowsDesktop(true),
62
setAttribute(Qt::WA_TranslucentBackground, false);
63
//setCacheMode(QGraphicsView::CacheNone);
65
/*FIXME: Work around for a (maybe) Qt bug:
66
* QApplication::focusWidget() can't track focus change in QGraphicsProxyWidget
67
* wrapped normal widget (eg. QLineEdit), if the QGraphicsView has called
68
* setFocusPolicy(Qt::NoFocus)
69
* I've created a bug report to Qt Software.
70
* There is also a simple reproduce program in case you're interested in this bug:
71
* ftp://fearee:public@public.sjtu.edu.cn/reproduce.tar.gz
74
//setFocusPolicy(Qt::NoFocus);
76
setWindowFlags(Qt::FramelessWindowHint);
77
SetWindowPos(winId(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
78
HWND hwndDesktop = ::FindWindowW(L"Progman", NULL);
79
SetParent(winId(), hwndDesktop);
81
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
84
checkDesktopAffiliation();
86
KWindowSystem::setType(winId(), NET::Desktop);
91
QPixmap tile(w * 2, w * 2);
92
tile.fill(palette().base().color());
94
QColor color = palette().mid().color();
96
pt.fillRect(0, 0, w, w, color);
97
pt.fillRect(w, w, w, w, color);
100
setBackgroundBrush(tile);
103
KConfigGroup cg = config();
104
const uint dashboardContainmentId = cg.readEntry("DashboardContainment", uint(0));
105
m_dashboardFollowsDesktop = dashboardContainmentId == 0;
107
// since Plasma::View has a delayed init we need to
108
// put a delay also for this call in order to be sure
109
// to have correct information set (e.g. screen())
111
QRect geom = PlasmaApp::self()->corona()->screenGeometry(containment->screen());
115
Kephal::Screens *screens = Kephal::Screens::self();
116
connect(screens, SIGNAL(screenResized(Kephal::Screen *, QSize, QSize)),
117
this, SLOT(screenResized(Kephal::Screen *)));
118
connect(screens, SIGNAL(screenMoved(Kephal::Screen *, QPoint, QPoint)),
119
this, SLOT(screenMoved(Kephal::Screen *)));
122
DesktopView::~DesktopView()
127
void DesktopView::checkDesktopAffiliation()
129
if (AppSettings::perVirtualDesktopViews()) {
130
m_desktop = containment() ? containment()->desktop() + 1 : -1;
131
kDebug() << "setting to desktop" << m_desktop;
132
KWindowSystem::setOnDesktop(winId(), m_desktop);
135
KWindowSystem::setOnAllDesktops(winId(), true);
139
void DesktopView::toggleDashboard()
141
kDebug() << "toggling dashboard for screen" << screen() << "and destop" << desktop() <<
142
(m_dashboard ? (m_dashboard->isVisible() ? "visible" : "hidden") : "non-existent");
145
m_dashboard->toggleVisibility();
146
kDebug() << "toggling dashboard for screen" << screen() << "and destop" << desktop() << m_dashboard->isVisible();
150
void DesktopView::showDashboard(bool show)
152
if (!show && (!m_dashboard || !m_dashboard->isVisible())) {
158
m_dashboard->showDashboard(show);
162
void DesktopView::prepDashboard()
165
if (!containment()) {
169
KConfigGroup cg = config();
170
Plasma::Containment *dc = dashboardContainment();
171
m_dashboardFollowsDesktop = dc == 0;
174
dc->enableAction("remove", false);
179
m_dashboard = new DashboardView(dc, this);
180
connect(m_dashboard, SIGNAL(dashboardClosed()), this, SIGNAL(dashboardClosed()));
181
m_dashboard->addActions(actions());
184
//If a separate dashboard is used we must use the screen of this containment instead of the dashboard one
185
if (!m_dashboardFollowsDesktop && containment()) {
186
m_dashboard->setGeometry(PlasmaApp::self()->corona()->screenGeometry(containment()->screen()));
190
Plasma::Containment *DesktopView::dashboardContainment() const
192
KConfigGroup cg = config();
193
Plasma::Containment *dc = 0;
194
const uint containmentId = cg.readEntry("DashboardContainment", uint(0));
196
if (containmentId > 0) {
197
foreach (Plasma::Containment *c, PlasmaApp::self()->corona()->containments()) {
198
if (c->id() == containmentId) {
208
void DesktopView::setDashboardContainment(Plasma::Containment *containment)
211
config().writeEntry("DashboardContainment", containment->id());
213
m_dashboard->setContainment(containment);
216
Plasma::Containment *dc = 0;
217
if (dashboardContainment()) {
218
dc = dashboardContainment();
221
config().deleteEntry("DashboardContainment");
223
m_dashboard->setContainment(View::containment());
225
//destroy this after changing the containment, makes sure the view won't receive the destroyed signal
231
m_dashboardFollowsDesktop = containment == 0;
234
void DesktopView::screenResized(Kephal::Screen *s)
236
if (s->id() == screen()) {
237
kDebug() << screen();
242
void DesktopView::screenMoved(Kephal::Screen *s)
244
if (s->id() == screen()) {
245
kDebug() << screen();
250
void DesktopView::adjustSize()
252
// adapt to screen resolution changes
253
QRect geom = PlasmaApp::self()->corona()->screenGeometry(screen());
254
kDebug() << "screen" << screen() << "geom" << geom;
257
containment()->resize(geom.size());
258
kDebug() << "Containment's geom after resize" << containment()->geometry();
262
m_dashboard->setGeometry(geom);
265
kDebug() << "Done" << screen() << geometry();
268
bool DesktopView::isDashboardVisible() const
270
return m_dashboard && m_dashboard->isVisible();
273
bool DesktopView::dashboardFollowsDesktop() const
275
return m_dashboardFollowsDesktop;
278
void DesktopView::setContainment(Plasma::Containment *containment)
280
Plasma::Containment *oldContainment = this->containment();
281
if (m_init && containment == oldContainment) {
282
//kDebug() << "initialized and containment is the same, aborting";
288
if (m_dashboard && m_dashboardFollowsDesktop) {
289
m_dashboard->setContainment(containment);
292
KConfigGroup viewIds(KGlobal::config(), "ViewIds");
293
if (oldContainment) {
294
disconnect(oldContainment, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(toolBoxOpened(bool)));
295
disconnect(oldContainment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer()));
296
viewIds.deleteEntry(QString::number(oldContainment->id()));
300
connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(toolBoxOpened(bool)));
301
connect(containment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer()));
302
viewIds.writeEntry(QString::number(containment->id()), id());
303
if (containment->corona()) {
304
containment->corona()->requestConfigSync();
308
View::setContainment(containment);
311
void DesktopView::toolBoxOpened(bool open)
313
if (isDashboardVisible()) {
318
NETRootInfo info(QX11Info::display(), NET::Supported);
319
if (!info.isSupported(NET::WM2ShowingDesktop)) {
324
connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)),
325
this, SLOT(showDesktopUntoggled(WId)));
327
disconnect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)),
328
this, SLOT(showDesktopUntoggled(WId)));
331
info.setShowingDesktop(open);
335
void DesktopView::showWidgetExplorer()
337
if (isDashboardVisible()) {
341
Plasma::Containment *c = containment();
343
PlasmaApp::self()->showWidgetExplorer(screen(), c);
347
void DesktopView::showDesktopUntoggled(WId id)
349
if (isDashboardVisible()) {
353
Plasma::Containment *c = containment();
355
c->setToolBoxOpen(false);
358
KWindowSystem::activateWindow(id);
361
void DesktopView::screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment* newContainment)
363
if (PlasmaApp::isPanelContainment(newContainment)) {
364
// we don't care about panel containments changing screens on us
369
kDebug() << "was:" << wasScreen << "is:" << isScreen << "my screen:" << screen()
370
<< "containment:" << (QObject *)newContainment << newContainment->activity()
371
<< "current containment" << (QObject *)containment()
372
<< "myself:" << (QObject *)this
373
<< "containment desktop:" << newContainment->desktop() << "my desktop:" << m_desktop;
376
if (containment() == newContainment &&
377
wasScreen == screen() &&
378
(isScreen != wasScreen || AppSettings::perVirtualDesktopViews())) {
379
//kDebug() << "nulling out containment";
383
if (isScreen > -1 && isScreen == screen() &&
384
(!AppSettings::perVirtualDesktopViews() || newContainment->desktop() == m_desktop - 1) ) {
385
//kDebug() << "setting new containment";
386
setContainment(newContainment);
390
#include "desktopview.moc"