mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 19:02:51 +00:00
375 lines
11 KiB
C++
375 lines
11 KiB
C++
/*
|
|
* Copyright 2007 Aaron Seigo <aseigo@kde.org>
|
|
* Copyright 2007 Matt Broadstone <mbroadst@gmail.com>
|
|
* Copyright (c) 2009 Chani Armitage <chani@kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License version 2 as
|
|
* published by the Free Software Foundation
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "desktopview.h"
|
|
|
|
#include <QFile>
|
|
#include <QtGui/qevent.h>
|
|
#include <QCoreApplication>
|
|
|
|
#include <KMenu>
|
|
#include <KRun>
|
|
#include <KToggleAction>
|
|
#include <KWindowSystem>
|
|
#include <NETRootInfo>
|
|
|
|
#include <Plasma/Applet>
|
|
#include <Plasma/Corona>
|
|
#include <Plasma/Containment>
|
|
#include <Plasma/Svg>
|
|
#include <Plasma/Wallpaper>
|
|
#include <Plasma/Theme>
|
|
|
|
#include <kephal/screens.h>
|
|
|
|
#include "dashboardview.h"
|
|
#include "desktopcorona.h"
|
|
#include "plasmaapp.h"
|
|
#include "plasma-shell-desktop.h"
|
|
|
|
|
|
DesktopView::DesktopView(Plasma::Containment *containment, int id, QWidget *parent)
|
|
: Plasma::View(containment, id, parent),
|
|
m_dashboard(0),
|
|
m_dashboardFollowsDesktop(true),
|
|
m_init(false)
|
|
{
|
|
setAttribute(Qt::WA_TranslucentBackground, false);
|
|
//setCacheMode(QGraphicsView::CacheNone);
|
|
|
|
/*FIXME: Work around for a (maybe) Qt bug:
|
|
* QApplication::focusWidget() can't track focus change in QGraphicsProxyWidget
|
|
* wrapped normal widget (eg. QLineEdit), if the QGraphicsView has called
|
|
* setFocusPolicy(Qt::NoFocus)
|
|
* I've created a bug report to Qt Software.
|
|
* There is also a simple reproduce program in case you're interested in this bug:
|
|
* ftp://fearee:public@public.sjtu.edu.cn/reproduce.tar.gz
|
|
*/
|
|
|
|
//setFocusPolicy(Qt::NoFocus);
|
|
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
|
|
|
checkDesktopAffiliation();
|
|
|
|
KWindowSystem::setType(winId(), NET::Desktop);
|
|
lower();
|
|
|
|
/*
|
|
const int w = 25;
|
|
QPixmap tile(w * 2, w * 2);
|
|
tile.fill(palette().base().color());
|
|
QPainter pt(&tile);
|
|
QColor color = palette().mid().color();
|
|
color.setAlphaF(.6);
|
|
pt.fillRect(0, 0, w, w, color);
|
|
pt.fillRect(w, w, w, w, color);
|
|
pt.end();
|
|
QBrush b(tile);
|
|
setBackgroundBrush(tile);
|
|
*/
|
|
|
|
KConfigGroup cg = config();
|
|
const uint dashboardContainmentId = cg.readEntry("DashboardContainment", uint(0));
|
|
m_dashboardFollowsDesktop = dashboardContainmentId == 0;
|
|
|
|
// since Plasma::View has a delayed init we need to
|
|
// put a delay also for this call in order to be sure
|
|
// to have correct information set (e.g. screen())
|
|
if (containment) {
|
|
QRect geom = PlasmaApp::self()->corona()->screenGeometry(containment->screen());
|
|
setGeometry(geom);
|
|
}
|
|
|
|
Kephal::Screens *screens = Kephal::Screens::self();
|
|
connect(screens, SIGNAL(screenResized(Kephal::Screen*,QSize,QSize)),
|
|
this, SLOT(screenResized(Kephal::Screen*)));
|
|
connect(screens, SIGNAL(screenMoved(Kephal::Screen*,QPoint,QPoint)),
|
|
this, SLOT(screenMoved(Kephal::Screen*)));
|
|
}
|
|
|
|
DesktopView::~DesktopView()
|
|
{
|
|
delete m_dashboard;
|
|
}
|
|
|
|
void DesktopView::checkDesktopAffiliation()
|
|
{
|
|
if (AppSettings::perVirtualDesktopViews()) {
|
|
m_desktop = containment() ? containment()->desktop() + 1 : -1;
|
|
kDebug() << "setting to desktop" << m_desktop;
|
|
KWindowSystem::setOnDesktop(winId(), m_desktop);
|
|
} else {
|
|
m_desktop = -1;
|
|
KWindowSystem::setOnAllDesktops(winId(), true);
|
|
}
|
|
}
|
|
|
|
void DesktopView::toggleDashboard()
|
|
{
|
|
kDebug() << "toggling dashboard for screen" << screen() << "and destop" << desktop() <<
|
|
(m_dashboard ? (m_dashboard->isVisible() ? "visible" : "hidden") : "non-existent");
|
|
prepDashboard();
|
|
if (m_dashboard) {
|
|
m_dashboard->toggleVisibility();
|
|
kDebug() << "toggling dashboard for screen" << screen() << "and destop" << desktop() << m_dashboard->isVisible();
|
|
}
|
|
}
|
|
|
|
void DesktopView::showDashboard(bool show)
|
|
{
|
|
if (!show && (!m_dashboard || !m_dashboard->isVisible())) {
|
|
return;
|
|
}
|
|
|
|
prepDashboard();
|
|
if (m_dashboard) {
|
|
m_dashboard->showDashboard(show);
|
|
}
|
|
}
|
|
|
|
void DesktopView::prepDashboard()
|
|
{
|
|
if (!m_dashboard) {
|
|
if (!containment()) {
|
|
return;
|
|
}
|
|
|
|
KConfigGroup cg = config();
|
|
Plasma::Containment *dc = dashboardContainment();
|
|
m_dashboardFollowsDesktop = dc == 0;
|
|
if (dc) {
|
|
dc->resize(size());
|
|
dc->enableAction("remove", false);
|
|
} else {
|
|
dc = containment();
|
|
}
|
|
|
|
m_dashboard = new DashboardView(dc, this);
|
|
connect(m_dashboard, SIGNAL(dashboardClosed()), this, SIGNAL(dashboardClosed()));
|
|
m_dashboard->addActions(actions());
|
|
}
|
|
|
|
//If a separate dashboard is used we must use the screen of this containment instead of the dashboard one
|
|
if (!m_dashboardFollowsDesktop && containment()) {
|
|
m_dashboard->setGeometry(PlasmaApp::self()->corona()->screenGeometry(containment()->screen()));
|
|
}
|
|
}
|
|
|
|
Plasma::Containment *DesktopView::dashboardContainment() const
|
|
{
|
|
KConfigGroup cg = config();
|
|
Plasma::Containment *dc = 0;
|
|
const uint containmentId = cg.readEntry("DashboardContainment", uint(0));
|
|
|
|
if (containmentId > 0) {
|
|
foreach (Plasma::Containment *c, PlasmaApp::self()->corona()->containments()) {
|
|
if (c->id() == containmentId) {
|
|
dc = c;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return dc;
|
|
}
|
|
|
|
void DesktopView::setDashboardContainment(Plasma::Containment *containment)
|
|
{
|
|
if (containment) {
|
|
config().writeEntry("DashboardContainment", containment->id());
|
|
if (m_dashboard) {
|
|
m_dashboard->setContainment(containment);
|
|
}
|
|
} else {
|
|
Plasma::Containment *dc = 0;
|
|
if (dashboardContainment()) {
|
|
dc = dashboardContainment();
|
|
}
|
|
|
|
config().deleteEntry("DashboardContainment");
|
|
if (m_dashboard) {
|
|
m_dashboard->setContainment(View::containment());
|
|
}
|
|
//destroy this after changing the containment, makes sure the view won't receive the destroyed signal
|
|
if (dc) {
|
|
dc->destroy(false);
|
|
}
|
|
}
|
|
|
|
m_dashboardFollowsDesktop = containment == 0;
|
|
}
|
|
|
|
void DesktopView::screenResized(Kephal::Screen *s)
|
|
{
|
|
if (s->id() == screen()) {
|
|
kDebug() << screen();
|
|
adjustSize();
|
|
}
|
|
}
|
|
|
|
void DesktopView::screenMoved(Kephal::Screen *s)
|
|
{
|
|
if (s->id() == screen()) {
|
|
kDebug() << screen();
|
|
adjustSize();
|
|
}
|
|
}
|
|
|
|
void DesktopView::adjustSize()
|
|
{
|
|
// adapt to screen resolution changes
|
|
QRect geom = PlasmaApp::self()->corona()->screenGeometry(screen());
|
|
kDebug() << "screen" << screen() << "geom" << geom;
|
|
setGeometry(geom);
|
|
if (containment()) {
|
|
containment()->resize(geom.size());
|
|
kDebug() << "Containment's geom after resize" << containment()->geometry();
|
|
}
|
|
|
|
if (m_dashboard) {
|
|
m_dashboard->setGeometry(geom);
|
|
}
|
|
|
|
kDebug() << "Done" << screen() << geometry();
|
|
}
|
|
|
|
bool DesktopView::isDashboardVisible() const
|
|
{
|
|
return m_dashboard && m_dashboard->isVisible();
|
|
}
|
|
|
|
bool DesktopView::dashboardFollowsDesktop() const
|
|
{
|
|
return m_dashboardFollowsDesktop;
|
|
}
|
|
|
|
void DesktopView::setContainment(Plasma::Containment *containment)
|
|
{
|
|
Plasma::Containment *oldContainment = this->containment();
|
|
if (m_init && containment == oldContainment) {
|
|
//kDebug() << "initialized and containment is the same, aborting";
|
|
return;
|
|
}
|
|
|
|
PlasmaApp::self()->prepareContainment(containment);
|
|
m_init = true;
|
|
|
|
if (m_dashboard && m_dashboardFollowsDesktop) {
|
|
m_dashboard->setContainment(containment);
|
|
}
|
|
|
|
KConfigGroup viewIds(KGlobal::config(), "ViewIds");
|
|
if (oldContainment) {
|
|
disconnect(oldContainment, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(toolBoxOpened(bool)));
|
|
disconnect(oldContainment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer()));
|
|
viewIds.deleteEntry(QString::number(oldContainment->id()));
|
|
}
|
|
|
|
if (containment) {
|
|
connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)), this, SLOT(toolBoxOpened(bool)));
|
|
connect(containment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer()));
|
|
viewIds.writeEntry(QString::number(containment->id()), id());
|
|
if (containment->corona()) {
|
|
containment->corona()->requestConfigSync();
|
|
}
|
|
}
|
|
|
|
View::setContainment(containment);
|
|
}
|
|
|
|
void DesktopView::toolBoxOpened(bool open)
|
|
{
|
|
if (isDashboardVisible()) {
|
|
return;
|
|
}
|
|
|
|
NETRootInfo info(QX11Info::display(), NET::Supported);
|
|
if (!info.isSupported(NET::WM2ShowingDesktop)) {
|
|
return;
|
|
}
|
|
|
|
if (open) {
|
|
connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)),
|
|
this, SLOT(showDesktopUntoggled(WId)));
|
|
} else {
|
|
disconnect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)),
|
|
this, SLOT(showDesktopUntoggled(WId)));
|
|
}
|
|
|
|
info.setShowingDesktop(open);
|
|
}
|
|
|
|
void DesktopView::showWidgetExplorer()
|
|
{
|
|
if (isDashboardVisible()) {
|
|
return;
|
|
}
|
|
|
|
Plasma::Containment *c = containment();
|
|
if (c) {
|
|
PlasmaApp::self()->showWidgetExplorer(screen(), c);
|
|
}
|
|
}
|
|
|
|
void DesktopView::showDesktopUntoggled(WId id)
|
|
{
|
|
if (isDashboardVisible()) {
|
|
return;
|
|
}
|
|
|
|
Plasma::Containment *c = containment();
|
|
if (c) {
|
|
c->setToolBoxOpen(false);
|
|
}
|
|
|
|
KWindowSystem::activateWindow(id);
|
|
}
|
|
|
|
void DesktopView::screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment* newContainment)
|
|
{
|
|
if (PlasmaApp::isPanelContainment(newContainment)) {
|
|
// we don't care about panel containments changing screens on us
|
|
return;
|
|
}
|
|
|
|
/*
|
|
kDebug() << "was:" << wasScreen << "is:" << isScreen << "my screen:" << screen()
|
|
<< "containment:" << (QObject *)newContainment << newContainment->activity()
|
|
<< "current containment" << (QObject *)containment()
|
|
<< "myself:" << (QObject *)this
|
|
<< "containment desktop:" << newContainment->desktop() << "my desktop:" << m_desktop;
|
|
*/
|
|
|
|
if (containment() == newContainment &&
|
|
wasScreen == screen() &&
|
|
(isScreen != wasScreen || AppSettings::perVirtualDesktopViews())) {
|
|
//kDebug() << "nulling out containment";
|
|
setContainment(0);
|
|
}
|
|
|
|
if (isScreen > -1 && isScreen == screen() &&
|
|
(!AppSettings::perVirtualDesktopViews() || newContainment->desktop() == m_desktop - 1) ) {
|
|
//kDebug() << "setting new containment";
|
|
setContainment(newContainment);
|
|
}
|
|
}
|
|
|
|
#include "moc_desktopview.cpp"
|
|
|