From kde-commits Wed Feb 29 22:45:22 2012 From: Shaun Reich Date: Wed, 29 Feb 2012 22:45:22 +0000 To: kde-commits Subject: [kde-workspace/plasma/sreich/sal-qml] plasma/netbook/containments/sal: add my own custom shell, plas Message-Id: <20120229224522.866B3A60C4 () git ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=133055556908408 Git commit b7ab3b804c479686cc45104a4af4f2e64f19d4a1 by Shaun Reich. Committed on 29/02/2012 at 18:01. Pushed by sreich into branch 'plasma/sreich/sal-qml'. add my own custom shell, plasma-sal, from the basis of plasma-overaly M +2 -0 plasma/netbook/containments/sal/CMakeLists.txt A +254 -0 plasma/netbook/containments/sal/shell/BackgroundDialog.ui A +27 -0 plasma/netbook/containments/sal/shell/CMakeLists.txt A +5 -0 plasma/netbook/containments/sal/shell/Messages.sh A +227 -0 plasma/netbook/containments/sal/shell/backgrounddialog.cpp = [License: GPL (v2+)] A +52 -0 plasma/netbook/containments/sal/shell/backgrounddialog.h = [License: GPL (v2+)] A +61 -0 plasma/netbook/containments/sal/shell/main.cpp [License:= GPL (v2+)] A +17 -0 plasma/netbook/containments/sal/shell/org.kde.plasma-sal.App= .xml A +10 -0 plasma/netbook/containments/sal/shell/plasma-salrc A +498 -0 plasma/netbook/containments/sal/shell/plasmaapp.cpp [Lic= ense: GPL (v2+)] A +137 -0 plasma/netbook/containments/sal/shell/plasmaapp.h [Licen= se: GPL (v2+)] A +205 -0 plasma/netbook/containments/sal/shell/salcorona.cpp [Lic= ense: LGPL (v2+)] A +65 -0 plasma/netbook/containments/sal/shell/salcorona.h [Licen= se: LGPL (v2+)] A +293 -0 plasma/netbook/containments/sal/shell/salview.cpp [Licen= se: LGPL (v2+)] A +85 -0 plasma/netbook/containments/sal/shell/salview.h [License= : LGPL (v2+)] http://commits.kde.org/kde-workspace/b7ab3b804c479686cc45104a4af4f2e64f19d4= a1 diff --git a/plasma/netbook/containments/sal/CMakeLists.txt b/plasma/netboo= k/containments/sal/CMakeLists.txt index a7ecaa9..a7890d7 100644 --- a/plasma/netbook/containments/sal/CMakeLists.txt +++ b/plasma/netbook/containments/sal/CMakeLists.txt @@ -4,3 +4,5 @@ install(DIRECTORY package/ DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/sal) = install(FILES package/metadata.desktop DESTINATION ${SERVICES_INSTALL_DIR}= RENAME plasma-applet-sal.desktop) + +add_subdirectory(shell) \ No newline at end of file diff --git a/plasma/netbook/containments/sal/shell/BackgroundDialog.ui b/pl= asma/netbook/containments/sal/shell/BackgroundDialog.ui new file mode 100644 index 0000000..d6d2df7 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/BackgroundDialog.ui @@ -0,0 +1,254 @@ + + + BackgroundDialog + + + + 0 + 0 + 519 + 173 + + + + + 200 + 700 + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Widget Translucency + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 17 + + + + + + + + User activity: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_activeSlider + + + + + + + 1 + + + 10 + + + 1 + + + Qt::Horizontal + + + + + + + While idle: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_idleSlider + + + + + + + 10 + + + 1 + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 17 + 13 + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Wallpaper + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 13 + 17 + + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + m_wallpaperMode + + + + + + + + 1 + 0 + + + + + 150 + 0 + + + + + + + + + + + + + 0 + 0 + + + + Monitor + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + 143 + 6 + + + + + + + + + diff --git a/plasma/netbook/containments/sal/shell/CMakeLists.txt b/plasma/= netbook/containments/sal/shell/CMakeLists.txt new file mode 100644 index 0000000..2c933fd --- /dev/null +++ b/plasma/netbook/containments/sal/shell/CMakeLists.txt @@ -0,0 +1,27 @@ +include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs ${KDEBASE_WORKSPA= CE_SOURCE_DIR}/libs/plasmagenericshell) + +set(plasma-sal_SRCS + main.cpp + plasmaapp.cpp + salcorona.cpp + salview.cpp +) + +kde4_add_ui_files(plasma-sal_SRCS BackgroundDialog.ui) + +set(plasmaapp_dbusXML org.kde.plasma-sal.App.xml) + +qt4_add_dbus_adaptor(plasma-sal_SRCS ${plasmaapp_dbusXML} plasmaapp.h Plas= maApp) + +kde4_add_executable(plasma-sal ${plasma-sal_SRCS}) + +target_link_libraries(plasma-sal ${KDE4_PLASMA_LIBS} kworkspace ${KDE4_KI= O_LIBS} ${KDE4_KFILE_LIBS} + ${X11_X11_LIB} plasmagenericshell) +if(X11_Xrender_FOUND) + target_link_libraries(plasma-sal ${X11_Xrender_LIB}) +endif(X11_Xrender_FOUND) + +set_target_properties(plasma-sal PROPERTIES OUTPUT_NAME plasma-sal) + +install(TARGETS plasma-sal ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES plasma-salrc DESTINATION ${CONFIG_INSTALL_DIR}) diff --git a/plasma/netbook/containments/sal/shell/Messages.sh b/plasma/net= book/containments/sal/shell/Messages.sh new file mode 100755 index 0000000..b79d051 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/Messages.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/plasma-overlay.pot +rm -f rc.cpp + diff --git a/plasma/netbook/containments/sal/shell/backgrounddialog.cpp b/p= lasma/netbook/containments/sal/shell/backgrounddialog.cpp new file mode 100644 index 0000000..a92dc7a --- /dev/null +++ b/plasma/netbook/containments/sal/shell/backgrounddialog.cpp @@ -0,0 +1,227 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (C) 2007 Ivan Cukic + Copyright (c) 2008 by Petri Damsten + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "backgrounddialog.h" + +//#include +//#include +//#include + +#include +//#include +//#include +//#include + +#include +#include +#include +#include +//#include + +#include "plasmaapp.h" +#include "plasmagenericshell/wallpaperpreview.h" + +#include "kworkspace/screenpreviewwidget.h" + +typedef QPair WallpaperInfo; +Q_DECLARE_METATYPE(WallpaperInfo) + + +BackgroundDialog::BackgroundDialog(const QSize& res, Plasma::Containment *= c, /*Plasma::View* view,*/ QWidget* parent) + : KDialog(parent), + m_wallpaper(0), + //m_view(view), + m_containment(c), + m_preview(0) +{ + //setWindowIcon(KIcon("preferences-desktop-wallpaper")); + setCaption(i18n("Background Settings")); + setButtons(Ok | Cancel | Apply); + + QWidget * main =3D new QWidget(this); + setupUi(main); + + // Size of monitor image: 200x186 + // Geometry of "display" part of monitor image: (23,14)-[151x115] + qreal previewRatio =3D (qreal)res.width() / (qreal)res.height(); + QSize monitorSize(200, int(200 * previewRatio)); + + m_monitor->setFixedSize(200,200); + m_monitor->setText(QString()); + m_monitor->setWhatsThis(i18n( + "This picture of a monitor contains a preview of " + "what the current settings will look like on your desktop.")); + m_preview =3D new ScreenPreviewWidget(m_monitor); + m_preview->setRatio(previewRatio); + m_preview->resize(200,200); + + connect(this, SIGNAL(finished(int)), this, SLOT(cleanup())); + connect(this, SIGNAL(okClicked()), this, SLOT(saveConfig())); + connect(this, SIGNAL(applyClicked()), this, SLOT(saveConfig())); + + setMainWidget(main); + reloadConfig(); + adjustSize(); +} + +BackgroundDialog::~BackgroundDialog() +{ + cleanup(); +} + +void BackgroundDialog::cleanup() +{ + //FIXME could be bad if we get hidden and reshown + delete m_wallpaper; + m_wallpaper =3D 0; +} + +void BackgroundDialog::reloadConfig() +{ + //transparency + m_activeSlider->setValue(PlasmaApp::self()->activeOpacity() * 10); + m_idleSlider->setValue(PlasmaApp::self()->idleOpacity() * 10); + + label->setVisible(PlasmaApp::hasComposite()); + m_activeSlider->setVisible(PlasmaApp::hasComposite()); + + // Wallpaper + disconnect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SL= OT(changeBackgroundMode(int))); + int wallpaperIndex =3D 0; + + bool doWallpaper =3D m_containment->drawWallpaper() && ! PlasmaApp::ha= sComposite(); + m_wallpaperLabel->setVisible(doWallpaper); + m_wallpaperTypeLabel->setVisible(doWallpaper); + m_wallpaperMode->setVisible(doWallpaper); + m_wallpaperConfig->setVisible(doWallpaper); + m_monitor->setVisible(doWallpaper); + m_preview->setVisible(doWallpaper); + if (doWallpaper) { + // Load wallpaper plugins + QString currentPlugin; + QString currentMode; + + Plasma::Wallpaper *currentWallpaper =3D m_containment->wallpaper(); + if (currentWallpaper) { + currentPlugin =3D currentWallpaper->pluginName(); + currentMode =3D currentWallpaper->renderingMode().name(); + } + + const KPluginInfo::List plugins =3D Plasma::Wallpaper::listWallpap= erInfo(); + m_wallpaperMode->clear(); + int i =3D 0; + QString placeholder =3D i18n("No Wallpaper"); + //m_wallpaperMode->addItem(KIcon(), i18n("No Wallpaper"), + // QVariant::fromValue(WallpaperInfo(QStri= ng(), QString()))); + foreach (const KPluginInfo& info, plugins) { + bool matches =3D info.pluginName() =3D=3D currentPlugin; + const QList& modes =3D info.service()->actions= (); + if (modes.count() > 0) { + foreach (const KServiceAction& mode, modes) { + m_wallpaperMode->addItem(KIcon(mode.icon()), mode.text= (), + QVariant::fromValue(WallpaperInfo(info= .pluginName(), mode.name()))); + if (matches && mode.name() =3D=3D currentMode) { + wallpaperIndex =3D i; + } + ++i; + } + } else { + m_wallpaperMode->addItem(KIcon(info.icon()), info.name(), + QVariant::fromValue(WallpaperInfo(info.plu= ginName(), QString()))); + if (matches) { + wallpaperIndex =3D i; + } + ++i; + } + } + m_wallpaperMode->setCurrentIndex(wallpaperIndex); + changeBackgroundMode(wallpaperIndex); + } + + connect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SLOT(= changeBackgroundMode(int))); +} + +void BackgroundDialog::changeBackgroundMode(int mode) +{ + kDebug(); + QWidget* w =3D 0; + WallpaperInfo wallpaperInfo =3D m_wallpaperMode->itemData(mode).value<= WallpaperInfo>(); + + if (!m_wallpaperConfig->layout()) { + new QVBoxLayout(m_wallpaperConfig); + } + + if (m_wallpaperConfig->layout()->count() > 0) { + delete dynamic_cast(m_wallpaperConfig->layout()->tak= eAt(0))->widget(); + } + + if (m_wallpaper && m_wallpaper->pluginName() !=3D wallpaperInfo.first)= { + delete m_wallpaper; + m_wallpaper =3D 0; + } + + if (wallpaperInfo.first.isEmpty()) { + return; + } + + if (!m_wallpaper) { + m_wallpaper =3D Plasma::Wallpaper::load(wallpaperInfo.first); + m_preview->setPreview(m_wallpaper); + } + + if (m_wallpaper) { + m_wallpaper->setRenderingMode(wallpaperInfo.second); + KConfigGroup cfg =3D wallpaperConfig(wallpaperInfo.first); + kDebug() << "making a" << wallpaperInfo.first << "in mode" << wall= paperInfo.second; + m_wallpaper->restore(cfg); + w =3D m_wallpaper->createConfigurationInterface(m_wallpaperConfig); + } + + if (!w) { + w =3D new QWidget(m_wallpaperConfig); + } + + m_wallpaperConfig->layout()->addWidget(w); +} + +KConfigGroup BackgroundDialog::wallpaperConfig(const QString &plugin) +{ + Q_ASSERT(m_containment); + + //FIXME: we have details about the structure of the containment config= duplicated here! + KConfigGroup cfg =3D m_containment->config(); + cfg =3D KConfigGroup(&cfg, "Wallpaper"); + return KConfigGroup(&cfg, plugin); +} + +void BackgroundDialog::saveConfig() +{ + //transparency + PlasmaApp::self()->setActiveOpacity(m_activeSlider->value() / 10.0); + PlasmaApp::self()->setIdleOpacity(m_idleSlider->value() / 10.0); + + // Wallpaper + QString wallpaperPlugin =3D m_wallpaperMode->itemData(m_wallpaperMode-= >currentIndex()).value().first; + QString wallpaperMode =3D m_wallpaperMode->itemData(m_wallpaperMode->c= urrentIndex()).value().second; + + Plasma::Wallpaper *currentWallpaper =3D m_containment->wallpaper(); + if (currentWallpaper) { + KConfigGroup cfg =3D wallpaperConfig(currentWallpaper->pluginName(= )); + currentWallpaper->save(cfg); + } + + if (m_wallpaper) { + KConfigGroup cfg =3D wallpaperConfig(m_wallpaper->pluginName()); + m_wallpaper->save(cfg); + } + + m_containment->setWallpaper(wallpaperPlugin, wallpaperMode); +} diff --git a/plasma/netbook/containments/sal/shell/backgrounddialog.h b/pla= sma/netbook/containments/sal/shell/backgrounddialog.h new file mode 100644 index 0000000..04b507a --- /dev/null +++ b/plasma/netbook/containments/sal/shell/backgrounddialog.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2007 Paolo Capriotti + Copyright (c) 2008 by Petri Damsten + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef BACKGROUNDDIALOG_H +#define BACKGROUNDDIALOG_H + +#include +#include "ui_BackgroundDialog.h" + +namespace Plasma { + class Wallpaper; + class Containment; + class View; +} + +class ScreenPreviewWidget; + +class BackgroundDialog : public KDialog, public Ui::BackgroundDialog +{ + Q_OBJECT +public: + BackgroundDialog(const QSize &res, Plasma::Containment *containment, + /*Plasma::View *view,*/ QWidget *parent =3D 0); + ~BackgroundDialog(); + + void reloadConfig(); + +public slots: + void saveConfig(); + +private: + KConfigGroup wallpaperConfig(const QString &plugin); + +private slots: + void changeBackgroundMode(int mode); + void cleanup(); + +private: + Plasma::Wallpaper* m_wallpaper; + //Plasma::View* m_view; + Plasma::Containment* m_containment; + ScreenPreviewWidget* m_preview; +}; + +#endif // BACKGROUNDDIALOG_H diff --git a/plasma/netbook/containments/sal/shell/main.cpp b/plasma/netboo= k/containments/sal/shell/main.cpp new file mode 100644 index 0000000..03b3036 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/main.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2006-2007 Aaron Seigo + * Copyright 2008 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * 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 +#include +#include +#include + +#include +#include "plasmaapp.h" + +static const char description[] =3D I18N_NOOP( "Plasma widgets over the sc= reensaver" ); +static const char version[] =3D "0.0"; + +//extern "C" +int main(int argc, char **argv) +{ + KAboutData aboutData("plasma-sal",0 , ki18n("Plasma for the Screensave= r"), + version, ki18n(description), KAboutData::License_= GPL, + ki18n("Copyright 2006-2008, The KDE Team")); + aboutData.addAuthor(ki18n("Chani Armitage"), + ki18n("Author and maintainer"), + "chanika@gmail.com"); + aboutData.addAuthor(ki18n("Aaron J. Seigo"), + ki18n("Plasma Author and maintainer"), + "aseigo@kde.org"); + aboutData.addCredit(ki18n("John Lions"), + ki18n("In memory of his contributions, 1937-1998."= ), + 0, "http://en.wikipedia.org/wiki/John_Lions"); + + KCmdLineArgs::init(argc, argv, &aboutData); + + KCmdLineOptions options; + options.add("cheats",ki18n("Enables some cheats that are useful for de= bugging.")); + options.add("setup",ki18n("Start unlocked for configuration.")); + KCmdLineArgs::addCmdLineOptions(options); + + PlasmaApp *app =3D PlasmaApp::self(); + QApplication::setWindowIcon(KIcon("plasma")); + app->disableSessionManagement(); // I assume we'd never want a screens= aver thing reppearing on login? + int rc =3D app->exec(); + delete app; + return rc; +} diff --git a/plasma/netbook/containments/sal/shell/org.kde.plasma-sal.App.x= ml b/plasma/netbook/containments/sal/shell/org.kde.plasma-sal.App.xml new file mode 100644 index 0000000..54724a8 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/org.kde.plasma-sal.App.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/plasma/netbook/containments/sal/shell/plasma-salrc b/plasma/ne= tbook/containments/sal/shell/plasma-salrc new file mode 100644 index 0000000..393e2c9 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/plasma-salrc @@ -0,0 +1,10 @@ +[KDE Action Restrictions][$i] +plasma/allow_configure_when_locked=3Dfalse + +[Constraints] +FileDialog=3Dfalse +LaunchApp=3Dfalse + +[General] +ExcludeCategories=3DWindows and Tasks,Application Launchers + diff --git a/plasma/netbook/containments/sal/shell/plasmaapp.cpp b/plasma/n= etbook/containments/sal/shell/plasmaapp.cpp new file mode 100644 index 0000000..c55ec8d --- /dev/null +++ b/plasma/netbook/containments/sal/shell/plasmaapp.cpp @@ -0,0 +1,498 @@ +/* + * Copyright 2006 Aaron Seigo + * Copyright 2008 Chani Armitage + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * 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. + */ + +// plasma.loadEngine("hardware") +// LineGraph graph +// plasma.connect(graph, "hardware", "cpu"); + +#include "plasmaapp.h" + +#include + +#ifndef _SC_PHYS_PAGES + #ifdef Q_OS_FREEBSD + #include + #include + #endif + + #ifdef Q_OS_NETBSD + #include + #include + #endif +#endif + +#include +#include +#include +#include + +//#include +#include +#include +#include + +//#include + +#include +#include +#include + +#include "appadaptor.h" +#include "salcorona.h" +#include "salview.h" + +#include +#include +#include + +Atom tag; //FIXME should this be a member var or what? +const unsigned char DIALOG =3D 1; //FIXME this is really bad code +const unsigned char VIEW =3D 2; + +Display* dpy =3D 0; +Colormap colormap =3D 0; +Visual *visual =3D 0; +bool composite =3D false; + +void checkComposite() +{ + dpy =3D XOpenDisplay(0); // open default display + if (!dpy) { + kError() << "Cannot connect to the X server" << endl; + return; + } + if( qgetenv( "KDE_SKIP_ARGB_VISUALS" ) =3D=3D "1" ) + return; + + int screen =3D DefaultScreen(dpy); + int eventBase, errorBase; + + if (XRenderQueryExtension(dpy, &eventBase, &errorBase)) { + int nvi; + XVisualInfo templ; + templ.screen =3D screen; + templ.depth =3D 32; + templ.c_class =3D TrueColor; + XVisualInfo *xvi =3D XGetVisualInfo(dpy, + VisualScreenMask | VisualDepthMa= sk | VisualClassMask, + &templ, &nvi); + for (int i =3D 0; i < nvi; ++i) { + XRenderPictFormat *format =3D XRenderFindVisualFormat(dpy, xvi= [i].visual); + if (format->type =3D=3D PictTypeDirect && format->direct.alpha= Mask) { + visual =3D xvi[i].visual; + colormap =3D XCreateColormap(dpy, RootWindow(dpy, screen),= visual, AllocNone); + break; + } + } + XFree(xvi); + } + + composite =3D KWindowSystem::compositingActive() && colormap; + + kDebug() << (colormap ? "Plasma has an argb visual" : "Plasma lacks an= argb visual") << visual << colormap; + kDebug() << ((KWindowSystem::compositingActive() && colormap) ? "Plasm= a can use COMPOSITE for effects" + : "Pla= sma is COMPOSITE-less") << "on" << dpy; +} + +PlasmaApp* PlasmaApp::self() +{ + if (!kapp) { + checkComposite(); + return new PlasmaApp(dpy, visual ? Qt::HANDLE(visual) : 0, colorma= p ? Qt::HANDLE(colormap) : 0); + } + + return qobject_cast(kapp); +} + +PlasmaApp::PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE color= map) + : KUniqueApplication(display, visual, colormap), + m_corona(0) +{ + //load translations for libplasma + KGlobal::locale()->insertCatalog("libplasma"); + KGlobal::locale()->insertCatalog("plasmagenericshell"); + + new AppAdaptor(this); + QDBusConnection::sessionBus().registerObject("/App", this); + + //FIXME this is probably totally invalid + // Enlarge application pixmap cache + // Calculate the size required to hold background pixmaps for all scre= ens. + // Add 10% so that other (smaller) pixmaps can also be cached. + int cacheSize =3D 0; + QDesktopWidget *desktop =3D QApplication::desktop(); + int numScreens =3D desktop->numScreens(); + for (int i =3D 0; i < numScreens; i++) { + QRect geometry =3D desktop->screenGeometry(i); + cacheSize +=3D 4 * geometry.width() * geometry.height() / 1024; + } + cacheSize +=3D cacheSize / 10; + + // Calculate the size of physical system memory; _SC_PHYS_PAGES * + // _SC_PAGESIZE is documented to be able to overflow 32-bit integers, + // so apply a 10-bit shift. FreeBSD 6-STABLE doesn't have _SC_PHYS_PAG= ES + // (it is documented in FreeBSD 7-STABLE as "Solaris and Linux extensi= on") + // so use sysctl in those cases. +#if defined(_SC_PHYS_PAGES) + int memorySize =3D sysconf(_SC_PHYS_PAGES); + memorySize *=3D sysconf(_SC_PAGESIZE) / 1024; +#else +#ifdef Q_OS_FREEBSD + int sysctlbuf[2]; + size_t size =3D sizeof(sysctlbuf); + int memorySize; + // This could actually use hw.physmem instead, but I can't find + // reliable documentation on how to read the value (which may + // not fit in a 32 bit integer). + if (!sysctlbyname("vm.stats.vm.v_page_size", sysctlbuf, &size, NULL, 0= )) { + memorySize =3D sysctlbuf[0] / 1024; + size =3D sizeof(sysctlbuf); + if (!sysctlbyname("vm.stats.vm.v_page_count", sysctlbuf, &size, NU= LL, 0)) { + memorySize *=3D sysctlbuf[0]; + } + } +#endif +#ifdef Q_OS_NETBSD + size_t memorySize; + size_t len; + static int mib[] =3D { CTL_HW, HW_PHYSMEM }; + + len =3D sizeof(memorySize); + sysctl(mib, 2, &memorySize, &len, NULL, 0); + memorySize /=3D 1024; +#endif + // If you have no suitable sysconf() interface and are not FreeBSD, + // then you are out of luck and get a compile error. +#endif + + // Increase the pixmap cache size to 1% of system memory if it isn't a= lready + // larger so as to maximize cache usage. 1% of 1GB ~=3D 10MB. + if (cacheSize < memorySize / 100) { + cacheSize =3D memorySize / 100; + } + + kDebug() << "Setting the pixmap cache size to" << cacheSize << "kiloby= tes"; + QPixmapCache::setCacheLimit(cacheSize); + + KConfigGroup cg(KGlobal::config(), "General"); + Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", fon= t())); + m_activeOpacity =3D cg.readEntry("activeOpacity", 1.0); + + if (cg.readEntry("forceNoComposite", false)) { + composite =3D false; + } + + //we have to keep an eye on created windows + tag =3D XInternAtom(QX11Info::display(), "_KDE_SCREENSAVER_OVERRIDE", = False); + qApp->installEventFilter(this); + + // this line initializes the corona. + corona(); + + connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup())); + + setup(KCmdLineArgs::parsedArgs()->isSet("setup")); + = + m_viewCreationTimer.setSingleShot(true); + m_viewCreationTimer.setInterval(0); + connect(&m_viewCreationTimer, SIGNAL(timeout()), this, SLOT(createWait= ingViews())); +} + +PlasmaApp::~PlasmaApp() +{ +} + +void PlasmaApp::cleanup() +{ + if (m_corona) { + m_corona->saveLayout(); + } + + qDeleteAll(m_views); + delete m_corona; + m_corona =3D 0; + + KGlobal::config()->sync(); +} + +void PlasmaApp::setActiveOpacity(qreal opacity) +{ + if (qFuzzyCompare(opacity, m_activeOpacity)) { + return; + } + m_activeOpacity =3D opacity; + emit setViewOpacity(opacity); + KConfigGroup cg(KGlobal::config(), "General"); + cg.writeEntry("activeOpacity", opacity); + m_corona->requestConfigSync(); +} + +void PlasmaApp::createWaitingViews() +{ + const QList > containments =3D m_vie= wsWaiting; + m_viewsWaiting.clear(); + foreach(QWeakPointer weakContainment, containment= s) { + if (weakContainment) { + Plasma::Containment *containment =3D weakContainment.data(); + = + KConfigGroup viewIds(KGlobal::config(), "ViewIds"); + = + // we have a new screen. neat. + SalView *view =3D viewForScreen(containment->screen()); + if (view) { + return; + } + = + view =3D new SalView(containment, 0); + if (m_corona) { + connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma= ::Containment*)), + view, SLOT(screenOwnerChanged(int,int,Plasma::Cont= ainment*))); + connect(m_corona, SIGNAL(shortcutsChanged()), view, SLOT(u= pdateShortcuts())); + } + view->setGeometry(QApplication::desktop()->screenGeometry(cont= ainment->screen())); + + //FIXME why do I get BadWindow? + //unsigned char data =3D VIEW; + //XChangeProperty(QX11Info::display(), view->effectiveWinId(),= tag, tag, 8, PropModeReplace, &data, 1); + + connect(containment, SIGNAL(configureRequested(Plasma::Contain= ment*)), + this, SLOT(configureContainment(Plasma::Containment*))= ); + + //a hack to make sure the keyboard shortcut works + view->addAction(corona()->action("unlock desktop")); + view->addAction(corona()->action("unlock widgets")); + m_views.append(view); + connect(view, SIGNAL(hidden()), SLOT(lock())); + connect(view, SIGNAL(hidden()), SIGNAL(hidden())); + connect(this, SIGNAL(showViews()), view, SLOT(show())); + connect(this, SIGNAL(hideViews()), view, SLOT(hide())); + connect(this, SIGNAL(setViewOpacity(qreal)), view, SLOT(setOpa= city(qreal))); + connect(this, SIGNAL(enableSetupMode()), view, SLOT(disableSet= upMode())); + connect(this, SIGNAL(disableSetupMode()), view, SLOT(disableSe= tupMode())); + connect(this, SIGNAL(openToolBox()), view, SLOT(openToolBox())= ); + connect(this, SIGNAL(closeToolBox()), view, SLOT(closeToolBox(= ))); + connect(QApplication::desktop(), SIGNAL(resized(int)), view, S= LOT(adjustSize(int))); + emit(openToolBox()); + kDebug() << "view created"; + } + } + //activate the new views (yes, this is a lazy way to do it) + setActive(m_active); +} + +qreal PlasmaApp::activeOpacity() const +{ + return m_activeOpacity; +} + +void PlasmaApp::setActive(bool activate) +{ + m_active =3D activate; + + emit setViewOpacity(m_activeOpacity); + emit showViews(); + emit openToolBox(); +} + +void PlasmaApp::syncConfig() +{ + KGlobal::config()->sync(); +} + +Plasma::Corona* PlasmaApp::corona() +{ + if (!m_corona) { + m_corona =3D new SalCorona(this); + connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Contai= nment*)), + this, SLOT(containmentScreenOwnerChanged(int,int,Plasma::C= ontainment*))); + connect(m_corona, SIGNAL(configSynced()), SLOT(syncConfig())); + //kDebug() << "connected to containmentAdded"; + /* + foreach (DesktopView *view, m_desktops) { + connect(c, SIGNAL(screenOwnerChanged(int,int,Plasma::Containme= nt*)), + view, SLOT(screenOwnerChanged(int,int,Plasma::= Containment*))); + }*/ + + m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); + m_corona->initializeLayout(); + + //we want this *after* init so that we ignore any lock/unlock spas= ms that might happen then + connect(m_corona, SIGNAL(immutabilityChanged(Plasma::ImmutabilityT= ype)), this, SLOT(immutabilityChanged(Plasma::ImmutabilityType))); + + //kDebug() << "layout should exist"; + //c->checkScreens(); + } + + return m_corona; +} + +bool PlasmaApp::hasComposite() +{ + return composite; +} + +void PlasmaApp::containmentScreenOwnerChanged(int wasScreen, int isScreen,= Plasma::Containment *containment) +{ + Q_UNUSED(wasScreen); + if (isScreen < 0) + return; + m_viewsWaiting.append(containment); + m_viewCreationTimer.start(); +} + +void PlasmaApp::setup(bool setupMode) +{ + kDebug() << "setup mode:" << setupMode; + + if (setupMode) { + emit enableSetupMode(); + if (m_corona->immutability() =3D=3D Plasma::UserImmutable) { + m_corona->setImmutability(Plasma::Mutable); + } + setActive(true); + } else { + kDebug() << "checking lockprocess is still around"; + QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess", + "org.kde.screenlocker.LockProcess", QDBusConnection::sessi= onBus(), this); + if (lockprocess.isValid()) { + kDebug() << "success!"; + setActive(false); + } else { + kDebug() << "bailing out"; + qApp->quit(); //this failed once. why? + } + } +} + +bool PlasmaApp::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() =3D=3D QEvent::Show) { + //apparently this means we created a new window + //so, add a tag to prove it's our window + //FIXME using the show event means we tag on every show, not just = the first. + //harmless but kinda wasteful. + QWidget *widget =3D qobject_cast(obj); + if (widget && widget->isWindow() && !(qobject_cast(widget) || + widget->testAttribute(Qt::WA_DontShowOnScreen))) { + unsigned char data =3D 0; + if (qobject_cast(widget)) { + data =3D VIEW; + } else if (m_dialogs.contains(widget)) { + data =3D DIALOG; + } else { + Qt::WindowFlags oldFlags =3D widget->windowFlags(); + Qt::WindowFlags newFlags =3D oldFlags | Qt::X11BypassWindo= wManagerHint; + if (oldFlags !=3D newFlags) { + //now we're *really* fucking with things + //we force-disable window management and frames to cut= off access to wm-y stuff + //and to make it easy to check the tag (frames are a p= ain) + kDebug() << "!!!!!!!setting flags on!!!!!" << widget; + QDesktopWidget *desktop =3D QApplication::desktop(); + if (qobject_cast(widget)) { + //this is a terrible horrible hack that breaks ext= enders but it mostly works + //weird thing is, it sometimes makes the calendar = popup too small. + newFlags =3D Qt::Popup; + } else { + //plasmadialogs can't handle direct input + //but configdialogs need it + m_dialogs.append(widget); + connect(widget, SIGNAL(destroyed(QObject*)), SLOT(= dialogDestroyed(QObject*))); + connect(this, SIGNAL(showDialogs()), widget, SLOT(= show())); + connect(this, SIGNAL(hideDialogs()), widget, SLOT(= hide())); + } + widget->setWindowFlags(newFlags); + //we do not know the screen this widget should appear = on + QRect availableGeometry =3D desktop->availableGeometry= (); + //move to the default screen + widget->move(availableGeometry.x(), availableGeometry.= y()); + widget->show(); //setting the flags hid it :( + //qApp->setActiveWindow(widget); //gives kbd but not m= ouse events + //kDebug() << "parent" << widget->parentWidget(); + //FIXME why can I only activate these dialogs from thi= s exact line? + widget->activateWindow(); //gives keyboard focus + return false; //we'll be back when we get the new show= event + } else { + widget->activateWindow(); //gives keyboard focus + } + } + + XChangeProperty(QX11Info::display(), widget->effectiveWinId(),= tag, tag, 8, PropModeReplace, &data, 1); + kDebug() << "tagged" << widget << widget->effectiveWinId() << = "as" << data; + } + } + return false; +} + +void PlasmaApp::dialogDestroyed(QObject *obj) +{ + m_dialogs.removeAll(qobject_cast(obj)); + //if (m_dialogs.isEmpty()) { + //FIXME multiview + //if (m_view) { + //this makes qactions work again + //m_view->activateWindow(); + //} + /*} else { failed attempt to fix kbd input after a subdialog closes + QWidget *top =3D m_dialogs.last(); + top->activateWindow(); + kDebug() << top;*/ + //} +} + +void PlasmaApp::configureContainment(Plasma::Containment *containment) +{ + +} + +void PlasmaApp::lock() +{ + kDebug() << "lock"; + if (corona() && corona()->immutability() =3D=3D Plasma::Mutable) { + corona()->setImmutability(Plasma::UserImmutable); + } +} + +void PlasmaApp::quit() +{ + qApp->quit(); +} + +void PlasmaApp::immutabilityChanged(Plasma::ImmutabilityType immutability) +{ + if (immutability =3D=3D Plasma::Mutable) { + emit showDialogs(); + } else { + emit hideDialogs(); + emit hideWidgetExplorer(); + emit disableSetupMode(); + } +} + +SalView *PlasmaApp::viewForScreen(int screen) +{ + foreach(SalView *view, m_views) { + if (view->screen() =3D=3D screen) + return view; + } + return 0; +} + +#include "plasmaapp.moc" diff --git a/plasma/netbook/containments/sal/shell/plasmaapp.h b/plasma/net= book/containments/sal/shell/plasmaapp.h new file mode 100644 index 0000000..f3f011f --- /dev/null +++ b/plasma/netbook/containments/sal/shell/plasmaapp.h @@ -0,0 +1,137 @@ +/* + * Copyright 2006, 2007 Aaron Seigo + * Copyright 2008 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * 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. + */ + +#ifndef PLASMA_APP_H +#define PLASMA_APP_H + +#include +#include +#include + +#include + +#include + +namespace Plasma +{ + class Containment; + class Corona; +} // namespace Plasma + +class SalView; + +class PlasmaApp : public KUniqueApplication +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.plasmasal.App") +public: + ~PlasmaApp(); + + static PlasmaApp* self(); + static bool hasComposite(); + + Plasma::Corona* corona(); + + void setActiveOpacity(qreal opacity); + void setIdleOpacity(qreal opacity); + qreal activeOpacity() const; + qreal idleOpacity() const; + +Q_SIGNALS: + // DBUS interface. + //if you change stuff, remember to regenerate with: + //qdbuscpp2xml -S -M plasmaapp.h > org.kde.plasma-overlay.App.xml + + //XXX can this be deleted? probably. if lockprocess really cares it ca= n use the unmapnotify + void hidden(); + +public Q_SLOTS: + // DBUS interface. + //if you change stuff, remember to regenerate ^^^ + /** + * tell plasma to go into active mode, ready for interaction + */ + void setActive(bool activate); + + /** + * lock widgets + */ + void lock(); + + //not really slots, but we want them in dbus: + + /** + * get plasma all set up and ready + * this makes sure things like opacity, visibility and locked-ness are= set right + * normally this is called only by plasmaapp itself when it finishes i= nitialization, but it's + * possible that it might need to be run again by lockprocess + * + * @param setupMode whether we're starting in setup mode + */ + void setup(bool setupMode); + + /** + * quit the application + * this is a duplicate so we can have everything we need in one dbus i= nterface + */ + void quit(); + +private Q_SLOTS: + void cleanup(); + //void adjustSize(int screen); + void dialogDestroyed(QObject *obj); + void configureContainment(Plasma::Containment*); + void syncConfig(); + void immutabilityChanged(Plasma::ImmutabilityType immutability); + void createWaitingViews(); + void containmentScreenOwnerChanged(int, int, Plasma::Containment*); + +Q_SIGNALS: + void showViews(); + void hideViews(); + void setViewOpacity(qreal opacity); + void showDialogs(); + void hideDialogs(); + void hideWidgetExplorer(); + void enableSetupMode(); + void disableSetupMode(); + void openToolBox(); + void closeToolBox(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap); + SalView *viewForScreen(int screen); + + Plasma::Corona *m_corona; + QList m_views; + QList m_dialogs; + + QList > m_viewsWaiting; + QTimer m_viewCreationTimer; + + qreal m_activeOpacity; + qreal m_idleOpacity; + bool m_active; +}; + +#endif // multiple inclusion guard diff --git a/plasma/netbook/containments/sal/shell/salcorona.cpp b/plasma/n= etbook/containments/sal/shell/salcorona.cpp new file mode 100644 index 0000000..2093c9b --- /dev/null +++ b/plasma/netbook/containments/sal/shell/salcorona.cpp @@ -0,0 +1,205 @@ +/* + * Copyright 2008 Aaron Seigo + * Copyright 2008 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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 "salcorona.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +SalCorona::SalCorona(QObject *parent) + : Plasma::Corona(parent) +{ + init(); +} + +void SalCorona::init() +{ + setPreferredToolBoxPlugin(Plasma::Containment::DesktopContainment, "or= g.kde.desktoptoolbox"); + setPreferredToolBoxPlugin(Plasma::Containment::CustomContainment, "org= .kde.desktoptoolbox"); + setPreferredToolBoxPlugin(Plasma::Containment::PanelContainment, "org.= kde.paneltoolbox"); + setPreferredToolBoxPlugin(Plasma::Containment::CustomPanelContainment,= "org.kde.paneltoolbox"); + + QDesktopWidget *desktop =3D QApplication::desktop(); + connect(desktop,SIGNAL(screenCountChanged(int)), SLOT(numScreensUpdate= d(int))); + m_numScreens =3D desktop->numScreens(); + + Plasma::ContainmentActionsPluginsConfig plugins; + plugins.addPlugin(Qt::NoModifier, Qt::RightButton, "minimalcontextmenu= "); + //should I add paste too? + setContainmentActionsDefaults(Plasma::Containment::CustomContainment, = plugins); + + bool unlocked =3D immutability() =3D=3D Plasma::Mutable; + + QAction *lock =3D action("lock widgets"); + if (lock) { + kDebug() << "unlock action"; + //rename the lock action so that corona doesn't mess with it + addAction("unlock widgets", lock); + //rewire the action so we can check for a password + lock->disconnect(SIGNAL(triggered(bool))); + connect(lock, SIGNAL(triggered()), this, SLOT(toggleLock())); + lock->setIcon(KIcon(unlocked ? "object-locked" : "configure")); + lock->setText(unlocked ? i18n("Lock Screen") : i18n("Configure Wid= gets")); + } + + //the most important action ;) + QAction *leave =3D new QAction(unlocked ? i18n("Leave Screensaver") : = i18n("Unlock"), this); + leave->setIcon(KIcon("system-lock-screen")); + leave->setShortcut(QKeySequence("esc")); + connect(leave, SIGNAL(triggered()), this, SLOT(unlockDesktop())); + addAction("unlock desktop", leave); + + //updateShortcuts(); //just in case we ever get a config dialog + + connect(this, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), S= LOT(updateActions(Plasma::ImmutabilityType))); +} + +void SalCorona::loadDefaultLayout() +{ + //kDebug(); + QDesktopWidget *desktop =3D QApplication::desktop(); + + // create a containment for the screens + Plasma::Containment *c; + for(int screen =3D 0; screen < m_numScreens; ++screen) + { + QRect g =3D desktop->screenGeometry(screen); + kDebug() << " screen" << screen << "geometry is" << g; + c =3D addContainment("saverdesktop"); + if (c) { + c->setScreen(screen); + c->setFormFactor(Plasma::Planar); + c->flushPendingConstraintsEvents(); + } + } + + // a default clock + c =3D containmentForScreen(desktop->primaryScreen()); + if (c) { + Plasma::Applet *clock =3D Plasma::Applet::load("clock"/*, c->id()= + 1*/); + c->addApplet(clock, QPointF(KDialog::spacingHint(), KDialog::spaci= ngHint()), true); + clock->init(); + clock->flushPendingConstraintsEvents(); + } + //emit containmentAdded(c); +} + +int SalCorona::numScreens() const +{ + return m_numScreens; +} + +QRect SalCorona::screenGeometry(int id) const +{ + return QApplication::desktop()->screenGeometry(id); +} + +void SalCorona::updateActions(Plasma::ImmutabilityType immutability) +{ + bool unlocked =3D immutability =3D=3D Plasma::Mutable; + QAction *a =3D action("unlock widgets"); + if (a) { + a->setIcon(KIcon(unlocked ? "object-locked" : "configure")); + a->setText(unlocked ? i18n("Lock Screen") : i18n("Configure Widget= s")); + } + a =3D action("unlock desktop"); + if (a) { + a->setText(unlocked ? i18n("Leave Screensaver") : i18n("Unlock")); + } +} + +void SalCorona::toggleLock() +{ + //require a password to unlock + QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess", "or= g.kde.screenlocker.LockProcess", QDBusConnection::sessionBus(), this); + if (immutability() =3D=3D Plasma::Mutable) { + setImmutability(Plasma::UserImmutable); + lockprocess.call(QDBus::NoBlock, "startLock"); + kDebug() << "locking up!"; + } else if (immutability() =3D=3D Plasma::UserImmutable) { + QList args; + args << i18n("Unlock widgets to configure them"); + bool sent =3D lockprocess.callWithCallback("checkPass", args, this= , SLOT(unlock(QDBusMessage)), SLOT(dbusError(QDBusError))); + kDebug() << sent; + } +} + +void SalCorona::unlock(QDBusMessage reply) +{ + //assuming everything went as expected + if (reply.arguments().isEmpty()) { + kDebug() << "quit succeeded, I guess"; + return; + } + //else we were trying to unlock just the widgets + bool success =3D reply.arguments().first().toBool(); + kDebug() << success; + if (success) { + setImmutability(Plasma::Mutable); + } +} + +void SalCorona::dbusError(QDBusError error) +{ + kDebug() << error.errorString(error.type()); + kDebug() << "bailing out"; + //if it was the quit call and it failed, we shouldn't leave the user s= tuck in + //plasma-overlay forever. + qApp->quit(); +} + +void SalCorona::unlockDesktop() +{ + QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess", + "org.kde.screenlocker.LockProcess", QDBusConnection::sessionBu= s(), this); + bool sent =3D (lockprocess.isValid() && + lockprocess.callWithCallback("quit", QList(), this, = SLOT(unlock(QDBusMessage)), SLOT(dbusError(QDBusError)))); + //the unlock slot above is a dummy that should never be called. + //somehow I need a valid reply slot or the error slot is never ever us= ed. + if (!sent) { + //ah crud. + kDebug() << "bailing out!"; + qApp->quit(); + } +} + +void SalCorona::numScreensUpdated(int newCount) +{ + m_numScreens =3D newCount; + //do something? +} + + +#include "salcorona.moc" + diff --git a/plasma/netbook/containments/sal/shell/salcorona.h b/plasma/net= book/containments/sal/shell/salcorona.h new file mode 100644 index 0000000..bf04851 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/salcorona.h @@ -0,0 +1,65 @@ +/* + * Copyright 2008 Aaron Seigo + * Copyright 2008 by Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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. + */ + +#ifndef SALCORONA_H +#define SALCORONA_H + +#include + +#include + +class QDBusMessage; +class QDBusError; + +/** + * @short A Corona for SAL + */ +class SalCorona : public Plasma::Corona +{ + Q_OBJECT + +public: + explicit SalCorona(QObject * parent =3D 0); + + /** + * Loads the default (system wide) layout for this user + **/ + void loadDefaultLayout(); + + virtual int numScreens() const; + virtual QRect screenGeometry(int id) const; + +private Q_SLOTS: + void updateActions(Plasma::ImmutabilityType immutability); + void toggleLock(); + void unlock(QDBusMessage reply); + void dbusError(QDBusError error); + void unlockDesktop(); + void numScreensUpdated(int newCount); + +private: + void init(); + + int m_numScreens; +}; + +#endif + + diff --git a/plasma/netbook/containments/sal/shell/salview.cpp b/plasma/net= book/containments/sal/shell/salview.cpp new file mode 100644 index 0000000..a37457b --- /dev/null +++ b/plasma/netbook/containments/sal/shell/salview.cpp @@ -0,0 +1,293 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2007 Matt Broadstone + * Copyright 2007 Andr=C3=A9 Duffeck + * Copyright 2008 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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 "salview.h" + +#include +#include + +#include +#include +#include +#include + +#include + +#include "plasmaapp.h" + +static const int SUPPRESS_SHOW_TIMEOUT =3D 500; // Number of millis to pre= vent reshow of dashboard + + +class ScreenSaverWidgetExplorer : public Plasma::WidgetExplorer +{ +public: + ScreenSaverWidgetExplorer(QGraphicsWidget *parent) + : Plasma::WidgetExplorer(parent) + { + connect(this, SIGNAL(closeClicked()), this, SLOT(deleteLater())); + m_svg =3D new Plasma::FrameSvg(this); + m_svg->setImagePath("widgets/frame"); + m_svg->setElementPrefix("raised"); + m_svg->setEnabledBorders(Plasma::FrameSvg::TopBorder); + } + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event) + { + m_svg->resizeFrame(event->newSize()); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, = QWidget *widget) + { + Q_UNUSED(option) + Q_UNUSED(widget) + m_svg->paintFrame(painter); + } + +private: + Plasma::FrameSvg *m_svg; +}; + +SalView::SalView(Plasma::Containment *containment, QWidget *parent) + : Plasma::View(containment, parent), + m_suppressShow(false), + m_setupMode(false), + m_init(false) +{ + setAttribute(Qt::WA_TranslucentBackground); + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt= ::X11BypassWindowManagerHint); + if (!PlasmaApp::hasComposite()) { + setAutoFillBackground(false); + setAttribute(Qt::WA_NoSystemBackground); + } + + setWallpaperEnabled(!PlasmaApp::hasComposite()); + installEventFilter(this); +} + +SalView::~SalView() +{ + delete m_widgetExplorer.data(); +} + +void SalView::enableSetupMode() +{ + if (!m_setupMode) { + m_setupMode =3D true; + update(); + } +} + +void SalView::disableSetupMode() +{ + if (m_setupMode) { + m_setupMode =3D false; + update(); + } +} + +void SalView::drawBackground(QPainter *painter, const QRectF & rect) +{ + if (PlasmaApp::hasComposite()) { + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->fillRect(rect, Qt::transparent); + } else { + Plasma::View::drawBackground(painter, rect); + } +} + +void SalView::showWidgetExplorer() +{ + Plasma::Containment *c =3D containment(); + if (!c) { + return; + } + + if (m_widgetExplorer) { + delete m_widgetExplorer.data(); + } else { + ScreenSaverWidgetExplorer *widgetExplorer =3D new ScreenSaverWidge= tExplorer(c); + widgetExplorer->installEventFilter(this); + widgetExplorer->setContainment(c); + widgetExplorer->setLocation(Plasma::BottomEdge); + widgetExplorer->populateWidgetList(); + widgetExplorer->setMaximumWidth(width()); + widgetExplorer->adjustSize(); + widgetExplorer->setZValue(1000000); + widgetExplorer->resize(width(), widgetExplorer->size().height()); + widgetExplorer->setPos(0, containment()->geometry().height() - wid= getExplorer->geometry().height()); + m_widgetExplorer =3D widgetExplorer; + } +} + +void SalView::hideWidgetExplorer() +{ + delete m_widgetExplorer.data(); +} + +void SalView::paintEvent(QPaintEvent *event) +{ + Plasma::View::paintEvent(event); + = + + // now draw a little label reminding the user their screen's not quite= locked + const QRect r =3D rect(); + const QString text =3D i18n("Setup Mode - Screen is NOT locked"); + QFont f =3D font(); + f.bold(); + const QFontMetrics fm(f); + const int margin =3D 6; + const int textWidth =3D fm.width(text); + const QPoint centered(r.width() / 2 - textWidth / 2 - margin, r.y()); + const QRect boundingBox(centered, QSize(margin * 2 + textWidth, fm.hei= ght() + margin * 2)); + +// if (!viewport() || !event->rect().intersects(boundingBox)) { +// return; +// } + + QPainterPath box; + box.moveTo(boundingBox.topLeft()); + box.lineTo(boundingBox.bottomLeft() + QPoint(0, -margin * 2)); + box.quadTo(boundingBox.bottomLeft(), boundingBox.bottomLeft() + QPoint= (margin * 2, 0)); + box.lineTo(boundingBox.bottomRight() + QPoint(-margin * 2, 0)); + box.quadTo(boundingBox.bottomRight(), boundingBox.bottomRight() + QPoi= nt(0, -margin * 2)); + box.lineTo(boundingBox.topRight()); + box.closeSubpath(); + + QPainter painter(viewport()); + painter.setRenderHint(QPainter::Antialiasing); + painter.setFont(f); + //kDebug() << "******************** painting from" << centered << boun= dingBox << rect() << event->rect(); + QColor highlight =3D palette().highlight().color(); + highlight.setAlphaF(0.7); + painter.setPen(highlight.darker()); + painter.setBrush(highlight); + painter.drawPath(box); + painter.setPen(palette().highlightedText().color()); + painter.drawText(boundingBox, Qt::AlignCenter | Qt::AlignVCenter, text= ); +} + +bool SalView::eventFilter(QObject *watched, QEvent *event) +{ + if (containment() && (watched =3D=3D (QObject*)m_widgetExplorer.data()= ) && + (event->type() =3D=3D QEvent::GraphicsSceneResize || event->type()= =3D=3D QEvent::GraphicsSceneMove)) { + Plasma::WidgetExplorer *widgetExplorer =3D m_widgetExplorer.data(); + widgetExplorer->setPos(0, containment()->geometry().height() - wid= getExplorer->geometry().height()); + } + + return false; +} + +void SalView::showView() +{ + if (isHidden()) { + if (m_suppressShow) { + kDebug() << "show was suppressed"; + return; + } + + setWindowState(Qt::WindowFullScreen); + //KWindowSystem::setOnAllDesktops(winId(), true); + //KWindowSystem::setState(winId(), NET::KeepAbove|NET::SkipTaskbar= ); + + show(); + raise(); + + m_suppressShow =3D true; + QTimer::singleShot(SUPPRESS_SHOW_TIMEOUT, this, SLOT(suppressShowT= imeout())); + } +} + +void SalView::setContainment(Plasma::Containment *newContainment) +{ + if (m_init && newContainment =3D=3D containment()) { + return; + } + + m_init =3D true; + + if (containment()) { + disconnect(containment(), SIGNAL(showAddWidgetsInterface(QPointF))= , this, SLOT(showWidgetExplorer())); + } + + if (newContainment) { + connect(newContainment, SIGNAL(showAddWidgetsInterface(QPointF)), = this, SLOT(showWidgetExplorer())); + } + + if (m_widgetExplorer) { + m_widgetExplorer.data()->setContainment(newContainment); + } + + View::setContainment(newContainment); +} + +void SalView::hideView() +{ + if (isHidden()) { + return; + } + + hideWidgetExplorer(); + + if (containment()) { + containment()->closeToolBox(); + } + + hide(); + //let the lockprocess know + emit hidden(); +} + +void SalView::suppressShowTimeout() +{ + kDebug() << "SalView::suppressShowTimeout"; + m_suppressShow =3D false; +} + +void SalView::setOpacity(qreal opacity) +{ + setWindowOpacity(opacity); +} + +void SalView::openToolBox() +{ + kDebug() << "close toolbox"; + containment()->openToolBox(); +} + +void SalView::closeToolBox() +{ + kDebug() << "close toolbox"; + containment()->closeToolBox(); +} + +void SalView::adjustSize(int screen) +{ + QDesktopWidget *desktop =3D QApplication::desktop(); + int thisScreen =3D desktop->screenNumber(this); + if(screen =3D=3D thisScreen) + { + setGeometry(desktop->screenGeometry(screen)); + } +} + +#include "salview.moc" diff --git a/plasma/netbook/containments/sal/shell/salview.h b/plasma/netbo= ok/containments/sal/shell/salview.h new file mode 100644 index 0000000..36de124 --- /dev/null +++ b/plasma/netbook/containments/sal/shell/salview.h @@ -0,0 +1,85 @@ +/* + * Copyright 2007 Aaron Seigo + * Copyright 2007 Andr=C3=A9 Duffeck + * Copyright 2008 Chani Armitage + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * 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. + */ + +#ifndef SALVIEW_H +#define SALVIEW_H + +#include + +#include +#include + +namespace Plasma +{ + class Containment; + class WidgetExplorer; +} + +class SalView : public Plasma::View +{ + Q_OBJECT + +public: + SalView(Plasma::Containment* containment, QWidget *parent); + ~SalView(); + + bool eventFilter(QObject *watched, QEvent *event); + +signals: + void hidden(); + +protected: + void drawBackground(QPainter *painter, const QRectF & rect); + void paintEvent(QPaintEvent *event); + +public slots: + void showView(); + void hideView(); + void setOpacity(qreal opacity); + void adjustSize(int screen); + + /** + * Sets the containment for this view, which will also cause the view + * to track the geometry of the containment. + * + * @arg containment the containment to center the view on + */ + void setContainment(Plasma::Containment *newContainment); + void hideWidgetExplorer(); + + void enableSetupMode(); + void disableSetupMode(); + +protected slots: + void showWidgetExplorer(); //FIXME actually this is toggle + void suppressShowTimeout(); + void openToolBox(); + void closeToolBox(); + +private: + QWeakPointer m_widgetExplorer; + QPoint m_appletBrowserDragStart; + bool m_suppressShow : 1; + bool m_setupMode : 1; + bool m_init : 1; +}; + +#endif // multiple inclusion guard