Welcome ... er ... Ozone, the new default KWin decoration, that will

be a fork of the Oxygen decoration with additional features that
the Oxygen developers don't want to have in Oxygen. See README
or #152030 for why they prefer it this way.
CCBUG: 152030


svn path=/trunk/KDE/kdebase/workspace/; revision=795243
icc-effect-5.14.5
Luboš Luňák 2008-04-09 15:32:58 +00:00
parent 0370c195d0
commit e9b46ee24c
13 changed files with 1178 additions and 2 deletions

View File

@ -6,6 +6,7 @@ add_subdirectory( keramik )
add_subdirectory( laptop )
add_subdirectory( modernsystem )
add_subdirectory( oxygen )
add_subdirectory( ozone )
add_subdirectory( quartz )
add_subdirectory( redmond )
add_subdirectory( web )

View File

@ -0,0 +1,22 @@
add_definitions (-DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS)
########### next target ###############
set(kwin_ozone_SRCS
lib/helper.cpp
oxygenclient.cpp
oxygenbutton.cpp
oxygen.cpp
)
kde4_add_plugin(kwin3_ozone ${kwin_ozone_SRCS})
target_link_libraries(kwin3_ozone ${KDE4_KDEUI_LIBS} ${X11_Xrender_LIB} kdecorations)
install(TARGETS kwin3_ozone DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES ozoneclient.desktop DESTINATION ${DATA_INSTALL_DIR}/kwin/ )

9
clients/ozone/README Normal file
View File

@ -0,0 +1,9 @@
This decoration is a fork of the Oxygen decoration, for reasons stated
in bug #152030 (comment #70 and others), namely Oxygen developers not
willing to accept widely-requested patches because of not fitting
the Oxygen vision and instead preferring a fork that's not branded
as Oxygen.
Everything is put into extra namespace called Ozone to make syncing easier.
All visible strings have Oxygen changed to Ozone.
Other things are not renamed to minimize conflicts as much as possible.

148
clients/ozone/oxygen.cpp Normal file
View File

@ -0,0 +1,148 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenbutton.h
// -------------------
// Ozone window decoration for KDE.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include "oxygenclient.h"
#include "oxygen.h"
#include <kconfiggroup.h>
extern "C"
{
KDE_EXPORT KDecorationFactory* create_factory()
{
return new Ozone::Oxygen::OxygenFactory();
}
}
namespace Ozone
{
namespace Oxygen
{
//////////////////////////////////////////////////////////////////////////////
// OxygenFactory Class //
//////////////////////////////////////////////////////////////////////////////
bool OxygenFactory::initialized_ = false;
Qt::Alignment OxygenFactory::titlealign_ = Qt::AlignLeft;
//////////////////////////////////////////////////////////////////////////////
// OxygenFactory()
// ----------------
// Constructor
OxygenFactory::OxygenFactory()
{
readConfig();
initialized_ = true;
}
//////////////////////////////////////////////////////////////////////////////
// ~OxygenFactory()
// -----------------
// Destructor
OxygenFactory::~OxygenFactory() { initialized_ = false; }
//////////////////////////////////////////////////////////////////////////////
// createDecoration()
// -----------------
// Create the decoration
KDecoration* OxygenFactory::createDecoration(KDecorationBridge* b)
{
return (new OxygenClient(b, this))->decoration();
}
//////////////////////////////////////////////////////////////////////////////
// reset()
// -------
// Reset the handler. Returns true if decorations need to be remade, false if
// only a repaint is necessary
bool OxygenFactory::reset(unsigned long changed)
{
// read in the configuration
initialized_ = false;
bool confchange = readConfig();
initialized_ = true;
if (confchange ||
(changed & (SettingDecoration | SettingButtons | SettingBorder))) {
return true;
} else {
resetDecorations(changed);
return false;
}
}
//////////////////////////////////////////////////////////////////////////////
// readConfig()
// ------------
// Read in the configuration file
bool OxygenFactory::readConfig()
{
// create a config object
KConfig config("oxygenrc");
KConfigGroup group = config.group("Windeco");
// grab settings
Qt::Alignment oldalign = titlealign_;
QString value = group.readEntry("TitleAlignment", "AlignLeft");
if (value == "AlignLeft") titlealign_ = Qt::AlignLeft;
else if (value == "AlignHCenter") titlealign_ = Qt::AlignHCenter;
else if (value == "AlignRight") titlealign_ = Qt::AlignRight;
if (oldalign == titlealign_)
return false;
else
return true;
}
bool OxygenFactory::supports( Ability ability ) const
{
switch( ability ) {
// announce
case AbilityAnnounceButtons:
case AbilityAnnounceColors:
// buttons
case AbilityButtonMenu:
case AbilityButtonHelp:
case AbilityButtonMinimize:
case AbilityButtonMaximize:
case AbilityButtonClose:
case AbilityButtonAboveOthers:
case AbilityButtonBelowOthers:
case AbilityButtonSpacer:
return true;
// no colors supported at this time
default:
return false;
};
}
} //namespace Oxygen
} //namespace Ozone

86
clients/ozone/oxygen.h Normal file
View File

@ -0,0 +1,86 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenbutton.h
// -------------------
// Ozone window decoration for KDE.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#ifndef OXYGEN_H
#define OXYGEN_H
#include <kconfig.h>
#include <kdecorationfactory.h>
namespace Ozone
{
namespace Oxygen
{
// OxygenFactory /////////////////////////////////////////////////////////////
static const int OXYGEN_BUTTONSIZE = 22;
#define TFRAMESIZE 3
#define BFRAMESIZE 5
#define LFRAMESIZE 5
#define RFRAMESIZE 5
enum ButtonType {
ButtonHelp=0,
ButtonMax,
ButtonMin,
ButtonClose,
ButtonMenu,
ButtonSticky,
ButtonAbove,
ButtonBelow,
ButtonTypeCount
};
Q_DECLARE_FLAGS(ButtonTypes, ButtonType)
class OxygenFactory: public KDecorationFactory
{
public:
OxygenFactory();
virtual ~OxygenFactory();
virtual KDecoration *createDecoration(KDecorationBridge *b);
virtual bool reset(unsigned long changed);
virtual bool supports( Ability ability ) const;
static bool initialized();
static Qt::Alignment titleAlign();
private:
bool readConfig();
private:
static bool initialized_;
static Qt::Alignment titlealign_;
};
inline bool OxygenFactory::initialized()
{ return initialized_; }
inline Qt::Alignment OxygenFactory::titleAlign()
{ return titlealign_; }
} //namespace Oxygen
} //namespace Ozone
#endif

View File

@ -0,0 +1,276 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenbutton.cpp
// -------------------
// Ozone window decoration for KDE. Buttons.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
// Copyright (c) 2006, 2007 Casper Boemann <cbr@boemann.dk>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include <math.h>
#include <QPainterPath>
#include <QPainter>
#include <QPen>
#include <QBitmap>
#include <kdecoration.h>
#include <kglobal.h>
#include <KColorUtils>
#include <kdebug.h>
#include <KColorScheme>
#include "oxygenclient.h"
#include "oxygenbutton.h"
#include "oxygen.h"
namespace Ozone
{
namespace Oxygen
{
// class OxygenClient;
/*
extern int BUTTONSIZE;
extern int DECOSIZE;*/
// static const int DECOSIZE = 8;
//////////////////////////////////////////////////////////////////////////////
// OxygenButton Class //
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// OxygenButton()
// ---------------
// Constructor
OxygenButton::OxygenButton(OxygenClient &parent,
const QString& tip, ButtonType type)
: KCommonDecorationButton((::ButtonType)type, &parent)
, client_(parent)
, helper_(parent.helper_)
, type_(type)
, lastmouse_(0)
, colorCacheInvalid_(true)
{
setAutoFillBackground(false);
setAttribute(Qt::WA_OpaquePaintEvent, false);
setFixedSize(OXYGEN_BUTTONSIZE, OXYGEN_BUTTONSIZE);
setCursor(Qt::ArrowCursor);
setToolTip(tip);
}
OxygenButton::~OxygenButton()
{
}
//declare function from oxygenclient.cpp
QColor reduceContrast(const QColor &c0, const QColor &c1, double t);
QColor OxygenButton::buttonDetailColor(const QPalette &palette)
{
if (client_.isActive())
return palette.color(QPalette::Active, QPalette::ButtonText);
else {
if (colorCacheInvalid_) {
QColor ab = palette.color(QPalette::Active, QPalette::Button);
QColor af = palette.color(QPalette::Active, QPalette::ButtonText);
QColor nb = palette.color(QPalette::Inactive, QPalette::Button);
QColor nf = palette.color(QPalette::Inactive, QPalette::ButtonText);
colorCacheInvalid_ = false;
cachedButtonDetailColor_ = reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4))));
}
return cachedButtonDetailColor_;
}
}
//////////////////////////////////////////////////////////////////////////////
// sizeHint()
// ----------
// Return size hint
QSize OxygenButton::sizeHint() const
{
return QSize(OXYGEN_BUTTONSIZE, OXYGEN_BUTTONSIZE);
}
//////////////////////////////////////////////////////////////////////////////
// enterEvent()
// ------------
// Mouse has entered the button
void OxygenButton::enterEvent(QEvent *e)
{
KCommonDecorationButton::enterEvent(e);
if (status_ != Oxygen::Pressed) {
status_ = Oxygen::Hovered;
}
update();
}
//////////////////////////////////////////////////////////////////////////////
// leaveEvent()
// ------------
// Mouse has left the button
void OxygenButton::leaveEvent(QEvent *e)
{
KCommonDecorationButton::leaveEvent(e);
// if we wanted to do mouseovers, we would keep track of it here
status_ = Oxygen::Normal;
update();
}
//////////////////////////////////////////////////////////////////////////////
// pressSlot()
// ------------
// Mouse has pressed the button
void OxygenButton::pressSlot()
{
status_ = Oxygen::Pressed;
update();
}
//////////////////////////////////////////////////////////////////////////////
// drawButton()
// ------------
// Draw the button
void OxygenButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPalette pal = palette(); // de-const-ify
if (type_ == ButtonMenu) {
// we paint the mini icon (which is 16 pixels high)
int dx = (width() - 16) / 2;
int dy = (height() - 16) / 2;
painter.drawPixmap(dx, dy, client_.icon().pixmap(16));
return;
}
// Set palette to the right group.
// TODO - fix KWin to do this for us :-).
if (client_.isActive())
pal.setCurrentColorGroup(QPalette::Active);
else
pal.setCurrentColorGroup(QPalette::Inactive);
if(client_.maximizeMode() == OxygenClient::MaximizeRestore)
painter.translate(0,-1);
QColor bg = helper_.backgroundTopColor(pal.window());
QLinearGradient lg = helper_.decoGradient(QRect(4,4,13,13), buttonDetailColor(pal));
if(status_ == Oxygen::Hovered) {
if(type_ == ButtonClose) {
QColor color = KColorScheme(pal.currentColorGroup()).foreground(KColorScheme::NegativeText).color();
lg = helper_.decoGradient(QRect(4,4,13,13), color);
painter.drawPixmap(0, 0, helper_.windecoButtonFocused(pal.button(), color,7));
}
else{
QColor color = KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color();
painter.drawPixmap(0, 0, helper_.windecoButtonFocused(pal.button(), color, 7));
}
}
else
painter.drawPixmap(0, 0, helper_.windecoButton(pal.button()));
painter.setRenderHints(QPainter::Antialiasing);
painter.setBrush(Qt::NoBrush);
painter.setPen(QPen(lg, 2.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
switch(type_)
{
case ButtonSticky:
painter.drawPoint(QPointF(10.5,10.5));
break;
case ButtonHelp:
painter.translate(1.5, 1.5);
painter.drawArc(7,5,4,4,135*16, -180*16);
painter.drawArc(9,8,4,4,135*16,45*16);
painter.drawPoint(9,12);
break;
case ButtonMin:
painter.drawLine(QPointF( 7.5, 9.5), QPointF(10.5,12.5));
painter.drawLine(QPointF(10.5,12.5), QPointF(13.5, 9.5));
break;
case ButtonMax:
switch(client_.maximizeMode())
{
case OxygenClient::MaximizeRestore:
case OxygenClient::MaximizeVertical:
case OxygenClient::MaximizeHorizontal:
painter.drawLine(QPointF( 7.5,11.5), QPointF(10.5, 8.5));
painter.drawLine(QPointF(10.5, 8.5), QPointF(13.5,11.5));
break;
case OxygenClient::MaximizeFull:
{
painter.translate(1.5, 1.5);
//painter.setBrush(lg);
QPoint points[4] = {QPoint(9, 6), QPoint(12, 9), QPoint(9, 12), QPoint(6, 9)};
//QPoint points[4] = {QPoint(9, 5), QPoint(13, 9), QPoint(9, 13), QPoint(5, 9)};
painter.drawPolygon(points, 4);
break;
}
}
break;
case ButtonClose:
painter.drawLine(QPointF( 7.5,7.5), QPointF(13.5,13.5));
painter.drawLine(QPointF(13.5,7.5), QPointF( 7.5,13.5));
break;
case ButtonAbove:
if(isChecked()) {
QPen newPen = painter.pen();
newPen.setColor(KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
painter.setPen(newPen);
}
painter.drawLine(QPointF( 7.5,14), QPointF(10.5,11));
painter.drawLine(QPointF(10.5,11), QPointF(13.5,14));
painter.drawLine(QPointF( 7.5,10), QPointF(10.5, 7));
painter.drawLine(QPointF(10.5, 7), QPointF(13.5,10));
break;
case ButtonBelow:
if(isChecked()) {
QPen newPen = painter.pen();
newPen.setColor(KColorScheme(pal.currentColorGroup()).decoration(KColorScheme::HoverColor).color());
painter.setPen(newPen);
}
painter.drawLine(QPointF( 7.5,11), QPointF(10.5,14));
painter.drawLine(QPointF(10.5,14), QPointF(13.5,11));
painter.drawLine(QPointF( 7.5, 7), QPointF(10.5,10));
painter.drawLine(QPointF(10.5,10), QPointF(13.5, 7));
break;
default:
break;
}
}
} //namespace Oxygen
} //namespace Ozone

View File

@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenbutton.h
// -------------------
// Ozone window decoration for KDE. Buttons.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
// class QAbstractButton;
#ifndef OXYGENBUTTON_H
#define OXYGENBUTTON_H
#include <kcommondecoration.h>
#include "oxygen.h"
#include "oxygenclient.h"
namespace Ozone
{
namespace Oxygen
{
class OxygenClient;
enum ButtonStatus {
Normal,
Hovered,
Pressed };
Q_DECLARE_FLAGS(ButtonState, ButtonStatus)
class OxygenButton : public KCommonDecorationButton
{
public:
explicit OxygenButton(OxygenClient &parent,
const QString &tip=NULL,
ButtonType type=ButtonHelp);
~OxygenButton();
QSize sizeHint() const;
const int lastMousePress(){return lastmouse_;}
void reset(long unsigned int){repaint();}
private:
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);
void paintEvent(QPaintEvent *e);
QColor buttonDetailColor(const QPalette &palette);
private Q_SLOTS:
void pressSlot();
private:
OxygenClient &client_;
OxygenHelper &helper_;
ButtonType type_;
ButtonState status_;
int lastmouse_;
bool colorCacheInvalid_;
QColor cachedButtonDetailColor_;
};
} //namespace Oxygen
} //namespace Ozone
#endif

View File

@ -0,0 +1,405 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenclient.cpp
// -------------------
// Ozone window decoration for KDE
// -------------------
// Copyright (c) 2006, 2007 Casper Boemann <cbr@boemann.dk>
// Copyright (c) 2006, 2007 Riccardo Iaconelli <riccardo@kde.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
// #ifndef OXYGENCLIENT_H
// #define OXYGENCLIENT_H
#include <KConfig>
#include <KGlobal>
#include <KLocale>
#include <KDebug>
#include <KColorUtils>
#include <QBitmap>
#include <QLabel>
#include <QLayout>
#include <QPainter>
#include <QToolTip>
//Added by qt3to4:
#include <QBoxLayout>
#include <QGridLayout>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QEvent>
#include <QShowEvent>
#include <QPaintEvent>
#include <QPainterPath>
#include <QTimer>
#include <QCache>
#include "math.h"
#include "oxygenclient.h"
#include "oxygenclient.moc"
#include "oxygenbutton.h"
#include "oxygen.h"
namespace Ozone
{
namespace Oxygen
{
K_GLOBAL_STATIC_WITH_ARGS(OxygenHelper, globalHelper, ("OxygenDeco"))
void renderDot(QPainter *p, const QPointF &point, qreal diameter)
{
p->drawEllipse(QRectF(point.x()-diameter/2, point.y()-diameter/2, diameter, diameter));
}
OxygenClient::OxygenClient(KDecorationBridge *b, KDecorationFactory *f)
: KCommonDecoration(b, f)
, colorCacheInvalid_(true)
, helper_(*globalHelper)
{
}
OxygenClient::~OxygenClient()
{
}
QString OxygenClient::visibleName() const
{
return i18n("Ozone");
}
void OxygenClient::init()
{
KCommonDecoration::init();
widget()->setAutoFillBackground(false);
widget()->setAttribute(Qt::WA_OpaquePaintEvent);
}
bool OxygenClient::decorationBehaviour(DecorationBehaviour behaviour) const
{
switch (behaviour) {
case DB_MenuClose:
return true;//Handler()->menuClose();
case DB_WindowMask:
return false;
default:
return KCommonDecoration::decorationBehaviour(behaviour);
}
}
int OxygenClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *btn) const
{
bool maximized = maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows();
switch (lm) {
case LM_BorderLeft:
case LM_BorderRight:
case LM_BorderBottom:
{
if (respectWindowState && maximized) {
return 0;
} else {
return BFRAMESIZE;
}
}
case LM_TitleEdgeTop:
{
if (respectWindowState && maximized) {
return 0;
} else {
return TFRAMESIZE;
}
}
case LM_TitleEdgeBottom:
{
return 0;
}
case LM_TitleEdgeLeft:
case LM_TitleEdgeRight:
{
if (respectWindowState && maximized) {
return 0;
} else {
return 6;
}
}
case LM_TitleBorderLeft:
case LM_TitleBorderRight:
return 5;
case LM_ButtonWidth:
case LM_ButtonHeight:
case LM_TitleHeight:
{
if (respectWindowState && isToolWindow()) {
return OXYGEN_BUTTONSIZE;
} else {
return OXYGEN_BUTTONSIZE;
}
}
case LM_ButtonSpacing:
return 1;
case LM_ButtonMarginTop:
return 0;
default:
return KCommonDecoration::layoutMetric(lm, respectWindowState, btn);
}
}
KCommonDecorationButton *OxygenClient::createButton(::ButtonType type)
{
switch (type) {
case MenuButton:
return new OxygenButton(*this, i18n("Menu"), ButtonMenu);
case HelpButton:
return new OxygenButton(*this, i18n("Help"), ButtonHelp);
case MinButton:
return new OxygenButton(*this, i18n("Minimize"), ButtonMin);
case MaxButton:
return new OxygenButton(*this, i18n("Maximize"), ButtonMax);
case CloseButton:
return new OxygenButton(*this, i18n("Close"), ButtonClose);
case AboveButton:
return new OxygenButton(*this, i18n("Keep above others"), ButtonAbove);
case BelowButton:
return new OxygenButton(*this, i18n("Keep below others"), ButtonBelow);
/*
case OnAllDesktopsButton:
return new OxygenButton(*this, i18n("All Desktops"), ButtonSticky);
*/
default:
return 0;
}
}
// c0 - background
// c1 - foreground
// t - target contrast ratio
QColor reduceContrast(const QColor &c0, const QColor &c1, double t)
{
double s = KColorUtils::contrastRatio(c0, c1);
if (s < t)
return c1;
double l = 0.0, h = 1.0;
double x = s, a;
QColor r = c1;
for (int maxiter = 16; maxiter; --maxiter) {
a = 0.5 * (l + h);
r = KColorUtils::mix(c0, c1, a);
x = KColorUtils::contrastRatio(c0, r);
if (fabs(x - t) < 0.01)
break;
if (x > t)
h = a;
else
l = a;
}
return r;
}
QColor OxygenClient::titlebarTextColor(const QPalette &palette)
{
if (isActive())
return palette.color(QPalette::Active, QPalette::WindowText);
else {
if(colorCacheInvalid_) {
QColor ab = palette.color(QPalette::Active, QPalette::Window);
QColor af = palette.color(QPalette::Active, QPalette::WindowText);
QColor nb = palette.color(QPalette::Inactive, QPalette::Window);
QColor nf = palette.color(QPalette::Inactive, QPalette::WindowText);
colorCacheInvalid_ = false;
cachedTitlebarTextColor_ = reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4))));
}
return cachedTitlebarTextColor_;
}
}
void OxygenClient::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e)
if (!OxygenFactory::initialized()) return;
QPalette palette = widget()->palette();
QPainter painter(widget());
// Set palette to the right group.
// TODO - fix KWin to do this for us :-).
if (isActive())
palette.setCurrentColorGroup(QPalette::Active);
else
palette.setCurrentColorGroup(QPalette::Inactive);
int x,y,w,h;
QRect frame = widget()->frameGeometry();
QColor color = palette.window().color();
const int titleHeight = layoutMetric(LM_TitleHeight);
const int titleTop = layoutMetric(LM_TitleEdgeTop) + frame.top();
const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
const int marginLeft = layoutMetric(LM_TitleBorderLeft);
const int marginRight = layoutMetric(LM_TitleBorderRight);
const int titleLeft = frame.left() + titleEdgeLeft + buttonsLeftWidth() + marginLeft;
const int titleWidth = frame.width() -
titleEdgeLeft - layoutMetric(LM_TitleEdgeRight) -
buttonsLeftWidth() - buttonsRightWidth() -
marginLeft - marginRight;
int splitY = qMin(300, 3*frame.height()/4);
QPixmap tile = helper_.verticalGradient(color, splitY);
painter.drawTiledPixmap(QRect(0, 0, frame.width(), titleHeight + TFRAMESIZE), tile);
painter.drawTiledPixmap(QRect(0, 0, LFRAMESIZE, splitY), tile);
painter.fillRect(0, splitY, LFRAMESIZE, frame.height() - splitY, helper_.backgroundBottomColor(color));
painter.drawTiledPixmap(QRect(frame.width()-RFRAMESIZE, 0,
RFRAMESIZE, splitY), tile,
QPoint(frame.width()-RFRAMESIZE, 0));
painter.fillRect(frame.width()-RFRAMESIZE, splitY, RFRAMESIZE, frame.height() - splitY, helper_.backgroundBottomColor(color));
painter.fillRect(0, frame.height() - BFRAMESIZE, frame.width(), BFRAMESIZE, helper_.backgroundBottomColor(color));
int radialW = qMin(600, frame.width() - LFRAMESIZE - RFRAMESIZE);
tile = helper_.radialGradient(color, radialW);
// In the style we assume the top frame to have a height of 32 this we need offset here with the
// actual value
int frameTopFixer = titleTop+titleHeight - 32;
QRect radialRect = QRect((frame.width() - radialW) / 2, frameTopFixer, radialW, 64);
painter.drawPixmap(radialRect, tile);
// draw title text
painter.setFont(options()->font(isActive(), false));
painter.setPen(titlebarTextColor(palette));
painter.drawText(titleLeft, titleTop-1, titleWidth, titleHeight, // -1 is to go into top resizearea
OxygenFactory::titleAlign() | Qt::AlignVCenter, caption());
painter.setRenderHint(QPainter::Antialiasing);
// Draw dividing line
frame = widget()->rect();
frame.adjust(1,1,-1,-1);
frame.getRect(&x, &y, &w, &h);
QColor light = helper_.calcLightColor(color);
QColor dark = helper_.calcDarkColor(color);
dark.setAlpha(120);
if(!isActive()) {
light.setAlpha(120);
dark.setAlpha(50);
}
QLinearGradient lg(x,0,x+w,0);
lg.setColorAt(0.5, dark);
dark.setAlpha(0);
lg.setColorAt(0.0, dark);
lg.setColorAt(1.0, dark);
painter.setPen(QPen(lg,1));
painter.drawLine(QPointF(x, titleTop+titleHeight-1.5),
QPointF(x+w, titleTop+titleHeight-1.5));
lg = QLinearGradient(x,0,x+w,0);
lg.setColorAt(0.5, light);
light.setAlpha(0);
lg.setColorAt(0.0, light);
lg.setColorAt(1.0, light);
painter.setPen(QPen(lg,1));
painter.drawLine(QPointF(x, titleTop+titleHeight-0.5),
QPointF(x+w, titleTop+titleHeight-0.5));
// Draw shadows of the frame
bool maximized = maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows();
if(maximized)
return;
helper_.drawFloatFrame(&painter, widget()->rect(), color);
if(!isResizable())
return;
// Draw the 3-dots resize handles
qreal cenY = frame.height() / 2 + x + 0.5;
qreal posX = frame.width() + y - 2.5;
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0, 66));
renderDot(&painter, QPointF(posX, cenY - 3), 1.8);
renderDot(&painter, QPointF(posX, cenY), 1.8);
renderDot(&painter, QPointF(posX, cenY + 3), 1.8);
painter.translate(x + frame.width()-9, y + frame.height()-9);
renderDot(&painter, QPointF(2.5, 6.5), 1.8);
renderDot(&painter, QPointF(5.5, 5.5), 1.8);
renderDot(&painter, QPointF(6.5, 2.5), 1.8);
}
void OxygenClient::updateWindowShape()
{
bool maximized = maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows();
int w=widget()->width();
int h=widget()->height();
if(maximized) {
QRegion mask(0,0,w,h);
setMask(mask);
return;
}
QRegion mask(4, 0, w-8, h);
mask += QRegion(0, 4, w, h-8);
mask += QRegion(2, 1, w-4, h-2);
mask += QRegion(1, 2, w-2, h-4);
setMask(mask);
}
} //namespace Oxygen
} //namespace Ozone
//#include "oxygenclient.moc"
// #endif

View File

@ -0,0 +1,71 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenclient.h
// -------------------
// Ozone window decoration for KDE
// -------------------
// Copyright (c) 2003, 2004 David Johnson <david@usermode.org>
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#ifndef OXYGENCLIENT_H
#define OXYGENCLIENT_H
#include <kcommondecoration.h>
#include "lib/helper.h"
class QPoint;
namespace Ozone
{
namespace Oxygen {
class OxygenClient : public KCommonDecoration
{
Q_OBJECT
public:
OxygenClient(KDecorationBridge *b, KDecorationFactory *f);
virtual ~OxygenClient();
virtual QString visibleName() const;
virtual KCommonDecorationButton *createButton(::ButtonType type);
virtual bool decorationBehaviour(DecorationBehaviour behaviour) const;
virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton * = 0) const;
virtual void updateWindowShape();
virtual void init();
private:
void paintEvent(QPaintEvent *e);
QColor titlebarTextColor(const QPalette &palette);
bool colorCacheInvalid_;
QColor cachedTitlebarTextColor_;
protected:
friend class OxygenButton;
OxygenHelper &helper_;
};
} // namespace Oxygen
} // namespace Ozone
#endif // EXAMPLECLIENT_H

View File

@ -0,0 +1,4 @@
# KDE Desktop Entry
[Desktop Entry]
Name=Ozone
X-KDE-Library=kwin3_ozone

72
clients/ozone/snippet.cpp Normal file
View File

@ -0,0 +1,72 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenbutton.h
// -------------------
// Ozone window decoration for KDE. Buttons.
// -------------------
// Copyright (c) 2006, 2007 Riccardo Iaconelli <ruphy@fsfe.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
class OxygenWidget : public QWidget
{
protected:
virtual void paintEvent ( QPaintEvent * event );
};
void OxygenWidget::paintEvent ( QPaintEvent * )
{
QPainter painter(this);
QRadialGradient grad1(QPointF(5.0, 5.0),5.0);
grad1.setColorAt(0.9, QColor(0,0,0,100));
grad1.setColorAt(1.0, QColor(0,0,0,0));
QRadialGradient grad2(QPointF(5.0, 5.0),5.0);
grad2.setColorAt(0.0, QColor(235,235,235));
grad2.setColorAt(1.0, QColor(220,220,220));
QRadialGradient grad3(QPointF(5.0, 3.75), 3.5,QPointF(5.0, 2.5));
grad3.setColorAt(0, QColor(255,255,255,50));
grad3.setColorAt(1, QColor(255,255,255,0));
QRadialGradient grad4(QPointF(5.0, 3.3), 3.5, QPointF(5.0, 2.1));
grad4.setColorAt(0, QColor(255,255,255,50));
grad4.setColorAt(1, QColor(255,255,255,0));
QBrush brush1(grad1);
QBrush brush2(grad2);
QBrush brush3(grad3);
QBrush brush4(grad4);
painter.scale(1.6, 1.6);
painter.setRenderHint(QPainter::Antialiasing,true);
QPainterPath path1;
path1.addEllipse(0.0, 0.0, 10.0, 10.0);
painter.fillPath(path1, brush1);
QPainterPath path2;
path2.addEllipse(0.5, 0.5, 9.0, 9.0);
painter.fillPath(path2, brush2);
QPainterPath path3;
path3.addEllipse(1.5, 0.5, 7.0, 6.0);
painter.fillPath(path3, brush3);
QPainterPath path4;
path4.addEllipse(1.5, 0.5, 7.0, 6.0);
painter.fillPath(path4, brush4);
}

View File

@ -450,7 +450,7 @@ void KWinDecorationModule::readConfig( const KConfigGroup & conf )
oldLibraryName = currentLibraryName;
currentLibraryName = conf.readEntry("PluginLib",
((QPixmap::defaultDepth() > 8) ? "kwin3_oxygen" : "kwin3_plastik"));
((QPixmap::defaultDepth() > 8) ? "kwin3_ozone" : "kwin3_plastik"));
QString decoName = decorationName( currentLibraryName );
// If we are using the "default" kde client, use the "default" entry.

View File

@ -33,7 +33,7 @@ PluginMgr::PluginMgr()
: KDecorationPlugins( KGlobal::config())
{
defaultPlugin = (QPixmap::defaultDepth() > 8) ?
"kwin3_oxygen" : "kwin3_plastik";
"kwin3_ozone" : "kwin3_plastik";
loadPlugin( "" ); // load the plugin specified in cfg file
}