2aed7b13d1
The preview code still contained all the old logic for embedding the preview into another widget. Most of the code had been dead for quite some time. The only preview rendering code now is the one to render into a pixmap. This is actually changed to render the widget directly at the right position obsoleting the previous widget positioning code. The no preview available label is dropped as it did not get rendered into the pixmap at all. Last but not least we fake that compositing is on. This has always been the case for Aurorae themes and just looks better. Especially on Oxygen I had always had some corruption when rendering this preview with compositing disabled. REVIEW: 108777
529 lines
12 KiB
C++
529 lines
12 KiB
C++
/*
|
|
*
|
|
* Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org>
|
|
*
|
|
* 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.
|
|
*
|
|
* 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 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 "preview.h"
|
|
|
|
#include <kapplication.h>
|
|
#include <klocale.h>
|
|
#include <kconfig.h>
|
|
#include <kglobal.h>
|
|
#include <QLabel>
|
|
#include <QStyle>
|
|
#include <QPainter>
|
|
#include <QMouseEvent>
|
|
#include <QVector>
|
|
#include <kicon.h>
|
|
|
|
#include <kdecorationfactory.h>
|
|
|
|
KDecorationPreview::KDecorationPreview(QWidget* parent)
|
|
: QWidget(parent)
|
|
{
|
|
options = new KDecorationPreviewOptions;
|
|
|
|
bridge[Active] = new KDecorationPreviewBridge(this, true);
|
|
bridge[Inactive] = new KDecorationPreviewBridge(this, false);
|
|
|
|
deco[Active] = deco[Inactive] = NULL;
|
|
|
|
setMinimumSize(100, 100);
|
|
}
|
|
|
|
KDecorationPreview::~KDecorationPreview()
|
|
{
|
|
for (int i = 0; i < NumWindows; i++) {
|
|
delete deco[i];
|
|
delete bridge[i];
|
|
}
|
|
delete options;
|
|
}
|
|
|
|
bool KDecorationPreview::recreateDecoration(KDecorationPlugins* plugins)
|
|
{
|
|
for (int i = 0; i < NumWindows; i++) {
|
|
delete deco[i]; // deletes also window
|
|
deco[i] = plugins->createDecoration(bridge[i]);
|
|
deco[i]->init();
|
|
}
|
|
|
|
m_activeMask = QRegion();
|
|
m_inactiveMask = QRegion();
|
|
|
|
if (deco[Active] == NULL || deco[Inactive] == NULL) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void KDecorationPreview::disablePreview()
|
|
{
|
|
delete deco[Active];
|
|
delete deco[Inactive];
|
|
deco[Active] = deco[Inactive] = NULL;
|
|
}
|
|
|
|
KDecorationFactory *KDecorationPreview::factory() const
|
|
{
|
|
return deco[Active] ? deco[Active]->factory() : 0;
|
|
}
|
|
|
|
QPixmap KDecorationPreview::preview()
|
|
{
|
|
QPixmap pixmap(size());
|
|
pixmap.fill(Qt::transparent);
|
|
if (!deco[Active] || !deco[Inactive])
|
|
return pixmap;
|
|
|
|
int titleBarHeight, leftBorder, rightBorder, xoffset,
|
|
dummy1, dummy2, dummy3;
|
|
// don't have more than one reference to the same dummy variable in one borders() call.
|
|
deco[Active]->borders(dummy1, dummy2, titleBarHeight, dummy3);
|
|
deco[Inactive]->borders(leftBorder, rightBorder, dummy1, dummy2);
|
|
|
|
titleBarHeight = qMin(int(titleBarHeight * .9), 30);
|
|
xoffset = qMin(qMax(10, QApplication::isRightToLeft()
|
|
? leftBorder : rightBorder), 30);
|
|
QPainter p;
|
|
p.begin(&pixmap);
|
|
|
|
const QSize size(width() - xoffset - 20, height() - titleBarHeight - 20);
|
|
render(&p, deco[Inactive], size, QPoint(10 + xoffset, 10), m_inactiveMask);
|
|
render(&p, deco[Active], size, QPoint(10, 10 + titleBarHeight), m_activeMask);
|
|
p.end();
|
|
return pixmap;
|
|
}
|
|
|
|
void KDecorationPreview::render(QPainter *painter, KDecoration *decoration, const QSize &recommendedSize, const QPoint &offset, const QRegion &mask) const
|
|
{
|
|
QWidget *w = decoration->widget();
|
|
QSize size = QSize(recommendedSize)
|
|
.expandedTo(decoration->minimumSize());
|
|
int padLeft, padRight, padTop, padBottom;
|
|
padLeft = padRight = padTop = padBottom = 0;
|
|
bool useMask = true;
|
|
if (KDecorationUnstable *unstable = qobject_cast<KDecorationUnstable *>(decoration)) {
|
|
unstable->padding(padLeft, padRight, padTop, padBottom);
|
|
size.setWidth(size.width() + padLeft + padRight);
|
|
size.setHeight(size.height() + padTop + padBottom);
|
|
if (padLeft || padRight || padTop || padBottom) {
|
|
useMask = false;
|
|
}
|
|
}
|
|
decoration->resize(size);
|
|
|
|
// why an if-else block instead of (useMask ? mask : QRegion())?
|
|
// For what reason ever it completely breaks if the mask is copied.
|
|
if (useMask) {
|
|
w->render(painter, offset + QPoint(-padLeft, - padTop), mask,
|
|
QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);
|
|
} else {
|
|
w->render(painter, offset + QPoint(-padLeft, - padTop), QRegion(),
|
|
QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);
|
|
}
|
|
}
|
|
|
|
QRect KDecorationPreview::windowGeometry(bool active) const
|
|
{
|
|
QWidget *widget = active ? deco[Active]->widget() : deco[Inactive]->widget();
|
|
return widget->geometry();
|
|
}
|
|
|
|
void KDecorationPreview::setTempBorderSize(KDecorationPlugins* plugin, KDecorationDefines::BorderSize size)
|
|
{
|
|
options->setCustomBorderSize(size);
|
|
if (plugin->factory()->reset(KDecorationDefines::SettingBorder)) {
|
|
// can't handle the change, recreate decorations then
|
|
recreateDecoration(plugin);
|
|
}
|
|
}
|
|
|
|
void KDecorationPreview::setTempButtons(KDecorationPlugins* plugin, bool customEnabled, const QString &left, const QString &right)
|
|
{
|
|
options->setCustomTitleButtonsEnabled(customEnabled);
|
|
options->setCustomTitleButtons(left, right);
|
|
if (plugin->factory()->reset(KDecorationDefines::SettingButtons)) {
|
|
// can't handle the change, recreate decorations then
|
|
recreateDecoration(plugin);
|
|
}
|
|
}
|
|
|
|
QRegion KDecorationPreview::unobscuredRegion(bool active, const QRegion& r) const
|
|
{
|
|
Q_UNUSED(active)
|
|
return r;
|
|
}
|
|
|
|
void KDecorationPreview::setMask(const QRegion ®ion, bool active)
|
|
{
|
|
if (active) {
|
|
m_activeMask = region;
|
|
} else {
|
|
m_inactiveMask = region;
|
|
}
|
|
}
|
|
|
|
KDecorationPreviewBridge::KDecorationPreviewBridge(KDecorationPreview* p, bool a)
|
|
: preview(p), active(a)
|
|
{
|
|
}
|
|
|
|
QWidget* KDecorationPreviewBridge::initialParentWidget() const
|
|
{
|
|
return preview;
|
|
}
|
|
|
|
Qt::WFlags KDecorationPreviewBridge::initialWFlags() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isActive() const
|
|
{
|
|
return active;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isCloseable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isMaximizable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
KDecoration::MaximizeMode KDecorationPreviewBridge::maximizeMode() const
|
|
{
|
|
return KDecoration::MaximizeRestore;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isMinimizable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::providesContextHelp() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
int KDecorationPreviewBridge::desktop() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isModal() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isShadeable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isShade() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isSetShade() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::keepAbove() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::keepBelow() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isMovable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isResizable() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
NET::WindowType KDecorationPreviewBridge::windowType(unsigned long) const
|
|
{
|
|
return NET::Normal;
|
|
}
|
|
|
|
QIcon KDecorationPreviewBridge::icon() const
|
|
{
|
|
return KIcon("xorg");
|
|
}
|
|
|
|
QString KDecorationPreviewBridge::caption() const
|
|
{
|
|
return active ? i18n("Active Window") : i18n("Inactive Window");
|
|
}
|
|
|
|
void KDecorationPreviewBridge::processMousePressEvent(QMouseEvent*)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::showWindowMenu(const QRect &)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::showWindowMenu(const QPoint &)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::showApplicationMenu(const QPoint &)
|
|
{
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::menuAvailable() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void KDecorationPreviewBridge::performWindowOperation(WindowOperation)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::setMask(const QRegion& reg, int mode)
|
|
{
|
|
Q_UNUSED(mode)
|
|
preview->setMask(reg, active);
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::isPreview() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
QRect KDecorationPreviewBridge::geometry() const
|
|
{
|
|
return preview->windowGeometry(active);
|
|
}
|
|
|
|
QRect KDecorationPreviewBridge::iconGeometry() const
|
|
{
|
|
return QRect();
|
|
}
|
|
|
|
QRegion KDecorationPreviewBridge::unobscuredRegion(const QRegion& r) const
|
|
{
|
|
return preview->unobscuredRegion(active, r);
|
|
}
|
|
|
|
WId KDecorationPreviewBridge::windowId() const
|
|
{
|
|
return 0; // no decorated window
|
|
}
|
|
|
|
void KDecorationPreviewBridge::closeWindow()
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::maximize(MaximizeMode)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::minimize()
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::showContextHelp()
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::setDesktop(int)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::titlebarDblClickOperation()
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::titlebarMouseWheelOperation(int)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::setShade(bool)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::setKeepAbove(bool)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::setKeepBelow(bool)
|
|
{
|
|
}
|
|
|
|
int KDecorationPreviewBridge::currentDesktop() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void KDecorationPreviewBridge::grabXServer(bool)
|
|
{
|
|
}
|
|
|
|
bool KDecorationPreviewBridge::compositingActive() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
QRect KDecorationPreviewBridge::transparentRect() const
|
|
{
|
|
return QRect();
|
|
}
|
|
|
|
// Window tabbing
|
|
|
|
int KDecorationPreviewBridge::tabCount() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
QString KDecorationPreviewBridge::caption(int) const
|
|
{
|
|
return active ? "Active Window" : "Inactive Window";
|
|
}
|
|
|
|
QIcon KDecorationPreviewBridge::icon(int) const
|
|
{
|
|
return icon();
|
|
}
|
|
|
|
long KDecorationPreviewBridge::tabId(int) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
long KDecorationPreviewBridge::currentTabId() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void KDecorationPreviewBridge::setCurrentTab(long)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::tab_A_before_B(long, long)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::tab_A_behind_B(long, long)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::untab(long, const QRect&)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::closeTab(long)
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::closeTabGroup()
|
|
{
|
|
}
|
|
|
|
void KDecorationPreviewBridge::showWindowMenu(const QPoint &, long)
|
|
{
|
|
}
|
|
|
|
|
|
KDecoration::WindowOperation KDecorationPreviewBridge::buttonToWindowOperation(Qt::MouseButtons)
|
|
{
|
|
return KDecoration::NoOp;
|
|
}
|
|
|
|
KDecorationPreviewOptions::KDecorationPreviewOptions()
|
|
{
|
|
customBorderSize = BordersCount; // invalid
|
|
customButtonsChanged = false; // invalid
|
|
customButtons = true;
|
|
customTitleButtonsLeft.clear(); // invalid
|
|
customTitleButtonsRight.clear(); // invalid
|
|
updateSettings();
|
|
}
|
|
|
|
KDecorationPreviewOptions::~KDecorationPreviewOptions()
|
|
{
|
|
}
|
|
|
|
unsigned long KDecorationPreviewOptions::updateSettings()
|
|
{
|
|
KConfig cfg("kwinrc");
|
|
unsigned long changed = 0;
|
|
changed |= KDecorationOptions::updateSettings(&cfg);
|
|
|
|
// set custom border size/buttons
|
|
if (customBorderSize != BordersCount)
|
|
setBorderSize(customBorderSize);
|
|
if (customButtonsChanged)
|
|
setCustomButtonPositions(customButtons);
|
|
if (customButtons) {
|
|
if (!customTitleButtonsLeft.isNull())
|
|
setTitleButtonsLeft(customTitleButtonsLeft);
|
|
if (!customTitleButtonsRight.isNull())
|
|
setTitleButtonsRight(customTitleButtonsRight);
|
|
} else {
|
|
setTitleButtonsLeft(KDecorationOptions::defaultTitleButtonsLeft());
|
|
setTitleButtonsRight(KDecorationOptions::defaultTitleButtonsRight());
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
void KDecorationPreviewOptions::setCustomBorderSize(BorderSize size)
|
|
{
|
|
customBorderSize = size;
|
|
|
|
updateSettings();
|
|
}
|
|
|
|
void KDecorationPreviewOptions::setCustomTitleButtonsEnabled(bool enabled)
|
|
{
|
|
customButtonsChanged = true;
|
|
customButtons = enabled;
|
|
|
|
updateSettings();
|
|
}
|
|
|
|
void KDecorationPreviewOptions::setCustomTitleButtons(const QString &left, const QString &right)
|
|
{
|
|
customTitleButtonsLeft = left;
|
|
customTitleButtonsRight = right;
|
|
|
|
updateSettings();
|
|
}
|
|
|
|
bool KDecorationPreviewPlugins::provides(Requirement)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#include "preview.moc"
|