shadows on dialogs
This commit is contained in:
parent
ddbd2a35ce
commit
8f7b7cda31
@ -133,6 +133,7 @@ set(plasma_LIB_SRCS
|
||||
private/tooltip.cpp
|
||||
private/wallpaperrenderthread.cpp
|
||||
private/windowpreview.cpp
|
||||
private/windowshadows.cpp
|
||||
private/kineticscroll.cpp
|
||||
private/declarative/declarativenetworkaccessmanagerfactory.cpp
|
||||
private/effects/halopainter.cpp
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "plasma/theme.h"
|
||||
#include "plasma/widgets/scrollwidget.h"
|
||||
#include "plasma/windoweffects.h"
|
||||
#include "plasma/private/windowshadows_p.h"
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
#include <X11/Xlib.h>
|
||||
@ -94,6 +95,11 @@ void DialogPrivate::scheduleBorderCheck(bool triggeredByResize)
|
||||
void DialogPrivate::themeChanged()
|
||||
{
|
||||
checkBorders(false);
|
||||
if (background->hasElement("shadow-top")) {
|
||||
WindowShadows::self()->addWindow(q);
|
||||
} else {
|
||||
WindowShadows::self()->removeWindow(q);
|
||||
}
|
||||
|
||||
const bool translucency = Plasma::Theme::defaultTheme()->windowTranslucencyEnabled();
|
||||
// WA_NoSystemBackground is going to fail combined with sliding popups, but is needed
|
||||
|
235
private/windowshadows.cpp
Normal file
235
private/windowshadows.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2011 by Aaron Seigo <aseigo@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,
|
||||
* 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 "windowshadows_p.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
#include <QX11Info>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
#endif
|
||||
|
||||
#include <kglobal.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class WindowShadows::Private
|
||||
{
|
||||
public:
|
||||
Private(WindowShadows *shadows)
|
||||
: q(shadows),
|
||||
m_managePixmaps(false)
|
||||
{
|
||||
}
|
||||
~Private()
|
||||
{
|
||||
clearPixmaps();
|
||||
}
|
||||
|
||||
void clearPixmaps();
|
||||
void setupPixmaps();
|
||||
void initPixmap(const QString &element);
|
||||
void updateShadow(const QWidget *window);
|
||||
void clearShadow(const QWidget *window);
|
||||
void updateShadows();
|
||||
void windowDestroyed(QObject *deletedObject);
|
||||
|
||||
WindowShadows *q;
|
||||
QList<QPixmap> m_shadowPixmaps;
|
||||
QVector<unsigned long> m_data;
|
||||
QSet<const QWidget *> m_windows;
|
||||
bool m_managePixmaps;
|
||||
};
|
||||
|
||||
class WindowShadowsSingleton
|
||||
{
|
||||
public:
|
||||
WindowShadows self;
|
||||
};
|
||||
|
||||
K_GLOBAL_STATIC(WindowShadowsSingleton, privateWindowShadowsSelf)
|
||||
|
||||
WindowShadows *WindowShadows::self()
|
||||
{
|
||||
return &privateWindowShadowsSelf->self;
|
||||
}
|
||||
|
||||
WindowShadows::WindowShadows(QObject *parent)
|
||||
: Plasma::Svg(parent),
|
||||
d(new Private(this))
|
||||
{
|
||||
setImagePath("dialogs/background");
|
||||
connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows()));
|
||||
}
|
||||
|
||||
void WindowShadows::addWindow(const QWidget *window)
|
||||
{
|
||||
if (!window || !window->isWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_windows << window;
|
||||
d->updateShadow(window);
|
||||
connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
|
||||
}
|
||||
|
||||
void WindowShadows::removeWindow(const QWidget *window)
|
||||
{
|
||||
if (!d->m_windows.contains(window)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_windows.remove(window);
|
||||
disconnect(window, 0, this, 0);
|
||||
d->clearShadow(window);
|
||||
|
||||
if (d->m_windows.isEmpty()) {
|
||||
d->clearPixmaps();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowShadows::Private::windowDestroyed(QObject *deletedObject)
|
||||
{
|
||||
m_windows.remove(static_cast<QWidget *>(deletedObject));
|
||||
|
||||
if (m_windows.isEmpty()) {
|
||||
clearPixmaps();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowShadows::Private::updateShadows()
|
||||
{
|
||||
setupPixmaps();
|
||||
foreach (const QWidget *window, m_windows) {
|
||||
updateShadow(window);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowShadows::Private::initPixmap(const QString &element)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
QPixmap pix = q->pixmap(element);
|
||||
if (pix.handle() == 0) {
|
||||
Pixmap xPix = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), pix.width(), pix.height(), 32);
|
||||
QPixmap tempPix = QPixmap::fromX11Pixmap(xPix, QPixmap::ExplicitlyShared);
|
||||
tempPix.fill(Qt::transparent);
|
||||
QPainter p(&tempPix);
|
||||
p.drawPixmap(QPoint(0, 0), pix);
|
||||
m_shadowPixmaps << tempPix;
|
||||
m_managePixmaps = true;
|
||||
} else {
|
||||
m_shadowPixmaps << pix;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void WindowShadows::Private::setupPixmaps()
|
||||
{
|
||||
clearPixmaps();
|
||||
initPixmap("shadow-top");
|
||||
initPixmap("shadow-topright");
|
||||
initPixmap("shadow-right");
|
||||
initPixmap("shadow-bottomright");
|
||||
initPixmap("shadow-bottom");
|
||||
initPixmap("shadow-bottomleft");
|
||||
initPixmap("shadow-left");
|
||||
initPixmap("shadow-topleft");
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
foreach (const QPixmap &pixmap, m_shadowPixmaps) {
|
||||
m_data << pixmap.handle();
|
||||
}
|
||||
#endif
|
||||
|
||||
QSize marginHint = q->elementSize("shadow-hint-top-margin");
|
||||
if (marginHint.isValid()) {
|
||||
m_data << marginHint.height();
|
||||
} else {
|
||||
m_data << m_shadowPixmaps[0].height(); // top
|
||||
}
|
||||
|
||||
marginHint = q->elementSize("shadow-hint-right-margin");
|
||||
if (marginHint.isValid()) {
|
||||
m_data << marginHint.width();
|
||||
} else {
|
||||
m_data << m_shadowPixmaps[2].width(); // right
|
||||
}
|
||||
|
||||
marginHint = q->elementSize("shadow-hint-bottom-margin");
|
||||
if (marginHint.isValid()) {
|
||||
m_data << marginHint.height();
|
||||
} else {
|
||||
m_data << m_shadowPixmaps[4].height(); // bottom
|
||||
}
|
||||
|
||||
marginHint = q->elementSize("shadow-hint-left-margin");
|
||||
if (marginHint.isValid()) {
|
||||
m_data << marginHint.width();
|
||||
} else {
|
||||
m_data << m_shadowPixmaps[6].width(); // left
|
||||
}
|
||||
}
|
||||
|
||||
void WindowShadows::Private::clearPixmaps()
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
if (m_managePixmaps) {
|
||||
foreach (const QPixmap &pixmap, m_shadowPixmaps) {
|
||||
XFreePixmap(QX11Info::display(), pixmap.handle());
|
||||
}
|
||||
m_managePixmaps = false;
|
||||
}
|
||||
#endif
|
||||
m_shadowPixmaps.clear();
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
void WindowShadows::Private::updateShadow(const QWidget *window)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
if (m_data.isEmpty()) {
|
||||
setupPixmaps();
|
||||
}
|
||||
|
||||
Display *dpy = QX11Info::display();
|
||||
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
|
||||
|
||||
//kDebug() << "going to set the shadow of" << winId() << "to" << data;
|
||||
XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace,
|
||||
reinterpret_cast<const unsigned char *>(m_data.constData()), m_data.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
void WindowShadows::Private::clearShadow(const QWidget *window)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
Display *dpy = QX11Info::display();
|
||||
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
|
||||
XDeleteProperty(dpy, window->winId(), atom);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Plasma
|
||||
|
||||
#include "windowshadows_p.moc"
|
||||
|
54
private/windowshadows_p.h
Normal file
54
private/windowshadows_p.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2011 by Aaron Seigo <aseigo@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,
|
||||
* 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_WINDOWSHADOWS_H
|
||||
#define PLASMA_WINDOWSHADOWS_H
|
||||
|
||||
#include <QSet>
|
||||
|
||||
#include <plasma/svg.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class WindowShadows : Plasma::Svg
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static WindowShadows *self();
|
||||
|
||||
explicit WindowShadows(QObject *parent = 0);
|
||||
|
||||
void addWindow(const QWidget *window);
|
||||
void removeWindow(const QWidget *window);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private * const d;
|
||||
|
||||
Q_PRIVATE_SLOT(d, void updateShadows())
|
||||
Q_PRIVATE_SLOT(d, void windowDestroyed(QObject *deletedObject))
|
||||
};
|
||||
|
||||
} // namespace Plasma
|
||||
|
||||
#endif
|
||||
|
@ -251,7 +251,7 @@ QVariant ItemBackground::itemChange(GraphicsItemChange change, const QVariant &v
|
||||
d->anim->stop();
|
||||
}
|
||||
|
||||
d->anim->setDuration(250);
|
||||
d->anim->setDuration(100);
|
||||
d->anim->start();
|
||||
|
||||
return retVisible;
|
||||
|
Loading…
Reference in New Issue
Block a user